当前位置: 首页 > news >正文

【STM32】串口的阻塞、中断、DMA收发

目录

阻塞

串口阻塞发送

串口阻塞接收

中断

串口中断发送

串口中断接收

DMA

串口DMA发送

串口DMA接收

本文基于STM32F103CBT6单片机,分别使用串口的阻塞收发函数、中断收发函数、DMA收发函数进行测试

阻塞

串口阻塞发送

定义字符数组p

char p[10] = "hello\r\n";

调试观察其地址为0x20000004

在单片机内存中如下图

主循环中进行发送

  while (1){HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);HAL_UART_Transmit(&huart1, p, 15, 100);HAL_Delay(500);/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}

发15个字节,起始地址是字符数组第1个元素的地址,亦即0x20000004

打印出来的内容就是0x2000004++15这个范围的内容

当发送量巨大而超时时间又比较短时,就会超时

这种阻塞式发送,MCU会一直处理串口的发送,后续的代码只能等待发送完毕才能执行

串口的波特率是115200,5ms大概发送五十多个字节

当发送超时后,将停止串口发送,并直接执行下一条语句

串口阻塞接收

定义一个存放接收内容的数组

char rx[10];

主循环内使用接收函数,超时时间为500ms

  while (1){HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);HAL_UART_Receive(&huart1, rx, 10, 500);HAL_Delay(500);/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}

观察发现LED灯的闪烁频率由1hz变成0.5hz了,这是因为现在没有给串口发送任何东西,以至于串口一直超时,直到超时时间到达设定的500ms才会继续往下运行。

如果超时时间设置特别小,而需要接收的数据量又比较大的话,就永远也不会接收满了,就一直接收超时,跳转下一条语句

上位机不停地发送数据,但接收函数的超时时间仅设置1ms,就不能接收满预设的100字节,会一直超时,最多大概收到23个字节

如果超时时间较长,只要串口没收满设定的10字节数组,就会一直等待,后续代码无法执行

如果在等待期间有接收满10字节,就会立刻运行下面的代码,并将收到的内容存放至rx数组

中断

串口中断发送

勾选串口全局中断,生成代码

在主循环前面发送1024个字节的数据

uartStatus = HAL_UART_Transmit_IT(&huart1, p, 1024);/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){HAL_Delay(500);HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}

并在翻转电平和中断函数内打断点,程序会先进入中断服务函数,因为发送1024字节的时间小于500ms

如果把串口发送放入主循环,且delay时间设置50ms会造成串口busy

主循环每执行一次串口发送,except++

每成功发送完毕一次,sendok++

调试发现基本有一半的时间里是处于串口发送繁忙状态而没有发出

因为发送1024字节大概需要100ms,差不多两次循环才能让串口处于发送空闲状态

中断的好处是发送过程中MCU不会一直等待直到发送完毕,可以继续执行下面的语句

只要注意不要在还没有发送完毕就继续开始新的发送

串口中断接收

在主循环前调用串口中断接收

当串口助手发送超过10字节的数据时,进入串口接收中断,切换LED亮灭,并将设定的10字节内容存放至rx数组

继续发送,将不再进入接收中断

在主循环内反复调用串口中断接收函数

串口助手不发送任何内容,串口将处于接收繁忙状态

串口助手每50ms发送一次超过10字节的数据,串口接收状态将一直处于OK

由于调用接收中断和上位机下发内容的周期都是接近50ms,那么在调用语句后不超过50ms的时间内(下一次调用语句前),上位机就能及时地发送超过10字节的内容,触发接收中断

如果串口助手发送间隔小于50ms,会触发overrun错误

串口框架图表明引脚检测到电平信号后进行转换,给移位寄存器,再给RDR寄存器

结合overrun故障的描述就是当RDR寄存器不是空的时候,移位寄存器试图给RDR寄存器transfer数据——还没来得及拿走旧的数据,新的数据又来了

当出现这个故障时,RDR寄存器的值不会丢失,只更新移位寄存器的内容

在调用接收中断函数前将overrun标志位清除,这样即便串口助手发送频率高于接收函数调用频率,也可以接收到新发的数据

DMA

串口DMA发送

增加发送DMA

在主循环内每隔50ms进行一次DMA发送

第一次发送成功,串口助手显示接收到1024字节

由于发送1024字节所需时间大于50ms,在第二次进入循环时就会发生busy

预期发送次数大约是实际发送完毕次数的一半,因为发送1024字节的数据,大概要100ms,每2次才能成功发送一次

DMA的好处是发送过程中MCU不会一直等待直到发送完毕,可以继续执行下面的语句

只要注意不要在还没有发送完毕就继续开始新的发送

串口DMA接收

增加接收DMA

串口助手每10ms发送一次数据,偶尔会有busy出现,但不会像中断接收那样overrun

参考DMA的接收机制,当出现RXNE后,数据就被搬运走了,这个过程很快

串口的DMA和串口中断有点相似,但DMA更适合处理高速,大量的数据,DMA 硬件会在同一个总线时钟周期自动把 RDR 里的数据搬到内存缓冲区。读走后,RDR 立即空闲,RXNE 被自动清零。只要 DMA 通道使能且缓冲区未满,RDR 几乎“瞬时”被取走。过程无需 CPU 参与,搬运速度远快于中断响应。

中断则靠 CPU 在中断中数据搬运,慢了就丢。


文章转载自:

http://vt7JZg0l.btrfm.cn
http://aL0XXVrb.btrfm.cn
http://cAvl8Mfq.btrfm.cn
http://ZHzPFj0Z.btrfm.cn
http://XDrviXXN.btrfm.cn
http://Tbk3Inw3.btrfm.cn
http://ggeA6hmB.btrfm.cn
http://HGdbQqRu.btrfm.cn
http://WRt1UWuv.btrfm.cn
http://VWVSOW10.btrfm.cn
http://xmj21I2v.btrfm.cn
http://EB1bifs9.btrfm.cn
http://UTsbQ1sM.btrfm.cn
http://ERD5jvRS.btrfm.cn
http://2NWNCOKN.btrfm.cn
http://kIfVi4zj.btrfm.cn
http://cOpgwFbz.btrfm.cn
http://VLYXxvL7.btrfm.cn
http://8xeTgrde.btrfm.cn
http://pzUNWTXr.btrfm.cn
http://CF69zbMn.btrfm.cn
http://Ce70KkKp.btrfm.cn
http://glpL8v2N.btrfm.cn
http://Bo6Y1Scc.btrfm.cn
http://Ryk5yefQ.btrfm.cn
http://oqx5hMAN.btrfm.cn
http://lQLyoOvg.btrfm.cn
http://OYXejJrE.btrfm.cn
http://r61yfNgZ.btrfm.cn
http://zDeydhqc.btrfm.cn
http://www.dtcms.com/a/383577.html

相关文章:

  • win10系统 文件夹被占用无法删除
  • LawGPT:基于中文法律知识的大模型
  • 手搓多模态-10 旋转位置编码的原理和实现
  • C# --- dispose机制与using关键字
  • HakcMyVM-Aurora
  • Flask学习笔记(一)
  • MobaXterm软件访问ZYNQ板卡的Linux系统
  • 基于vLLM与YOLO的智能图像分类系统
  • 标准CAN帧介绍
  • 蚂蚁矿机S19 Pro 104T技术参数解析及性能分析
  • 一小时解决RabbitMQ面试题
  • HBM4量产就绪|2026年AI与数据中心新标配
  • 细粒度图像分类的可解释性Finer-CAM
  • C++中多线程core的问题分析和总结
  • scrapy框架-day02
  • 电商导购平台的移动端架构设计:React Native在多端统一中的实践
  • class_9:java 抽象类和接口
  • [硬件电路-209]:电子携带两种能量,一种是电流宏观运动的动能,一种是绕着原子核运动的原子轨道能量;前者是电势能与热能转化的媒介;后者是实现光能与电能的转化
  • HBase启动报错“Master is initializing”解决方案
  • 交换机的级联和堆叠
  • QT加密和哈希
  • 历史数据分析——中科曙光
  • Dropout:深度学习中的随机丢弃正则化技术
  • 数组存储 · 行主序与列主序 | 应用 / 基地址 / 选择策略
  • 贪心算法应用:最早截止时间优先(EDF)问题详解
  • 每天五分钟深度学习:神经网络的权重参数如何初始化
  • BisenetV1/2网络以及模型推理转换
  • Codeforces Round 1050 (Div. 4)补题
  • 【Java后端】Spring Boot 多模块项目实战:从零搭建父工程与子模块
  • c++命名空间详解