我正在使用与xbee连接的STM32f4发现板接收来自远程温度传感器的温度数据。使用的代码是CMIS UART示例代码。我将接收数据包数据,一次一个字节。换句话说,只要每个字节接收到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);
}
}
}
发布于 2015-07-01 20:25:34
我从来没有用过你提到的API,所以我可能是错的,但在看过之后,我注意到了以下几点:
HAL_UART_RxCpltCallback
不是通用异步收发器中断。这是一个来自HAL子系统的回调,当您发出的receive请求完成时将调用它。这意味着只有在发出接收请求后的一段时间内才会调用它。您不能访问UART中断,如果您使用HAL层,也不应该试图干扰它。
关于这一点,HAL_UART_Receive_IT
实际上是一个发出接收请求的函数。它总是会立即返回,并且永远不会收到任何东西。这意味着在调用之后接收缓冲区中的数据无效。发出请求后,在接收完成后的任何时间都会调用HAL_UART_RxCpltCallback
。只有在此时,缓冲区中的数据才有效。要检索数据,您可以使用HAL_UART_Receive_IT
中的相同变量,但是也可以通过回调参数中的(UART_HandleTypeDef*)->pRxBuffPtr
使用数据缓冲区。
我认为在回调中再次调用HAL_UART_Receive_IT
是可以的,但在结束时调用可能会更好。
另外,__HAL_UART_FLUSH_DRREGISTER
是用来做什么的?对我来说,这看起来弊大于利。
发布于 2015-07-01 19:25:39
在回调函数和程序的其余部分之间共享的变量必须声明为易失性,以防止编译器错误地优化代码。
您还必须确保对此类变量的写入和读取是原子的,或者使用信号量来保护它们。否则,您可能会得到竞争条件错误。
这两个经典bug中的任何一个或两者都可能导致您所描述的问题:两者都倾向于导致间歇性的、意想不到的行为,这些行为很难重现。
此外,如果您的CPU允许,请设置一个断点,该断点在对中断启用寄存器的写访问时触发,并检查跟踪。
https://stackoverflow.com/questions/31156982
复制相似问题