STM32 串口通信 (UART) 全栈底层复习指南
目录一、 物理层与通信协议基础 (底层时序)1. 硬件连接规则2. 通信时序与数据帧 (以最常用的 10 位标准帧 8N1 为例)二、 UART 底层硬件架构 (双缓冲机制)1. 接收双缓冲移位寄存器 RDR (接收数据寄存器)2. 发送双缓冲TDR (发送数据寄存器) 移位寄存器3. 波特率发生器 (Baud Rate Generator)三、 底层硬件的四大核心中断机制四、 软件生态演进标准库 vs HAL 库五、 终极奥义HAL 库 API 与底层硬件中断的映射关系1. 基础系列 HAL_UART_... (已知长度处理)2. 扩展系列 HAL_UARTEx_... (不定长数据处理)极简速记对照表一、 物理层与通信协议基础 (底层时序)串口UART是一种异步串行通信协议。它的根本在于**“双方约定相同的波特率并用规定的速率去采样电平数据”**。1. 硬件连接规则交叉连接设备 A 的 TX发送数据线连设备 B 的 RX接收数据线设备 A 的 RX 连设备 B 的 TX。必须共地 (GND)串口是通过电压高低来判断 0 和 1 的。如果没有连接 GND 提供统一的电压参考零点通信绝对会乱码或无法识别。2. 通信时序与数据帧 (以最常用的 10 位标准帧 8N1 为例)在总线空闲时RX 和 TX 线的默认状态为高电平。发送一次常规数据需要 10 位Bit起始位 (1位)把高电平拉低。这是极其重要的一步接收方检测到电平由高变低的“下降沿”才知道数据要来了并开始按波特率计时。数据位 (8位)真正的有效数据。低电平代表 0高电平代表 1。(注意串口底层是低位 LSB 先发高位 MSB 后发)。校验位 (可选)通常不用配置为 None。停止位 (1位)【 核心要求】必须将电平拉高停止位必须是高电平目的是强行让总线恢复到默认的高电平空闲状态这样才能保证下一个起始位的“由高变低”能被成功检测到。二、 UART 底层硬件架构 (双缓冲机制)单片机内部到底长什么样为什么会有“移位寄存器”和“数据寄存器”之分其实串口内部采用的是**“双缓冲架构 (Double Buffer)”**。1. 接收双缓冲移位寄存器 RDR (接收数据寄存器)接收移位寄存器这是一个在底层默默“接砖头”的临时工。外部 RX 线上的数据是一位一位串行进来的移位寄存器就像一个抽屉每来一个 Bit它就把抽屉里的数据往左推一格直到 8 个 Bit 全部收齐。RDR (接收数据寄存器)当移位寄存器凑齐 8 个 Bit 后它会瞬间把这 8 个 Bit并行一次性倒进 RDR 寄存器中。此时触发RXNE中断通知 CPU“砖凑齐了快拿走”为什么搞双缓冲如果没有 RDRCPU 必须在第 8 个 Bit 刚收完的一瞬间立刻把数据拿走否则第 9 个 Bit 进来就会把数据覆盖。有了双缓冲移位寄存器可以继续收下一个字节CPU 只要在下一个字节收完之前把 RDR 里的数据读走就行大大降低了 CPU 的压力。2. 发送双缓冲TDR (发送数据寄存器) 移位寄存器逻辑完全反过来CPU 把一个字节写进 TDR。硬件会自动把 TDR 的数据倒入“发送移位寄存器”。移位寄存器接管后按照波特率一位一位地通过 TX 引脚“挤”出去。3. 波特率发生器 (Baud Rate Generator)它是串口的“心脏起搏器”。内部有一个分频器把单片机的系统时钟如 72MHz分频成你需要的采样频率如 115200 bps。三、 底层硬件的四大核心中断机制串口内部就像一个流水线四大状态都会产生硬件标志位Flag。必须满足条件“硬件标志位产生 (Flag1) 软件开启中断允许 (IE1) NVIC 配置放行”CPU 才会真正跳入真正的中断函数。中断类型标志位触发条件底层白话解释接收非空中断RXNE数据从移位寄存器转移到接收数据寄存器 (DR) 后触发。“收到了 1 个完整字节放在 DR 里了CPU 快来拿走”发送为空中断TXECPU 将数据放入发送数据寄存器 (DR) 后数据进入发送移位寄存器。此时 DR 被腾空触发。“我手里的这块砖DR扔进流水线了CPU 可以给我下一块砖了”发送完成中断TC不仅发送 DR 空了连发送移位寄存器也空了最后一个停止位彻底发完。“全部砖头都彻底从引脚上丢出去了打完收工”总线空闲中断IDLE接收到字节后后面连着 1 个完整字节的时间10个Bit时长RX线都是高电平。“运砖车断档了外面没动静了这批货发完了”四、 软件生态演进标准库 vs HAL 库当硬件中断产生时软件怎么处理标准库 (手工小作坊)所有硬件中断都会进入同一个入口函数USARTx_IRQHandler。软件必须在里面自己写if判断if(USART_GetITStatus(...) ! RESET)去查看到底是谁触发的警报并且最后还需要手动清除标志位。HAL 库 (现代化工厂)我们只需要调用对应的 API。HAL 库底层替我们写好了那几百行的if判断和清除标志位代码它判断完之后会自动呼叫对应的“回调函数 (Callback)”交给我们处理数据。五、 终极奥义HAL 库 API 与底层硬件中断的映射关系在 HAL 库中表面上你只是调用了一个函数但底层其实是开启了不同的硬件警报器。根据是否使用Ex扩展函数底层的逻辑有天壤之别。1. 基础系列HAL_UART_...(已知长度处理)这个系列处理的是死心眼的“定长”任务它绝对不会去开启空闲中断 (IDLE)。纯中断接收 (HAL_UART_Receive_IT)底层开关开启RXNEIE。触发事件仅靠RXNE标志位。逻辑外部每发来 1 个字节打断 1 次 CPU。搬走数据后计数器减 1。减到 0 时关掉RXNEIE并呼叫回调。纯中断发送 (HAL_UART_Transmit_IT)底层开关先开TXEIE后开TCIE。触发事件接力赛。先由TXE触发塞数据最后一个字节离开引脚时由TC触发回调。DMA 接收 (HAL_UART_Receive_DMA)底层开关开启 DMA 控制器中断 (TCIE,HTIE)。强制关闭串口RXNEIE触发事件只有 DMA 的TC(满载) 或HT(过半) 能触发中断。串口本身装聋作哑。2. 扩展系列HAL_UARTEx_...(不定长数据处理)这个系列带有ToIdle字眼是专门为了对付“不知道对方发多少”而生的它的核心灵魂就是必定会开启串口的 IDLE 中断。纯中断空闲接收 (HAL_UARTEx_ReceiveToIdle_IT)底层开关RXNEIEIDLEIE。触发事件RXNE搬砖IDLE负责断流截断结算。混合双打。DMA 空闲接收 (HAL_UARTEx_ReceiveToIdle_DMA) - 【终极神仙函数】底层开关DMA 控制器中断 (TCIE,HTIE) 串口的IDLEIE。依然强制关闭RXNEIE。触发事件 (跨部门竞速赛)部门 A (DMA 控制器)数据刚好塞满触发DMA 的TC或HT过半。部门 B (串口门卫)数据没塞满但中途断流了触发串口的IDLE。殊途同归无论哪个硬件标志位触发HAL 库都会聪明的计算出真实的字节数Size并最终统一导向同一个回调函数RxEventCallback。极简速记对照表你调用的 HAL 库 API数据搬运工触发 CPU 中断的底层硬件标志 (Flag)HAL_UART_Receive_ITCPU 亲力亲为仅 RXNE(每字节 1 次)HAL_UART_Receive_DMADMA 硬件搬运仅 DMA TC / HT(串口装聋作哑容易死等)HAL_UARTEx_ReceiveToIdle_ITCPU 亲力亲为RXNE(每字节搬运) IDLE(断流截断)HAL_UARTEx_ReceiveToIdle_DMADMA 硬件搬运DMA TC / HT(满载保底) 串口 IDLE(断流截断工业首选)
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2544333.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!