打印
[STM32F4]

串口无法接受数据

[复制链接]
648|14
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
chenho|  楼主 | 2020-9-10 23:43 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
用STM32CubeMX 生成的串口初始代码,通过hal接口无法接收串口数据,一般会是什么原因
if (HAL_UART_Receive_IT(&huart1, &uartData.rxbuf[0], uartData.len)==HAL_OK){
                        HAL_GPIO_WritePin(LD2_Green_GPIO_Port,LD2_Green_Pin,GPIO_PIN_RESET);
                }
回掉函数不会进入
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle)
{
        if (UartHandle==&huart1){
                HAL_GPIO_TogglePin(LD2_Green_GPIO_Port,LD2_Green_Pin);
        }
}

使用特权

评论回复
沙发
tian111| | 2020-9-10 23:48 | 只看该作者
串口是嵌入式开发中最常前的外设设备,既可以用作不同单片机之间的通信,也可以用作在STM32 MCU和PC机之间的通信,STM32F407的串口功能非常强大,可以接红外,可以接流控,也可以接SIM卡接口,但我这里只介绍我们最常用的UART通信的一点调试经验,以STM32F407为例,对其它STM32芯片也适用,希望对大家有所帮助,如有错误不当之处欢迎大家联系指正。

一、串口的三种工作方式
操作串口一般有两种方式:查询和中断;STM32还支持第三种DMA方式。
(1)查询:串口程序不断地循环查询标志,看看当前有没有数据要它传送或接收。如果有的话进行相应的写操作和读操作进行传送或接收数据。
(2)中断:平时串口只要打开中断即可。如果发现有一个中断来,则意味着有数据需要接收(接收中断)或数据已经发送完成(发送中断)。
(3)DMA方式,设置好DMA工作方式,由DMA来自动接收或发送数据。
一般来说,查询方式的效率是比较低的,并且由于STM32的UART硬件上没有FIFO,如果程序功能比较多,查询不及时的话很容易出现数据丢失的现象, 故实际项目中这种方式用的并不多。
中断方式的话我们可以分别设置接收中断和发送中断,当串口有数据需要接收时才进入中断程序进行读读操,这种方式占用CPU资源比较少,实际项目中比较常用,但需要注意中断程序不要太复杂使执行时间太长,如果执行时间超过一个字符的时间的话也会出现数据丢失的现象,这个波特率比较高的串口编程中比较容易出现,可以考虑用循环BUF方法,在中断程序中只负责实时地接收实数数和发送时的填数(写发送寄存器),其它操作放在中断外处理。
STM32还提供了第三种DMA方式用来支持高速地串口传输。这种方式只要设置好接收和发送缓冲位置,可以由DMA来自动接收和发送数据,这可以最小化占用CPU时间。

使用特权

评论回复
板凳
tian111| | 2020-9-10 23:51 | 只看该作者
二、串口的使用步骤
(1)中断方式
基本步骤是初试化时钟,脚位、波特率设置、安装中断服务程序、开中断等,参考代码如下:
void uart_init(void)
{
   USART_InitTypeDef USART_InitStructure;
  NVIC_InitTypeDef NVIC_InitStructure;
  GPIO_InitTypeDef  GPIO_InitStructure;
   
  /* Enable GPIO clock  */
   RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
  
   /* Enable USART clock */
   RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
  
   /* Connect USART pins to AF7 */
   GPIO_PinAFConfig(GPIOC, GPIO_PinSource10, GPIO_AF_USART3);
  GPIO_PinAFConfig(GPIOC, GPIO_PinSource11,  GPIO_AF_USART3);
   
  /* Configure USART Tx and Rx as  alternate function push-pull */
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_Speed =  GPIO_Speed_100MHz;
   GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd =  GPIO_PuPd_UP;
   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
  GPIO_Init(GPIOC,  &GPIO_InitStructure);
   
  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_11;
  GPIO_Init(GPIOC,  &GPIO_InitStructure);
  /*  USARTx configuration  ----------------------------------------------------*/
  /* USARTx configured as follow:
        - BaudRate = 3750000 baud
  - Maximum BaudRate that can be achieved when  using the Oversampling by 8
     is: (USART APB Clock / 8)
Example:
   - (USART3 APB1  Clock / 8) = (30 MHz / 8) = 3750000 baud
   - (USART1 APB2 Clock / 8) = (60 MHz / 8) = 7500000  baud
  - Maximum BaudRate that can  be achieved when using the Oversampling by 16
    is: (USART APB Clock / 16)
Example: (USART3 APB1 Clock / 16) = (30 MHz / 16)  = 1875000 baud
Example: (USART1  APB2 Clock / 16) = (60 MHz / 16) = 3750000 baud
        - Word Length = 8 Bits
        - one Stop Bit
        - No parity
        - Hardware flow control disabled (RTS and  CTS signals)
        - Receive and  transmit enabled
   */
   USART_InitStructure.USART_BaudRate = 115200;
  USART_InitStructure.USART_WordLength =  USART_WordLength_8b;
   USART_InitStructure.USART_StopBits = USART_StopBits_1;
  USART_InitStructure.USART_Parity =  USART_Parity_No;
   USART_InitStructure.USART_HardwareFlowControl =  USART_HardwareFlowControl_None;
   USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
  USART_Init(USART3,  &USART_InitStructure);
   
  /* NVIC configuration  */
  /* Configure the Priority  Group to 2 bits */
   NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
  
   /* Enable the USARTx Interrupt */
  NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority =  0;
   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
   NVIC_Init(&NVIC_InitStructure);
  
  /* Enable USART  */
  USART_Cmd(USART3,  ENABLE);
  USART_ITConfig(USART3,  USART_IT_RXNE, ENABLE);
}
中断服务程序如下:
void USART3_IRQHandler(void)
{
unsigned char ch;  
if(USART_GetITStatus(USART3,  USART_IT_RXNE) != RESET)
   {
    /* Read one byte from the  receive data register */
    ch =  (USART_ReceiveData(USART3));

     printf("in[%c].\r\n",ch);
  }   
}
直接把接收到的字符打印出来。

使用特权

评论回复
地板
juventus9554| | 2020-9-10 23:55 | 只看该作者
初始化不成功造成的,或者波特率不对

使用特权

评论回复
5
caigang13| | 2020-9-11 08:02 | 只看该作者
楼主是配置的中断法还是查询标志法?

使用特权

评论回复
6
tian111| | 2020-9-11 19:59 | 只看该作者
波特率怎么设置的

使用特权

评论回复
7
tian111| | 2020-9-11 20:04 | 只看该作者
数据发送出去了吗,只是接受不到吗

使用特权

评论回复
8
chenho|  楼主 | 2020-9-11 20:07 | 只看该作者
谢谢楼上,提供翔实的回答,我已经解决了

使用特权

评论回复
9
stly| | 2020-9-11 20:11 | 只看该作者
你好,我也遇到同样的问题,请问下,你是怎么解决的呢

使用特权

评论回复
10
llljh| | 2020-9-11 20:15 | 只看该作者

    请问cube mx生成的函数HAL_SPI_TransmitReceive_IT这个函数是不是表示同时开启发送与接收中断,若调用回调函数HAL_SPI_TxRxCpltCallback,是不是指发送与接收触发中断后,都会各自调用一次HAL_SPI_TxRxCpltCallback中的程序?

使用特权

评论回复
11
huwr| | 2020-9-11 20:19 | 只看该作者
楼主,是啥错误啊,一堆代码也没看明白。

使用特权

评论回复
12
wangpe| | 2020-9-11 20:23 | 只看该作者

楼主,是啥错误啊,一堆代码也没看明白。

使用特权

评论回复
13
huwr| | 2020-9-11 20:27 | 只看该作者
没有进中断?

使用特权

评论回复
14
zhuhuis| | 2020-9-11 20:31 | 只看该作者

难道没有开中断?

使用特权

评论回复
15
chenho|  楼主 | 2020-9-11 20:38 | 只看该作者

嗯,我再好好缕一缕吧,有了好消息及时通知大家

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

748

主题

9853

帖子

5

粉丝