1.問題描述:
只有上電后第一次接收到的第一字節數據會丟失,往后再接收也不會存在問題了。
2.先貼出來重寫UART中斷回調函數
我在接收到第一字節數據后開啟定時器中斷的,做一個超時處理,每次接收到數據會對定時器計數值清零,如果超過6ms則認為一幀數據接收完畢。
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{if(huart->Instance == USART1){if(uart1.rx_buf_cnt >= UART1_RXSIZE - 1) //接收數據量超限,錯誤{uart1.rx_buf_cnt = 0;memset(uart1.rx_buf, 0x00, sizeof(uart1.rx_buf)); HAL_UART_Transmit(huart, (uint8_t *)"數據溢出", 10, 0xFFFF);}else //接收正常{uart1.rx_buf[uart1.rx_buf_cnt] = RxBuffer; //接收數據存儲到rx_bufuart1.rx_buf_cnt++;if(uart1.rx_buf_cnt == 1){ HAL_TIM_Base_Start_IT(&htim3); //在接收到第一個數據后 開啟定時器6ms中斷 } __HAL_TIM_SET_COUNTER(&htim3, 0); //每次接收數據后清空計數器數值,防止超時}HAL_UART_Receive_IT(huart, (uint8_t *)&RxBuffer, 1); }
}
上電第一次接收數據總是會少第一個字節。
3.解決過程
一開始以為是UART初始化后沒有清除接收中斷標志位,嘗試過清除標志位,也根據網上說得的開中斷要放在初始化后,但都沒有效果,仿真過程中在中斷回調函數中加入斷點后就可以接收到,懷疑有什么影響到回調函數了,然后把開啟定時器中斷函數注釋掉之后就可以了,就猜測是定時器初始化后中斷標志位沒有清零,開啟后定時器中斷后就直接進入中斷函數把接收數據個數直接清零了,然后就從第二個數據重新開始接收。
3.解決最后
正如我的猜測,果然加入清除定時器中斷標志位后數據就接收正常了。
原因:在定時器初始化的時候,為了更新預裝載值,會置中斷標志位,所以需要在NVIC開啟前先清除一下標志位。