单片机串口收发数据不可靠--用做指令会执行错误动作
单片机串口通信里最常见、最头疼的问题之一:发送端发出去的数据 ≠ 接收端收到的数据,一旦用来当指令,就会执行错误动作。
1. 为何不一样
串口(UART)本身是不可靠通信,没有纠错、没有重发。出现错误的常见原因:
电平干扰:电机、继电器、电源噪声、线太长,都会把 0 变成 1、1 变成 0。
波特率不匹配 / 时钟偏差:两个单片机晶振精度不一样,时间久了就错位,直接乱码。
起始位、停止位出错;一个位错,整帧数据就废了。
缓冲区溢出:发送太快、接收来不及处理,数据直接丢失或错位。
结果就是:你发0x01(开灯),收到可能是0x11、0x00甚至乱码,单片机就会执行错误指令。
2. 实际工程如何避免
不直接裸传指令,必须加校验和保护。
常用方案(从简单到实用):
① 简单校验:奇偶校验
单片机硬件自带,能检出单 bit 错误,但不能纠错,错了就丢帧。
② 和校验 / 异或校验(常用)
格式类似:帧头 + 指令 + 数据长度 + 数据 + 校验和 + 帧尾
接收端重新算一遍校验和,对不上就直接丢弃,不执行。
③ 更稳一点:CRC16/CRC32
工业常用,抗干扰强,几乎不会误判。
④ 应答机制(ACK)
- 发送 → 等待应答
- 收不到正确应答 → 重发
- 多次失败 → 报错
这样就能保证:要么收到正确指令,要么不收,绝不乱执行。
3. 最关键的原则
单片机绝对不能收到什么就执行什么!
正确逻辑应该是:
- 接收一帧完整数据
- 校验通过
- 指令在合法列表里
- 再执行
否则:
- 电机乱转
- 继电器乱吸合
- 加热失控
- 甚至设备损坏、危险
4. 总结
- 裸奔串口确实会传错,指令会乱。
- 裸奔串口(不加校验)只能用在不危险、不重要的场合。
- 工业 / 控制场景必须:帧结构 + 校验 + 合法指令判断。
