STM32采用HAL库HAL_UART_Receive_IT()多次开启的问题

来源:互联网 发布:双十一网络诈骗事件 编辑:程序博客网 时间:2024/05/16 02:13

硬件平台:STM32F429
软件平台:Keil 5 采用HAL库
本人借鉴了正点原子的例程,在这里表示感谢。
在编写串口的过程中,遇到了

HAL_UART_Receive_IT(&UART1_Handler, (u8 *)aRxBuffer, 1);

这个函数,首先是在初始化uart_init(115200)的时候调用了一次。
这里写图片描述

紧接着,在串口中断服务函数里,又调用了一次,继续接收,这样就不会造成接收完指定的的数据帧长度就不会进入中断了。如下图:

这里写图片描述

在这里,我们需要引入原子哥的一张图,
这里写图片描述
由此图可知:
采用HAL库,中断方式接收串口,只有当RxXferCount == 0 时,也就是调用这个函数,接收指定量的数据大小完成时,才会调用回调函数HAL_UART_RxCpltCallback()。

HAL_UART_Receive_IT(&UART1_Handler, (u8 *)aRxBuffer,1);

这个开启接收中断的源码如下:其中使能了接收完成中断(USART_IT_RXNE)
这里写图片描述
在这里,我们定义的大小是1,也就是每接收到一个字节,便会进入USART_IRQHandler中断,在这个中断里,在调用HAL库的串口中断HAL_UART_IRQHandler。

这里写图片描述
这个函数,其实就是判断一些发生的中断,这里我们只需关心接收完成中断,其便会调用:UART_Receive_IT(huart)。
这里写图片描述
这里写图片描述

该函数的重点,便是将接收到的数据保存到指定的串口缓冲区。aRxBuffer 。接着再判断。RxXferCount自减后 是否等于0.
如果等于0 ,则关闭接收完成中断。如果需要再一次开启时。需要再一次开启中断,也就是调用 HAL_UART_Receive_IT()函数。

不采用在中断服务函数中调用HAL库的串口中断

类似采用标准库的做法,首先是在初始化的时候调用一次HAL_UART_Receive_IT(&UART1_Handler, (u8 *)aRxBuffer,1);
这个函数开启接受完成中断,然后接收到了一个字符,会进入串口中断USART_IRQHandler( ) .在这个函数中,自己完成接受USART_DR中的数据和清中断标志。这样就不调用HAL_UART_IRQHandler()函数了。
具体代码如下所示:

void USART2_IRQHandler(void)                    {         u8 Res;        if(USART2->SR & (1<<6))//如果发送完成,置标志位        {            USART2->SR &= ~(1<<6);//清发送完成中标志        }           if(USART2->SR & (1<<3))//如果上溢错误        {            USART2->SR &= ~(1<<3);        }                   if(USART2->SR & (1<<5))//如果接受完成        {                   Res = USART2->DR;   //读取数据寄存器,清SR中断标志            USART2->SR &= ~(1<<5);//清RXNE标志                if((USART2_RX_STA & 0xfff) == 13)  //接收帧尾            {                ++USART2_RX_STA;                USART2_RX_BUF[USART2_RX_STA & 0xfff] = Res; //接收校验位                ////收到一帧,进行CRC校验,并执行,然后回复                if(!pc_cmd_crc())                {                    if(USART2_RX_BUF[2]==0xff || USART2_RX_BUF[2]==GD_BUF[INDEX_ID]) //是否是正确的ID                    {                        if(run_pc_cmd())//如果是正确的指令,则用往DMA传数据                        pc_cmd_reply();                         }                }                USART2_RX_STA = 0;            }            else if(USART2_RX_STA & 0x4000) //接收一帧数据的第3个----第9个数据            {                ++USART2_RX_STA;                USART2_RX_BUF[USART2_RX_STA & 0xfff] = Res;            }            else if(USART2_RX_STA & 0x8000) //接收一帧数据的第二个数据 ---0xfe            {                if(Res != 0xfe)                USART2_RX_STA = 0;                else                {                    USART2_RX_BUF[(++USART2_RX_STA)&0xfff] = Res;                    USART2_RX_STA |= 0x4000;                }            }            else if(Res == 0xef)  //接收一帧数据的第一个数据 ---0xef            {                USART2_RX_BUF[USART2_RX_STA & 0xfff] = Res;                USART2_RX_STA |= 0x8000;            }                           }   } 

这里还需要注意下面两个函数的区别,
HAL_UART_Receive_IT()
HAL_UART_Receive()
上面的为非阻塞模式下接受数据
下面为阻塞模式下接受数据
STM32串口有3中通信方式:轮询,中断,DMA .其中轮询方式为阻塞。中断和DMA为非阻塞,

具体采用何种方式,可自行选择

阅读全文
2 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 来例假刺激外阴高潮了怎么办 客人消费完说没钱怎么办? 孕13周血糖偏高怎么办 餐后血糖高14点怎么办 餐后血糖20多怎么办 空腹血糖6.6饭后9.2怎么办 键盘shift键失效了怎么办 灵异附身夫妻不合怎么办 鞋子买大了半码怎么办 鞋子买小了半码怎么办 黑布鞋鞋面白了怎么办 黑布鞋不黑了怎么办 黑布鞋退白了怎么办 老北京布鞋款式太少怎么办 老人输液抽搐后昏迷怎么办 头七家里有狗怎么办 股票退市股民的钱怎么办 美国股票退市股民怎么办 百度云字幕和视频不同步怎么办 百度云加载字幕有延迟怎么办 很难适应新环境怎么办 蜘蛛丝碰到嘴唇上起包有毒怎么办? 电瓶车在路上爆胎了怎么办 嘴被虫子咬肿了怎么办 高铁管家购票失败怎么办 高铁车厢空调冷怎么办 高铁票过了时间怎么办 网购火车票丢了怎么办 改签没有票了怎么办 火车票取了没赶上车怎么办 上车后车票丢了怎么办 晒了吗任务过期怎么办 坐火车买了站票怎么办 坐火车忘记带票怎么办 距离二本线差几分怎么办 行李包落火车候车厅怎么办 高铁票买错地点怎么办 高铁票买错日期怎么办 票买错时间了怎么办 上高铁了票丢了怎么办 上车前高铁票丢了怎么办