能否通过编程配置8051的UART数据帧字长、停止位及奇偶校验?
8051 UART帧格式配置说明
支持范围明确
标准8051核心的UART并非支持所有你提到的组合,具体支持情况如下:
- 字长:仅支持8位和9位,不支持5-7位(需软件模拟)
- 停止位:仅支持1位(硬件原生),2位需软件模拟;不支持1.5位
- 奇偶校验:支持无校验、偶校验、奇校验(通过9位模式的第9位实现)
核心配置寄存器
8051 UART的配置主要依赖SCON(串行控制寄存器,地址0x98)和PCON(电源控制寄存器,地址0x87):
SCON寄存器位定义
| 位 | 符号 | 功能说明 |
|---|---|---|
| 7 | SM0 | 模式选择位,配合SM1使用 |
| 6 | SM1 | 模式选择位 |
| 5 | SM2 | 多机通信控制位(模式2/3下有效) |
| 4 | REN | 允许接收位(置1开启接收) |
| 3 | TB8 | 发送第9位数据(模式2/3下可作为奇偶校验位) |
| 2 | RB8 | 接收第9位数据(模式2/3下对应发送的TB8) |
| 1 | TI | 发送完成中断标志(需软件清零) |
| 0 | RI | 接收完成中断标志(需软件清零) |
模式选择(SM0+SM1)
00:模式0(移位寄存器模式,非异步UART)01:模式1(8位UART,1停止位,波特率由定时器1控制)10:模式2(9位UART,1停止位,波特率固定为fosc/32或fosc/64)11:模式3(9位UART,1停止位,波特率由定时器1控制)
PCON寄存器
SMOD位(第7位):置1时将UART波特率加倍(仅模式1/2/3有效)
具体配置流程与代码示例
1. 8位字长、1停止位、无校验(模式1)
这是最常用的异步通信模式,波特率由定时器1的8位自动重装模式(模式2)控制。
配置步骤:
- 设置
SM0=0、SM1=1,选择模式1 - 置
REN=1开启接收(若需要接收功能) - 配置定时器1为模式2,设置初值计算波特率
- 可选:置
SMOD=1实现波特率加倍
代码示例(以11.0592MHz晶振、9600波特率为例):
#include <reg51.h> // UART初始化 void uart_init(void) { SCON = 0x50; // SM0=0, SM1=1(模式1), REN=1(允许接收) TMOD |= 0x20; // 定时器1设为模式2(8位自动重装) TH1 = 0xFD; // 11.0592MHz晶振,9600波特率(SMOD=0)的初值 TL1 = 0xFD; TR1 = 1; // 启动定时器1 // PCON |= 0x80; // 若需波特率加倍,取消注释,此时TH1=0xFA } // 发送单个字符 void uart_send_char(unsigned char ch) { SBUF = ch; while(!TI); // 等待发送完成 TI = 0; // 清零发送标志 } // 接收单个字符 unsigned char uart_receive_char(void) { while(!RI); // 等待接收完成 RI = 0; // 清零接收标志 return SBUF; }
2. 9位字长、1停止位、奇偶校验(模式2/3)
利用模式2/3的第9位(TB8/RB8)实现奇偶校验,模式2波特率固定,模式3波特率可变。
配置步骤(偶校验为例):
- 选择模式2(
SM0=1、SM1=0)或模式3(SM0=1、SM1=1) - 置
REN=1开启接收 - 发送前计算数据的奇偶位,赋值给
TB8;接收时对比RB8与数据奇偶性
代码示例(模式2,偶校验):
#include <reg51.h> // UART初始化(模式2,波特率fosc/32) void uart_init(void) { SCON = 0xD0; // SM0=1, SM1=0(模式2), REN=1 PCON |= 0x80; // SMOD=1,波特率为11.0592MHz/32=345600 } // 带偶校验发送字符 void uart_send_char_even_parity(unsigned char ch) { unsigned char parity = __builtin_parity(ch); // 计算数据中1的个数奇偶性 TB8 = !parity; // 偶校验:TB8=1 当数据1的个数为奇数,使总个数为偶数 SBUF = ch; while(!TI); TI = 0; } // 带偶校验接收字符,校验错误返回0xFF unsigned char uart_receive_char_even_parity(void) { unsigned char ch, parity; while(!RI); RI = 0; ch = SBUF; parity = __builtin_parity(ch); if(RB8 != !parity) { // 对比奇偶位 return 0xFF; // 校验错误返回标志 } return ch; }
不支持配置的处理方案
- 5-7位字长:硬件不支持,需软件处理:发送时在数据末尾补0至8位,接收时仅取前5-7位有效数据
- 2停止位:硬件仅支持1停止位,可通过软件在发送完数据后额外发送一个空闲位(逻辑1)模拟
- 1.5停止位:硬件完全不支持,无法通过寄存器配置,不建议软件模拟(兼容性极差)
内容的提问来源于stack exchange,提问作者paramesh pallela
相关产品推荐
相关产品推荐

