通过USART接收数据我遇到了一些麻烦 . 我实际想要实现的是,我可以通过USART接收没有特定长度的命令(只有最大可能的长度) . 所以我使用中断例程检查收到的每个字符,但我仍然无法实现我想要的 . 每次收到一个新字符时都会调用该例程,但不知怎的HAL_UART_Receive_IT(&huart1,rx_data,buff_size_rx)没有实时升级,那么当我检查rx_data [指针]时我看不到收到的字符,但是几次之后它位于rx_data缓冲区中 .
到目前为止我所拥有的:
int pointer =0;
...
void USART1_IRQHandler(void)
{
/* USER CODE BEGIN USART1_IRQn 0 */
if ( USART1->ISR & UART_IT_TXE) {
}
if ( USART1->ISR & UART_IT_RXNE) {
HAL_UART_Receive_IT(&huart1,rx_data,buff_size_rx);
if(rx_data[pointer]=='\0') {
pointer=0;
readCommand(rx_data);
clearBuffer(rx_data,buff_size_rx);
} else {
pointer++;
if(pointer>=buff_size_rx) {
pointer=0;
}
}
}
/* USER CODE END USART1_IRQn 0 */
HAL_UART_IRQHandler(&huart1);
/* USER CODE BEGIN USART1_IRQn 1 */
/* USER CODE END USART1_IRQn 1 */
}
2 回答
HAL_UART_Receive_IT()
不是要从中断处理程序那样调用,而是通过中断启动接收 fixed 字节数 .可能的解决方法是在
HAL_UART_IRQHandler()
完成后检查输入缓冲区,即在/* USER CODE BEGIN USART1_IRQn 1 */
部分 . 处理命令时,可以将句柄结构中的pRxBuffPtr
和RxXferCount
重置为其原始值,以便再次从缓冲区的起始位置开始 .另一个可怕的可能解决方法是使用缓冲区大小为1调用
HAL_UART_Receive_IT()
,并设置一个HAL_UART_RxCpltCallback()
处理程序,每次检查接收到的字节,并在必要时再次调用HAL_UART_Receive_IT()
.当然,你可以在没有HAL的情况下做到这一点,就像PeterJ和其他人(总是)建议的那样 .
您已经实现了引脚和中断设置,首先保持不变 .
根据参考手册计算
UART->BRR
值,或从hal复制相关代码 .set
UART->CR1=USART_CR1_RE|USART_CR1_TE|USART_CR1_UE|USART_CR1_RXNEIE;
现在,您正在获得中断 .在中断函数中,将
UART->SR
读入临时变量,并检查它 .当收到的字节等待时读取
UART->DR
,否则执行错误处理(稍后) .当上述工作正常时,摆脱其余的HAL调用 .
中断响应和处理时间在嵌入式应用程序中通常至关重要,而HAL只是浪费了很多 .
普通的HAL库对于连续接收或具有不同长度的命令没有用 .
如果安装了完整的HAL包,则可以查看 L ow L evel接口的示例 .
最重要的是让你接受连续接收:
USART IT Handler看起来应该是这样的
最后要设置的是Callback
您可以将字节放入缓冲区并在主循环中或您想要的位置处理它 .