波特率(Baud Rate)是指每秒传输的符号数,在串口通信中直接等同于每秒传输的二进制位数(bps, bits per second)。常见的波特率有9600、19200、38400、57600、115200等。
**位时间(Bit Time)**是传输单个二进制位所需的时间,计算公式为:
位时间(秒) = 1 / 波特率
以115200bps为例:
位时间 = 1 / 115200 ≈ 8.68μs(微秒)
这意味着每个二进制位在传输线上持续约8.68微秒。这个时间决定了:
异步串口通信对波特率误差有一定的容忍度,通常要求:
例如115200bps时:
一个完整的字节传输包含以下部分:
组成部分 | 位数 | 电平 | 说明 |
---|---|---|---|
起始位 | 1 | 低 | 标志传输开始,同步时钟 |
数据位 | 8 | 高低 | 实际数据(LSB先发) |
停止位 | 1 | 高 | 标志传输结束,恢复空闲 |
总位数:1(起始) + 8(数据) + 1(停止) = 10位
单字节传输时间 = 位数 × 位时间
以115200bps传输字符’A’(0x41)为例:
总时间 = 10 × 8.68μs ≈ 86.8μs
表:不同波特率下的字节传输时间对比
波特率 | 位时间 | 10位帧时间 | 理论最大速率 |
---|---|---|---|
9600 | 104.2μs | 1.042ms | 960字节/秒 |
115200 | 8.68μs | 86.8μs | 11,520字节/秒 |
921600 | 1.085μs | 10.85μs | 92,160字节/秒 |
字符’A’的ASCII码为0x41(二进制01000001),按照LSB-first顺序发送:
起始位(0) + 数据位(10000010) + 停止位(1)
波形时序解析:
位序: S D0 D1 D2 D3 D4 D5 D6 D7 ST
电平: 0 1 0 0 0 0 0 1 0 1
时间: |-8.68μs-| (每个电平持续相同时间)
硬件连接:
示波器设置:
协议解码(若支持):
理想波形特征:
异常波形诊断:
问题现象 | 可能原因 | 解决方案 |
---|---|---|
数据位宽度不均 | 波特率不匹配 | 校准两端波特率 |
停止位为低 | 帧格式错误 | 检查停止位设置 |
上升沿缓慢 | 信号完整性差 | 缩短线缆/加终端电阻 |
随机毛刺 | 电磁干扰 | 改善屏蔽/走线 |
通过叠加多个位周期形成的"眼图"可评估信号质量:
良好信号应具备:
硬件定时器法(推荐):
void UART_SendBit(bool bit) {
TX_PIN = bit;
Timer_Start(8.68); // 启动定时器(8.68μs)
while(!Timer_Expired()); // 等待位时间结束
}
指令周期法(需校准):
// 假设72MHz时钟,每条指令约13.89ns
#define BIT_DELAY 625 // 8.68μs / 13.89ns ≈ 625 cycles
void delay_cycles(uint32_t cycles) {
__asm__ volatile (
"1: subs %0, #1 \n"
" bne 1b"
: "+r" (cycles)
);
}
过采样技术(16倍典型值):
bool UART_ReadBit() {
uint16_t samples = 0;
for(int i=0; i<16; i++) {
samples += RX_PIN;
delay_cycles(BIT_DELAY/16);
}
return (samples > 8); // 多数表决
}
帧错误检测:
if(stop_bit != HIGH) {
error_count++;
if(error_count > MAX_ERRORS) {
reinit_uart(); // 重新初始化
}
}
现象:长帧传输时后部数据出错
原理分析:
解决方案:
TTL与RS232转换:
[MCU] --(TTL 0/3.3V)--> [MAX3232] --(RS232 ±15V)--> [PC]
关键参数:
硬件流控(RTS/CTS):
// 发送端
while(CTS_PIN == HIGH); // 等待接收端就绪
UART_SendByte(data);
// 接收端
if(buffer_ready()) {
RTS_PIN = LOW; // 暂停接收
process_buffer();
RTS_PIN = HIGH; // 恢复接收
}
高效传输架构:
[应用层] → [DMA缓冲区] → (硬件UART)
↑
[中断服务程序]
配置示例(STM32Cube):
huart1.hdmatx = &hdma_usart1_tx;
HAL_UART_Transmit_DMA(&huart1, buffer, len);
算法原理:
代码片段:
float detect_baud() {
while(RX_PIN == HIGH); // 等待起始位
uint32_t t1 = get_micros();
while(RX_PIN == LOW); // 测量起始位宽度
uint32_t t2 = get_micros();
return 1000000.0 / (t2 - t1);
}
动态波特率调整:
void set_low_power_mode() {
if(battery_low) {
UART_Init(9600); // 切换至低速
enable_sleep();
}
}
深入理解串口通信的波特率计算(1/115200≈8.68μs)和帧结构组成(10位/字节),是嵌入式开发的基础能力。通过本文介绍的理论计算、示波器检测和软件实现方法,开发者可以:
实际应用中建议:
随着技术进步,虽然高速USB、以太网等接口日益普及,但串口因其简单可靠,仍然是嵌入式调试、工业控制等场景的首选方案。掌握这些核心知识,将为您的嵌入式开发之路奠定坚实基础。