在中断处理程序STM32F407中禁用中断

时间:2016-01-05 12:35:48

标签: c embedded raspberry-pi uart stm32f4discovery

我是新来的,我正试图解决我的项目问题。我试图通过UART从Raspberry Pi B +发送数据到我的STM32F407,并实时处理这些数据。我的问题是:如何实际同步main()thred和UART中断处理程序不要长时间停止我的UART中断。从Raspberry发送的数据看起来像(其中n是数字):nwnx代码:

void UART4_IRQHandler(void)
{
    if(USART_GetITStatus(UART4, USART_IT_RXNE))
    {
        if(!flag)
        {
            processing = true;
            widthTemp[j] = USART_ReceiveData(UART4);
            USART_ClearITPendingBit(UART4, USART_IT_RXNE);

            if(widthTemp[j] != 'w')
            {
                j++;
            }
            else
            {
                j = 0;
                flaga = true;
                processing = false;
                //__disable_irq();
                NVIC_DisableIRQ(UART4_IRQn);
            }
        }else if(flag)
        {
            processing = true;
            heightTemp[j] = USART_ReceiveData(UART4);
            USART_ClearITPendingBit(UART4, USART_IT_RXNE);

            if(heightTemp[j] != 'x')
            {
                j++;
            }
            else
            {
                j++;
                heightTemp[j] = '\n';
                j = 0;
                processing = false;
                flag = false;
                NVIC_DisableIRQ(UART4_IRQn);
            }
        }
    }
}

现在主要代码:

while (1)
{
    if(!NVIC_GetPendingIRQ(UART4_IRQn))
    {
        //if()
        if(flag == true && processing == false)
        {
            sscanf(heightTemp, "%d", &height );
            USART_puts(UART4, heightTemp); // sending back data to raspberry (temporary)
            for(i = 0; i< sizeof(widthTemp);i++)
            {
                heightTemp[i] = '\0';
            }
            NVIC_EnableIRQ(UART4_IRQn);
        }
        if(flag == false && processing == false)
        {
            sscanf(widthTemp, "%d", &width );
            USART_puts(UART4, widthTemp); // sending back data to raspberry (temporary)
            for(i = 0; i< sizeof(widthTemp);i++)
            {
                widthTemp[i] = '\0';
            }
            NVIC_EnableIRQ(UART4_IRQn);
        }
    }
}

我的问题是,在某些时候,rasbperry开始对收到的数据造成巨大延迟。

问题:  1.我可以像在代码中那样禁用中断处理程序中的中断,让我的main()知道它可以继续数据吗?如果是的话,我是否检查了这项任务的良好注册?  2.有没有更好的方法将缓冲区(widthTemp f.e.)发送到某个变量?也许我不需要像这样复杂我的代码。  3.我可以在代码中使用可能的线程吗?会有帮助吗?  这是我的第一篇文章,所以关于如何格式化问题,关于代码的建议等的任何信息都会很好。

2 个答案:

答案 0 :(得分:2)

一般情况下,您的UART ISR应该只做:

  • 对于接收中断,将RXD中的字符放入环形缓冲区
  • 对于发送中断,从环形缓冲区获取字符并将其放入TXD。在STM32上,如果环形缓冲区为空,则必须明确关闭发射机。
  • 清除中断标志(处理错误标志可选)。

然后你的主线程(或者一些其他线程/任务,如果使用线程调度器或RTOS),只需从Rx环形缓冲区读取(或写入Tx环形缓冲区)。

请注意,在STM32上,如果发送器未运行,则应将第一个字符直接放在TXD中,然后发送器启动,然后将后续字符放在Tx环形缓冲区中。

如果使用RTOS或其他操作系统,您可以使用队列或邮箱,而不是实现自己的环形缓冲区。当多个上下文访问控制数据时,需要注意确保一致的缓冲区控制。

请注意,STM32能够使用DMA传输到UART操作,这可能提供替代解决方案,特别是在数据速率非常快的情况下,因为STM32 UART没有FIFO,如果每个字符都没有被删除,它将溢出RXD从RXD获得另一个人的时间。

答案 1 :(得分:-1)

如@arduic评论所述,您不应该在中断中处理数据。您应该尽可能短地(和快速)保持中断服务程序。因此,您不需要禁用它们,以防止在UART RX中断时丢失数据。