1.8 串口通信实验
学习目标:理解 UART 串口通信原理,掌握波特率设置,实现单片机与上位机(虚拟终端)的收发通信。
实验原理
串口通信基础
UART(通用异步收发器)通过一根发送线(TXD)和一根接收线(RXD)按异步串行方式传输数据。51 单片机串口(UART)引脚:
- P3.0 / RXD:接收数据
- P3.1 / TXD:发送数据
单片机 上位机
┌──────┐ ┌──────────┐
│ TXD ├──────────────►│ RXD │
│ RXD ├───────────────│ TXD │
│ GND ├───────────────│ GND │
└──────┘ └──────────┘
(需共地!)数据帧格式
起始位(0) | D0 | D1 | D2 | D3 | D4 | D5 | D6 | D7 | 停止位(1)- 空闲时为高电平
- 起始位:1 位低电平(标志数据开始)
- 数据位:8 位(本实验)
- 停止位:1 位高电平(标志数据结束)
波特率
波特率 = 每秒传输的比特数(bps)。51 串口波特率由定时器 1 产生:
波特率 = (2^SMOD / 32) × 定时器1溢出率常用配置:12MHz 晶振,定时器 1 方式 2 自动重装,波特率 4800 时初值 0xF3。
程序设计
串口初始化函数
c
/****************************************************
* 串口初始化:方式1(8位UART),波特率4800
* 使用定时器1方式2作为波特率发生器
****************************************************/
void uart_init(void)
{
SCON = 0x50; // 方式1:8位UART,REN=1(允许接收)
TMOD &= 0x0F; // 清定时器1模式位
TMOD |= 0x20; // 定时器1,方式2(8位自动重装)
TH1 = 0xF3; // 波特率 4800(12MHz)
TL1 = 0xF3;
TR1 = 1; // 启动定时器1
// ES = 1; // (如需中断接收,打开串口中断)
// EA = 1; // 打开总中断
}发送一个字节 / 字符串
c
// 发送一个字节
void send_byte(unsigned char dat)
{
SBUF = dat; // 数据写入发送缓冲
while (TI == 0); // 等待发送完成
TI = 0; // 清发送完成标志
}
// 发送字符串
void send_string(unsigned char *str)
{
while (*str != '\0')
{
send_byte(*str++);
}
}主程序:发送 + 接收回显
c
/****************************************************
* 实验名称:串口通信——发送字符串 + 接收回显
****************************************************/
#include <reg51.h>
void uart_init(void);
void send_byte(unsigned char dat);
void send_string(unsigned char *str);
// 串口中断接收服务函数
void uart_isr(void) interrupt 4
{
unsigned char recv;
if (RI) // 接收完成标志
{
RI = 0; // 清接收标志
recv = SBUF; // 读取接收数据
send_byte(recv); // 回显(发回上位机)
}
}
void main(void)
{
uart_init();
ES = 1; // 使能串口中断
EA = 1; // 开总中断
send_string("Hello, AIOTEER!\r\n");
while (1)
{
// 主循环:中断接收处理
}
}Proteus 虚拟终端
Proteus 提供 VIRTUAL TERMINAL(虚拟终端) 元件,可模拟电脑串口助手:
- 放置
VIRTUAL TERMINAL - 连接:RXD 接单片机 TXD,TXD 接单片机 RXD
- 双击虚拟终端,设置波特率 4800、8 数据位、无校验、1 停止位
- 运行仿真,即可看到单片机发送的字符串
AT89C51 VIRTUAL TERMINAL
┌──────┐ ┌────────────┐
│ TXD ├──────────►│ RXD │
│ RXD ├───────────│ TXD │
└──────┘ │ GND │
└────────────┘
(波特率 4800)关键知识点
| 知识点 | 说明 |
|---|---|
| SCON | 串口控制寄存器(SM0/SM1 选方式,REN 允许接收) |
| SBUF | 发送/接收缓冲寄存器(物理上是两个) |
| TI | 发送完成标志 |
| RI | 接收完成标志 |
| 波特率发生器 | 定时器 1 方式 2 常用作波特率发生器 |
| 共地 | 通信双方必须共地,否则电平参考不同 |
波特率与初值对照(12MHz)
| 波特率 | TH1/TL1(方式2) | 误差 |
|---|---|---|
| 2400 | 0xF3 | 0.16% |
| 4800 | 0xF3(SMOD=1) | 0.16% |
| 9600 | 0xFD | 0.16% |
12MHz 下 9600 波特率有一定误差但可工作;11.0592MHz 晶振专为串口设计,可精确产生 9600/19200 等标准波特率。
常见问题
Q1:虚拟终端收不到数据?
- 检查波特率设置是否一致
- 检查 TXD/RXD 是否交叉连接
- 检查是否共地
Q2:收到乱码?
- 波特率不匹配(误差过大)
- 数据位/停止位设置不一致
- 建议改用 11.0592MHz 晶振
Q3:发送字符串不完整?
- 检查发送函数 TI 标志处理
- 检查字符串是否以 '\0' 结尾
实验任务
- 单片机发送字符串"Hello"到虚拟终端
- 实现接收回显(收到什么发回什么)
- 扩展:用 Proteus 虚拟终端 + 串口控制 LED(收到 '1' 点亮,'0' 熄灭)
考核点 / 验收标准
| 考核项 | 验收标准 | 分值 |
|---|---|---|
| 串口初始化 | SCON/TMOD/TH1 等配置正确,波特率准确 | 30 |
| 数据发送 | 能发送字符串到虚拟终端 | 25 |
| 数据接收 | 能接收并回显数据 | 25 |
| 协议理解 | 能说明数据帧格式与波特率含义 | 20 |
实操要求:现场演示串口收发,收到 '1' 点亮 LED、'0' 熄灭。