STM32 HAL USART 通过中断接收 [英] STM32 HAL USART receive by interrupt

查看:43
本文介绍了STM32 HAL USART 通过中断接收的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在通过 USART 接收数据时遇到了一些麻烦.我真正想要实现的是,我可以通过 USART 接收没有特定长度(只有最大可能长度)的命令.所以我使用中断例程来检查接收到的每个字符,但不知何故我仍然无法实现我想要的.每次收到新字符时都会调用该例程,但不知何故 HAL_UART_Receive_IT(&huart1,rx_data,buff_size_rx) 没有实时升级,然后我在检查 rx_data[pointer] 时看不到接收到的字符,但是有一些稍后它在 rx_data 缓冲区中.

I have some trouble to receive data over the USART. What I actually want to achieve ist, that I can receive a command over USART with no specific length (only a maximum possible length). So I use the interrupt routine to check each character received, but I somehow still cannot achieve what I want. The routine is called each time I receive a new character, but somehow HAL_UART_Receive_IT(&huart1,rx_data,buff_size_rx) does not upgrade in realtime, then I don't see the received character when I check rx_data[pointer], but a few time later it is in the rx_data buffer.

到目前为止我所拥有的:

What I have so far:

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 */
}

推荐答案

HAL_UART_Receive_IT() 并不是要以这种方式从中断处理程序中调用,而是要开始接收 fixed 通过中断的字节数.

HAL_UART_Receive_IT() is not meant to be called from an interrupt handler that way, but to initiate receiving a fixed number of bytes via interrupt.

一种可能的解决方法是在 HAL_UART_IRQHandler() 完成后检查您的输入缓冲区 ,即在 /* USER CODE BEGIN USART1_IRQn 1 */ 部分.处理命令时,您可以将句柄结构中的pRxBuffPtrRxXferCount 重置为原始值,以重新从缓冲区的开头开始.

A possible workaround is to check your input buffer after HAL_UART_IRQHandler() completes, i.e. in the /* USER CODE BEGIN USART1_IRQn 1 */ section. When a command is processed, you can reset pRxBuffPtr and RxXferCount in the handle structure to their original values to start from the start of the buffer again.

另一种可怕可能的解决方法是调用HAL_UART_Receive_IT(),缓冲区大小为1,并设置一个HAL_UART_RxCpltCallback() 处理程序每次检查接收到的字节,并在必要时再次调用HAL_UART_Receive_IT().

Another horrible possible workaround would be to call HAL_UART_Receive_IT() with a buffer size of 1, and set up a HAL_UART_RxCpltCallback() handler that checks the received byte each time, and calls HAL_UART_Receive_IT() again when necessary.

当然,正如 PeterJ 和其他人(总是)建议的那样,您可以在没有 HAL 的情况下做到这一点.

Of course you could do it without HAL, as PeterJ and others (always) suggest.

  • 您已经实现了引脚和中断设置,请先将它们保持不变.
  • 根据参考手册计算UART->BRR值,或者从hal复制相关代码.
  • set UART->CR1=USART_CR1_RE|USART_CR1_TE|USART_CR1_UE|USART_CR1_RXNEIE; 现在,您收到了中断.
  • 在中断函数中,将UART->SR读入一个临时变量中,并检查它.
  • 当有接收字节等待时读取UART->DR,否则进行错误处理(稍后).
  • 在上述工作正常时摆脱其余的 HAL 调用.
  • You've already implemented pin and interrupt setup, leave them unchanged at first.
  • Calculate the UART->BRR value according to the reference manual, or copy the relevant code from hal.
  • set UART->CR1=USART_CR1_RE|USART_CR1_TE|USART_CR1_UE|USART_CR1_RXNEIE; Now, you are getting interrupts.
  • In the interrupt function, read UART->SR into a temporary variable, and examine it.
  • Read UART->DR when there is a received byte waiting, do the error handling otherwise (later).
  • Get rid of the rest of the HAL calls when the above is working.

中断响应和处理时间在嵌入式应用程序中通常至关重要,而 HAL 只是浪费了很多.

Interrupt response and processing time is often critical in embedded applications, and the HAL just wastes a lot of that.

这篇关于STM32 HAL USART 通过中断接收的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆