利用空闲中断实现不定长数据的收发
一、空闲中断的特点
1. 在一帧数据传输结束后,通信线路将会维持高电平,这个状态称为空闲状态;
2. 当 CPU 检测到通信线路处于空闲状态时,且空闲状态持续时间大于一个字节传输时间时,空闲状态标志 IDLE 将由硬件置 1 。如果串口控制寄存器 CR1 中的 IDLEIE 位为 1 ,将会触发空闲中断 (IDLE 中断);
3. 由于空闲标志是在一帧数据传输完成后才置位,在有效数据传输过程中不会置位,因此借助空闲中断,可以实现不定长数据的收发。
二、空闲中断时序图
假设一帧数据由2 个字符构成,分别是 0xaa 、 0x55 ,传输的时序图如下:
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存失败,源站可能有防盗链机制,建议将图片保存下来直接上传下上传(iWG3yl0FK0cH-1632623238621)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210923155133881.png)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210923155133881.png)]](https://img-blog.csdnimg.cn/1ff6470702474a0db9ca71d2f4ac3ec7.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5L2g5piv5oiR55qE5pWR55Sf5ZyI,size_20,color_FFFFFF,t_70,g_se,x_16)
从图中可以看到,在发送该帧数据之前和之后,数据线为高电平,处于 IDLE 状态。在该帧有效数据发送过程中,即 0xaa 字节与 0x55 字节之间,没有 IDLE 状态出现,这样利用 IDLE 状态就可以判断不定长数据的发送结束。
三、设计思路
1.使能 IDLE 中断,在串口 1 的中断服务程序 USART1_IRQHandler 中添加对 IDLE 中断的判断,该函数位于 stm32f4xx_it.c 文件;
2.设置传输模式为普通模式,启动 DMA 传输。串口一旦接收到数据,则触发 DMA 操作,将数据存放到用户定义的接收缓冲区;
3.当一帧数据发送完成后,线路处于 IDLE 状态,将触发 IDLE 中断,调用 IDLE 中断回调函数,设置数据接收完成标志;
4.主程序检测到接收完成标志置位后,将接收的一帧数据原样发回到PC ,并禁能 DMA ,以触发 DMA 中断。 DMA 中断将调用接收中断回调函数,在回调函数中重新启动 DMA 传输。
四、STM32CubeMX 配置
1、串口DMA配置
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IaIWTyDC-1632623238625)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210923160102766.png)]](https://img-blog.csdnimg.cn/0eb7250406e14db29e9cc0e6aa964d19.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5L2g5piv5oiR55qE5pWR55Sf5ZyI,size_20,color_FFFFFF,t_70,g_se,x_16)
2、设置串口 接收 的 DMA 参数:
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LUSFr0RH-1632623238627)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210923160236159.png)]](https://img-blog.csdnimg.cn/907768b422064782bffabd2c1687ed86.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5L2g5piv5oiR55qE5pWR55Sf5ZyI,size_20,color_FFFFFF,t_70,g_se,x_16)
3、设置串口 发送 的 DMA 参数:
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aQkuVFF5-1632623238632)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210923160340385.png)]](https://img-blog.csdnimg.cn/18d8aaacdc0b413d80a90ea8685d7a54.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5L2g5piv5oiR55qE5pWR55Sf5ZyI,size_20,color_FFFFFF,t_70,g_se,x_16)
4、使能串口中断及DMA 中断
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VqJRNIjS-1632623238637)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210923160432650.png)]](https://img-blog.csdnimg.cn/8829b8cd1b454f11b677139cd010cd78.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5L2g5piv5oiR55qE5pWR55Sf5ZyI,size_20,color_FFFFFF,t_70,g_se,x_16)
五、程序编写(一)
1、添加空闲中断的处理
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4i28Tq7Y-1632623238638)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210923160714624.png)]](https://img-blog.csdnimg.cn/6f01d5c74f1f41e9a7c58f15bac1feef.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5L2g5piv5oiR55qE5pWR55Sf5ZyI,size_20,color_FFFFFF,t_70,g_se,x_16)
2、添加用户宏定义及变量定义,添加用户初始化代码。
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yVpYdtde-1632623238639)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210923160727015.png)]](https://img-blog.csdnimg.cn/1478fe992ab9443f9fdf962576233101.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5L2g5piv5oiR55qE5pWR55Sf5ZyI,size_20,color_FFFFFF,t_70,g_se,x_16)
3、编写用户应用代码
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3JQvh5OW-1632623238640)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210923161240231.png)]](https://img-blog.csdnimg.cn/d3cf9eb6d8b744c1b3c3583db6f9c4b4.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5L2g5piv5oiR55qE5pWR55Sf5ZyI,size_20,color_FFFFFF,t_70,g_se,x_16)
4、编写回调函数
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pAenvUc8-1632623238641)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210923161325355.png)]](https://img-blog.csdnimg.cn/670c068b83e1462a908b0dfe9355fdd0.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5L2g5piv5oiR55qE5pWR55Sf5ZyI,size_20,color_FFFFFF,t_70,g_se,x_16)
5、添加函数声明
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-px5U3J7x-1632623238642)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210923161413070.png)]](https://img-blog.csdnimg.cn/144a58de6f7f43b79595e1507d0da1e9.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5L2g5piv5oiR55qE5pWR55Sf5ZyI,size_20,color_FFFFFF,t_70,g_se,x_16)
6、下载调试
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jIYpHdj4-1632623238643)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210926092046479.png)]](https://img-blog.csdnimg.cn/0fe79f8892c84fb790bd35b6165aebed.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5L2g5piv5oiR55qE5pWR55Sf5ZyI,size_20,color_FFFFFF,t_70,g_se,x_16)
六、程序编写(二)
1、添加空闲中断的处理
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Z8equnsu-1632623238645)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210926100650752.png)]](https://img-blog.csdnimg.cn/7487345ce45140cdbe1036159dd3308a.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5L2g5piv5oiR55qE5pWR55Sf5ZyI,size_20,color_FFFFFF,t_70,g_se,x_16)
2、添加用户宏定义及变量定义,添加用户初始化代码。
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MalnykQb-1632623238646)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210926092433139.png)]](https://img-blog.csdnimg.cn/b1567e7dde4041ee8a4de5bc073944ff.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5L2g5piv5oiR55qE5pWR55Sf5ZyI,size_20,color_FFFFFF,t_70,g_se,x_16)
3、编写用户应用代码
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZScqVON3-1632623238647)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210926100832693.png)]](https://img-blog.csdnimg.cn/e32cb8da3c3f475b94caa064565118c7.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5L2g5piv5oiR55qE5pWR55Sf5ZyI,size_20,color_FFFFFF,t_70,g_se,x_16)
5、编写回调函数
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-52NP4zA8-1632623238648)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210926102259851.png)]](https://img-blog.csdnimg.cn/febc37d6b2d742c99ffae8bacfc2a825.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5L2g5piv5oiR55qE5pWR55Sf5ZyI,size_20,color_FFFFFF,t_70,g_se,x_16)
4、下载调试
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4wzlU4bU-1632623238649)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210926102345264.png)]](https://img-blog.csdnimg.cn/1338bfa39fcf4665a78d737a471a7055.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5L2g5piv5oiR55qE5pWR55Sf5ZyI,size_20,color_FFFFFF,t_70,g_se,x_16)
七、程序编写(三)
1、添加用户宏定义及变量定义,添加用户初始化代码。
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FVyzobjx-1632623238651)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210926092433139.png)]](https://img-blog.csdnimg.cn/3108fa0ddaa84bf395735e367ee6cb56.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5L2g5piv5oiR55qE5pWR55Sf5ZyI,size_20,color_FFFFFF,t_70,g_se,x_16)
2、编写用户应用代码
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0jXPl5MG-1632623238652)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210926092744121.png)]](https://img-blog.csdnimg.cn/a3e1d2a63a8042be81b3906d349c4b15.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5L2g5piv5oiR55qE5pWR55Sf5ZyI,size_20,color_FFFFFF,t_70,g_se,x_16)
3、编写回调函数
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zTLoJ3TR-1632623238655)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210926093920122.png)]](https://img-blog.csdnimg.cn/1104cd5682e6415693ebd9f14166784f.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5L2g5piv5oiR55qE5pWR55Sf5ZyI,size_20,color_FFFFFF,t_70,g_se,x_16)
4、下载调试

复盘一下: 第一种方法是电子科技大学的一个老师课件里的,我照着写了一下,总会出现好多bug…,解决方法:在空闲中断回调函数那停止一下DMA传输就好了。 第二种是请教同事写的,实际项目中也用的比较多。 第三种是我详细研究了一下,看了看回调函数的实现过程,最后改良了一下,代码比较简洁,以后做项目的时候用一下试试!不知道大家喜欢哪一种? 另外我用typora写好笔记,上传后图片显示不出来…
|