1. UART
UART(Universal Asynchronous Receiver/Transmitter,通用异步收发器) 是一种异步、串行通信协议(更准确说是实现该协议的硬件电路模块)。
它把并行数据转成串行数据发送出去,也能把接收到的串行数据还原成并行数据。通信双方不共用时钟线,靠事先约定的波特率和帧格式实现同步,所以叫"异步"。
核心特点:
-
异步:无时钟线,双方按约定波特率各自采样
-
串行:数据在一根线上按位依次传输
-
全双工:发送(TXD)和接收(RXD)两条数据线,可同时收发
-
仅需 3 根线即可通信:TXD、RXD、GND(共地)
帧格式:1位起始位(低电平)+ 5~8位数据位(低位在前)+ 可选1位校验位 + 1~2位停止位(高电平)。
51单片机内置一个全双工UART(对应SFR:SCON串口控制寄存器、SBUF数据缓冲器、PCON中SMOD波特率倍增位),占用中断源中的串口中断(入口地址0023H)。
常见对比:UART是"协议/模块",RS-232、RS-485、TTL是电平标准。单片机引脚输出TTL电平(0V/5V),电脑RS-232电平(±3~±15V),两者通信需MAX232芯片转换。
2. 单工、半双工、全双工的区别
按通信方向分类的三种工作方式:
| 方式 | 方向 | 能否同时收发 | 典型例子 |
|---|---|---|---|
| 单工(Simplex) | 只能单方向传输 | ❌ | 遥控器→电视、广播、LED显示屏 |
| 半双工(Half-Duplex) | 双向传输,但同一时刻只能一个方向 | ❌(需分时切换) | 对讲机、RS-485、I2C |
| 全双工(Full-Duplex) | 双向传输,且可同时收发 | ✅ | 电话、UART(TXD+RXD两根线)、SPI |
形象类比:
-
单工 = 单行道,只能往一个方向开
-
半双工 = 独木桥,两边都能过,但一次只能一辆车
-
全双工 = 双向车道,两个方向同时通行
判断关键:①数据能否双向传;②双向传输时是否需要"轮流"。
3. 串行传输和并行传输特点
串行传输(Serial) :数据在一根数据线上逐位传输 ,先低位后高位。 并行传输(Parallel) :数据在多根数据线上同时传输,如8根线一次传一个字节。
| 对比项 | 串行传输 | 并行传输 |
|---|---|---|
| 数据线数量 | 1根(单向) | n根(8/16/32...) |
| 一次传输量 | 1位 | n位 |
| 速度 | 单位时间位数少(但现代高速串口已达Gbps级) | 理论上更快的总吞吐 |
| 抗干扰/距离 | 线少、抗干扰强、传得远(RS-485可达1200m) | 线间串扰、时序偏移(skew)随距离急剧恶化 |
| 成本 | 线少、接口小、便宜 | 线多、连接器大、贵 |
| 典型应用 | UART、SPI、I2C、USB、网线 | 内存总线、LCD并口(8080时序)、老式打印机并口 |
为什么现在高速接口都是串行(USB/SATA/PCIe)? 因为并行线间的时钟偏移和串扰在高频下难以控制,而串行配合差分信号和嵌入式时钟可以跑到更高频率------"串行胜在速度上限,并行胜在瞬时吞吐",但工程上串行总线通过提高频率碾压了并行。
4.波特率
波特率(Baud Rate) :每秒传输的码元(符号)个数 ,单位 Baud(波特)。
比特率(Bit Rate) :每秒传输的二进制位数,单位 bps(bit/s)。
两者关系:
比特率 = 波特率 \\times 每码元携带的比特数
在单片机串口通信中,每个码元只携带1个比特(两电平调制),所以波特率数值上等于比特率,例如9600波特 = 每秒9600位。这也是日常混用两者的原因(严谨场合要区分:若采用QAM等多电平调制,1码元携带多个比特,比特率 > 波特率)。
常用波特率:4800、9600、14400、19200、38400、57600、115200 bps。
51单片机串口波特率计算(方式1/3,由定时器T1方式2产生):
28-2smod * focs / 32 / bps / 12
其中smod表示PCON的B7,根据实际情况带入,不是0就是1;
focs晶振频率,我们这是12M;
bps目标波特率我们这是1200
这就是为什么串口几乎都用11.0592MHz 晶振------它能被波特率时钟整除,误差极小。通信双方波特率必须一致,否则采样错位产生乱码(误差一般要求 < 2.5%)。
5. 同步通信和异步通信的区别
| 对比项 | 异步通信(UART) | 同步通信(SPI/I2C) |
|---|---|---|
| 时钟线 | 无,靠约定波特率+起始位同步 | 有,共用时钟(SCL/SCLK) |
| 帧结构 | 每个字节带起始位+停止位(帧开销大) | 连续比特流,靠同步字符/时钟对齐(开销小) |
| 速率 | 较低(时钟偏差会累积,不能太快) | 高(时钟显式传递,速率只受线长限制) |
| 发送间隔 | 字符间可任意间隔(空闲为高电平) | 时钟不停,需连续配合 |
| 线数 | 少(TXD/RXD/GND) | SPI需4线(MOSI/MISO/SCLK/CS) |
| 典型应用 | UART、RS-232 | SPI、I2C、USB、PCIe(嵌入式时钟的同步通信) |
异步的本质 :接收方检测到起始位下降沿后,按"波特率周期"在第7、8、9个时钟采样数据位中点(16倍过采样时),每个字符重新对齐一次时钟,从而容忍双方时钟的微小偏差。
同步的本质:数据与时钟一起传,接收方随时可用时钟沿锁存数据,无需约定速率,但双方必须"节拍一致"地连续传输。
6. 串口通信参数
串口通信双方必须约定一致的4个参数(简称"波特率、数据位、校验位、停止位"):
-
波特率(Baud Rate):如9600、115200,必须双方一致
-
数据位(Data Bits) :5/6/7/8位,常用8位
-
校验位(Parity):
-
无校验(None)
-
奇校验(Odd):数据位+校验位中"1"的个数为奇数
-
偶校验(Even):数据位+校验位中"1"的个数为偶数
-
-
停止位(Stop Bits) :1、1.5或2位(高电平),常用1位
常见的配置写法:"9600, 8N1" = 9600波特率、8数据位、无校验、1停止位------这是嵌入式开发中最经典的默认配置。
数据位顺序(LSB先行)在UART中是固定的,不属于可配置参数;但某些协议可配。
7. 串口通信时序
以UART一帧数据(8N1格式,发送字节0x55 = 01010101B)为例:
空闲 起始位 D0 D1 D2 D3 D4 D5 D6 D7 停止位 空闲
────┐ ┌───┐ ┌───┬───┬───┬───┬───┬───┬───┐ ┌────────────
└───┘ └──┘ 1 0 1 0 1 0 1 └──┘
高电平 低电平 │←———— 低位在前,逐位发送 ————→│ 高电平
完整时序流程:
发送方:
-
空闲 :TXD保持高电平(线路约定俗成:空闲=1)
-
起始位:拉低1个波特率周期(0),通知对方"帧开始了"
-
数据位 :从最低位D0开始逐位发送,每位持续1个波特率周期(0x55先发1、再0、再1......)
-
校验位(若有):按奇/偶约定补上校验位
-
停止位 :拉高电平1~2个周期,标志帧结束
-
回到空闲或紧接着发送下一帧
接收方:
-
一直监测RXD线
-
检测到下降沿(高→低),认为起始位到来,启动内部定时
-
在半个波特率周期后(即起始位中点)再次采样确认仍为低,防止毛刺误触发
-
之后每隔一个完整波特率周期 在各位的中点采样一次,依次读出D0~D7(共8次)
-
采样校验位、停止位;停止位必须为高,否则帧错误(FE)
-
若接收中断允许(ES=1),硬件置位RI,CPU到0023H执行中断服务程序,从SBUF读走数据
-
软件清除RI(串口标志需手动清0),准备接收下一帧
51单片机相关SFR:
-
SCON:SM0/SM1选方式(方式1最常用:8位UART、波特率可变)、REN允许接收、TI/RI收发中断标志 -
SBUF:物理上是两个独立寄存器------写SBUF=发送缓冲,读SBUF=接收缓冲(共用地址99H) -
发送:
SBUF = 0x55;硬件自动逐位移出,发完置TI;接收:收到完整帧后数据自动进SBUF,置RI
// 51串口初始化(9600, 8N1 @11.0592MHz)
void UART_Init(void)
{
SCON = 0x50; // 方式1,8位UART,允许接收(REN=1)
TMOD |= 0x20; // T1方式2,自动重装
TH1 = 0xFD; // 波特率9600 @11.0592MHz
TL1 = 0xFD;
PCON = 0x00; // SMOD=0,不倍增
ES = 1; // 允许串口中断
EA = 1;
TR1 = 1; // 启动T1
}
void UART_Send(unsigned char dat)
{
SBUF = dat; // 写SBUF启动发送
while (!TI); // 等待发送完成
TI = 0; // 软件清发送标志
}
void UART_ISR(void) interrupt 4
{
if (RI) {
RI = 0; // 软件清接收标志
recv = SBUF; // 读取接收到的数据
}
}
总结
| 问题 | 一句话答案 |
|---|---|
| UART | 通用异步收发器,无时钟线的串行全双工通信(TXD/RXD/GND三根线) |
| 单工/半双工/全双工 | 单向 / 双向分时 / 双向同时,类比单行道/独木桥/双向车道 |
| 串行 vs 并行 | 一根线逐位传(远、稳、便宜)vs 多根线同时传(快、短、贵) |
| 波特率 | 每秒传输码元数;UART中数值上等于比特率,双方必须一致 |
| 同步 vs 异步 | 有时钟线随数据传 vs 无时钟线靠约定波特率+起始位对齐 |
| 串口参数 | 波特率、数据位、校验位、停止位(9600,8N1) |
| 通信时序 | 空闲高→起始位低→数据位低位在前→校验位→停止位高,接收方检测下降沿后按波特率周期在位中点采样 |
核心记忆链:"无时钟线 → 必须约定波特率 → 必须有起始/停止位帧定界 → 接收方按位中点采样 → 标志位RI/TI需软件清0"------整条串口知识线由此串起来。
版权声明:本文为博主原创文章,转载请注明出处。 如果觉得有帮助,欢迎点赞、收藏、关注,评论区交流讨论!