成功接收数小时后,UART接收中断停止触发

时间:2015-07-01 09:03:00

标签: c embedded stm32f4discovery cmsis

我正在使用与xbee连接的STM32f4发现板来接收来自远程温度传感器的温度数据。使用的代码是CMIS UART示例代码。我将收到分组数据,一次1个字节。换句话说,只要每个字节接收到,就会调用UART接收中断。一旦我得到完整的数据包,我将复制温度数据。我的UART回调函数没有任何问题。但几个小时后,UART接收中断停止工作,UART无法接收任何内容。然而,UART传输仍然有效。我使用波特率为115200的UART1。我将UART中断优先级设置为0,没有其他中断共享此优先级。所有其他中断优先级低于UART。请问任何人请告诉我为什么UART中断停止触发?

#define PACKET_DELIMETER 0x7E

uint8_t g_frame_ok=0; //flag to indicate complete packet received
uint8_t g_index_of_aoBuf=0; //Index of receive buffer
uint8_t g_aoBuf_of_xbee[100]={0};//Receive Buffer
uint8_t r_byte=0; //Receiving byte 

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *allUartHandle)
{
 __HAL_UART_FLUSH_DRREGISTER(allUartHandle); 

 if(HAL_UART_Receive_IT(allUartHandle, (uint8_t *)&r_byte, 1) == HAL_OK) //Interrupt occurs when each byte arrives
 {
    if(r_byte==PACKET_DELIMETER)
    {
        //start receiving packet
    }
    if( g_index_of_aoBuf>=g_aoBuf_of_xbee[2]+4)
    {
        g_frame_ok=1;
        BSP_LED_On(LED4);
    }           
   }
 }

2 个答案:

答案 0 :(得分:4)

我从来没有使用过你提到的API,所以我可能错了,但是在看了之后我注意到了一些事情:

HAL_UART_RxCpltCallback不是UART中断。它是来自HAL子系统的回调,当您发出的接收请求完成时,将调用该回调。这意味着只有在您发出接收请求后才会调用它。您无法访问UART中断,如果使用HAL图层,则不应该尝试使用它。

关于此,HAL_UART_Receive_IT实际上是一个发出接收请求的函数。它将永远立即返回,它永远不会收到任何东西。这意味着在调用之后接收缓冲区中的数据无效。发出请求后,将在收到完成后的任何时间调用HAL_UART_RxCpltCallback。只有在此时缓冲区中的数据才有效。要检索数据,您可以使用HAL_UART_Receive_IT中的相同变量,但数据缓冲区也可以通过(UART_HandleTypeDef*)->pRxBuffPtr从回调参数中获得。

我认为在回调中再次拨打HAL_UART_Receive_IT可以,但最后可能会更好。

另外,__HAL_UART_FLUSH_DRREGISTER用于什么?对我而言,它看起来弊大于利。

答案 1 :(得分:3)

回调函数和程序其余部分之间共享的变量必须声明为volatile,以防止编译器错误地优化代码。

您还必须确保对这些变量的写入和读取是原子的,或者用信号量保护它们。否则你可能会遇到竞争条件错误。

这两个经典错误中的任何一个或两个都可能导致您描述的问题:两者都会导致难以重新产生的间歇性,意外行为。

此外,如果您的CPU允许,请设置一个断点,该断点在对中断使能寄存器进行写访问时触发并检查跟踪。