<?xml version="1.0" encoding="UTF-8"?><?xml-stylesheet href="/scripts/pretty-feed-v3.xsl" type="text/xsl"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:h="http://www.w3.org/TR/html4/"><channel><title>OutlierLi</title><description>Stay hungry, stay foolish</description><link>https://outlierli-s-blog.pages.dev</link><item><title>串口通信原理与流控</title><link>https://outlierli-s-blog.pages.dev/blog/serial-communication-flow-control/post</link><guid isPermaLink="true">https://outlierli-s-blog.pages.dev/blog/serial-communication-flow-control/post</guid><description>梳理串口通信中的软硬件流控、UART 数据帧、轮询、中断、DMA 以及发送状态机。</description><pubDate>Sat, 18 Jul 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;流控&lt;/h2&gt;
&lt;p&gt;流控分为硬流控和软流控。软流控的实现需要占据数据通道，硬流控通过硬件实现，无需占据数据通道。&lt;/p&gt;
&lt;h2&gt;串口流控示例&lt;/h2&gt;
&lt;p&gt;串口流控：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://outlierli-s-blog.pages.dev/images/serial-communication-flow-control/uart-flow-control.png&quot; alt=&quot;串口流控示例&quot;&gt;&lt;/p&gt;
&lt;p&gt;串口通过 TX 和 RX 发送数据，通过拉高或者拉低 TX 电平来发送数据，通过 RX 的电平采样数据来接收数据。&lt;/p&gt;
&lt;p&gt;RTS：输入管脚，请求对方发送数据。高电平表示不允许对端发送，低电平表示允许对端发送数据。&lt;/p&gt;
&lt;h2&gt;流控实现细节分析&lt;/h2&gt;
&lt;h3&gt;串口数据传输流程&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://outlierli-s-blog.pages.dev/images/serial-communication-flow-control/uart-frame.png&quot; alt=&quot;串口数据传输流程&quot;&gt;&lt;/p&gt;
&lt;p&gt;起始位、校验位、结束位，针对的是每一个字节。也就是一个字节 8 bit，加上起始位、校验位、结束位，发送到 TX 线上的电平信号为 11 bit。默认 TX 线常态为高，所以停止位为 1。&lt;/p&gt;
&lt;p&gt;轮询数据传输流程：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://outlierli-s-blog.pages.dev/images/serial-communication-flow-control/polling-transfer.png&quot; alt=&quot;轮询数据传输流程&quot;&gt;&lt;/p&gt;
&lt;p&gt;轮询会大量占据 CPU 的时间片，对性能影响很大。外循环和内循环实现了生产者-消费者模型。&lt;/p&gt;
&lt;p&gt;中断实现流程：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://outlierli-s-blog.pages.dev/images/serial-communication-flow-control/interrupt-transfer.png&quot; alt=&quot;中断实现流程&quot;&gt;&lt;/p&gt;
&lt;p&gt;中断是大部分设备使用的方案。&lt;/p&gt;
&lt;p&gt;DMA 实现流程：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://outlierli-s-blog.pages.dev/images/serial-communication-flow-control/dma-transfer.png&quot; alt=&quot;DMA 实现流程&quot;&gt;&lt;/p&gt;
&lt;p&gt;发送状态机 FSM：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://outlierli-s-blog.pages.dev/images/serial-communication-flow-control/tx-fsm.png&quot; alt=&quot;发送状态机 FSM&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;bit_tick&lt;/code&gt; 为波特率时钟驱动。流控也是在这里进行控制，CTS 为输入管脚，控制本端的 TX。当 CTS 为高，FIFO 即使不空，也不会进入 LOAD 流程，不会进行 START，所以看上去就是卡在了当前字节。&lt;/p&gt;</content:encoded></item></channel></rss>