STM32H743开发周记问题汇总(串口通讯集中)
溢出错误
出现的串口接收过程中,中断接收在溢出后无法进入,需要重点考虑溢出问题,以下是溢出恢复代码
波特率115200 优先级0-1 高于定时器 初步诊断是数据流导致的接收溢出问题
/*** @brief 检查并清除UART溢出错误(带状态验证)* @param huart: UART句柄指针* @retval HAL_OK: 成功清除 | HAL_ERROR: 无溢出或清除失败*/
HAL_StatusTypeDef UART_CheckAndClearOverrun(UART_HandleTypeDef *huart)
{// 1. 检查ORE标志是否存在if(!__HAL_UART_GET_FLAG(huart, UART_FLAG_ORE)) {return HAL_ERROR; // 无溢出错误}// 2. 原子操作保护uint32_t primask = __get_PRIMASK();__disable_irq();// 3. 清除流程(严格顺序)volatile uint8_t tmp = huart->Instance->RDR; // 必须读取DR__HAL_UART_CLEAR_OREFLAG(huart); // 官方推荐清除方式__HAL_UART_FLUSH_DRREGISTER(huart); // 确保FIFO清空// 4. 验证是否清除成功HAL_StatusTypeDef status = __HAL_UART_GET_FLAG(huart, UART_FLAG_ORE) ? HAL_ERROR : HAL_OK;// 5. 重启接收中断(可选)if(status == HAL_OK) {__HAL_UART_DISABLE_IT(huart, UART_IT_RXNE);__HAL_UART_ENABLE_IT(huart, UART_IT_RXNE);}// 6. 恢复中断状态if(!(primask & 1)) __enable_irq();return status;
}
问题查找方式
溯源方式:DEBUG查找判断是否执行
// 1. 检查ORE标志是否存在if(!__HAL_UART_GET_FLAG(huart, UART_FLAG_ORE)) {return HAL_ERROR; // 无溢出错误}
重点,不要加在串口接收中断函数中,不会触发,采用定时器一段时间检查一次即可
读串口对应的CR1可以确认接收中断有没有使能,2D代表对应的位使能,0D则不使能说明被意外关闭了。
对应的STATE则用来进一步辅助判断,因为中断和ISR会有延迟的情况发生,不可单独依靠这两个去判断。
发送阻塞卡死
另外一种出现的发送卡死在以下函数中的问题:
HAL_StatusTypeDef UART_WaitOnFlagUntilTimeout(UART_HandleTypeDef *huart, uint32_t Flag, FlagStatus Status, uint32_t Tickstart, uint32_t Timeout)
{/* Wait until flag is set */while((__HAL_UART_GET_FLAG(huart, Flag) ? SET : RESET) == Status){/* Check for the Timeout */if(Timeout != HAL_MAX_DELAY){if((Timeout == 0U) || ((HAL_GetTick()-Tickstart) > Timeout)){/* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE));CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);huart->gState = HAL_UART_STATE_READY;huart->RxState = HAL_UART_STATE_READY;/* Process Unlocked */__HAL_UNLOCK(huart);return HAL_TIMEOUT;}}}return HAL_OK;
}
溯源发生在两种情况下,第一种是中断优先级过低,被打断导致;第二种则是错误的在其他地方,人为的去操作串口的STATE位的状态,导致的串口状态混乱,所以请务必遵守HAL库默认的状态机情况,不要杂乱的修改导致状态混乱的情况发生。
// 在初始化末尾添加(HAL_UART_Init之后)__HAL_UART_DISABLE_IT(huart, UART_IT_TXE | UART_IT_TC); // 明确禁用发送中断huart->Instance->CR1 &= ~(USART_CR1_TXEIE | USART_CR1_TCIE); // 寄存器级禁用
串口发送中断被禁用的情况下请不要调用对应的清理串口发送中断的HAL库函数,一定几率造成堵死。
HAL_GetTick
计数失效导致的问题
请确保HAL_GetTick函数未失效,不管是使用WDT硬件计数器还是滴答定时器,在使用滴答定时器的时候请注意滴答定时器的中断优先级问题导致的一系列问题。
缓冲器资源冲突问题
环形缓冲区在读取和写入的时候,特别针对主函数一边读涉及到删除,中断写入的情况下,需要注意资源冲突问题,在写或者读的时候,进行保护。