51单片机字符串口通信为什么乱码?终于找到原因了

博主分享了在单片机开发中遇到的串口通信乱码问题,原因是晶振频率不匹配导致的波特率错误。通过调整晶振频率和设置TH1寄存器值,成功解决了4800bps通信问题。同时提供了详细的代码示例和工程资源,供初学者参考。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

        被这个问题卡了3天,代码很简单就是乱码出问题,烦恼!

        后来查资料找到原因,晶振12MHz和11.0592Hz的问题。

        如果你用的是12Mhz的单片机,定时器初值TH1一般要设置到E6(2400bps)、F3(4800bps)。

对应的在上位机配置UART串口时,选取2400 4800bps。如果试了不行,那就换更低的1200bps。

修改前

修改后

2021.8.12

做了半天才发现我的晶振是11.0592Mhz,为啥对应的开发板视频讲的是12Mhz。

以4800bps为例,TH1=TL1=0xF4,SMOD=1,波特率翻倍=2*2400bps。这样就不会乱码了

-----------------------------------------------------------分---割---线-------------------------------------------------------

        我看大家跟我初学51一样,有很多小问题。我把之前总结的word文档和工程(有详细备注)直接发出来吧。方便大家寻找。

链接:https://pan.baidu.com/s/1y2sR97rVwUw48-U64_rg1Q?pwd=Lu26 
提取码:Lu26

例如红外通信的学习笔记:

 

 

   例如练习工程:

 Uart单字节工程

/************************************************
******************
*实验现象:下载程序后,在串口发送助手上输入1发送后,会看到单片机发送到上位机的数字1。
*数据传输流程:1.上位机发送字符1; 2.单片机串口接收到1,然后单片机串口发送1给上位机; 3.上位机接收到字符1后显示出来
		   	
*实验目的:	验证串口发送功能
*注意事项:	1.串口助手的HEX显示和HEX发送的2个功能,使用时必须同时打开或关闭。
			2.串口是可以同时收/发的,虽然都是用SBUF,但却是两个独立的寄存器,互不影响,只是都叫一个名,SBUF。
******************
************************************************/
#include "reg52.h"			 //此文件中定义了单片机的一些特殊功能寄存器

typedef unsigned int u16;	  //对数据类型进行声明定义
typedef unsigned char u8;


void UsartInit()
{
	SCON=0X50;			   //确定串行口方式为1,且打开串行接受位REN
	TMOD=0X20;			   //选择定时器方式2
	PCON=0X80;			   //即SMOD=1,波特率翻倍2400bps*2						   
	TH1=0XF4;			   //串口通信中,初值高8位等于初值低8位,即TH1=TL1
	TL1=TH1;			   //由串口工作方式1的波特率4800、T1溢出率、晶振是11.0592MHz计算得出						  
	ES=1;				   //串行口中断允许位			
	EA=1;				   //CPU中断允许(总允许)位
	TR1=1;				   //打开T1定时器	
}						    
						  
						  
void main()
{	
	UsartInit();  //	串口初始化
	while(1);		
}


void Usart() interrupt 4
{
	u8 receiveData;
									 
	receiveData=SBUF;		//接受缓冲寄存器,接受完以后RI硬件置1
	RI = 0;					//每接受1字节,RI需要软件置0
	SBUF=receiveData;		//发送缓冲寄存器,接受完以后TI硬件置1;   串口是可以同时收/发的,虽然都是用SBUF,但却是两个独立的寄存器,互不影响,只是都叫一个名,SBUF。
	while(!TI);			 	//TI=1时退出循环,代表单片机发送1个字符结束标志。
	TI=0;					//每发送1字节,TI需要软件置0
}									 

### 51单片机通信字符串发送乱码的解决方案 当遇到51单片机通信发送字符串时出现乱码的情况,可以从以下几个方面进行排查和解决: #### 1. 中断允许位设置 在某些情况下,即使波特率和其他硬件参数都已正确配置,仍然可能出现乱码现象。这可能是由于中断允许位未被正确设置所引起的。对于STC89C52单片机而言,在初始化过程中需确保全局中断使能以及串中断使能均已开启。具体操作如下所示[^1]: ```c EA = 1; // 开启总中断 ES = 1; // 开启串中断 ``` #### 2. 波特率校准 波特率不匹配是导致串通信乱码的一个常见原因。尽管已经确认波特率无误,仍建议重新计算并验证波特率分频器寄存器(`TH1` 和 `TL1` 的初始值)。例如,假设使用的是11.0592 MHz晶振,并希望实现9600 bps的波特率,则可以通过以下公式计算初值[^3]: \[ \text{Initial Value} = 2^{16} / (\text{Oscillator Frequency (Hz)} / 12 * \text{Baud Rate}) - 1 \] 对应代码片段可能如下: ```c TMOD = 0x20; // 设置定时器模式为方式2 TH1 = 0xFD; // 初始值设为FDH 对应于9600bps@11.0592MHz TR1 = 1; // 启动定时器T1 ``` #### 3. 晶振频率调整 如果使用的开发板上的实际晶振频率与程序设定不符,也可能引发数据传输错误。通常情况下,默认采用标准工业级晶体如11.0592 MHz 或者12 MHz。然而,部分自制电路可能会存在偏差较大的廉价晶体元件。此时可尝试修改源代码中的预定义宏或常量数值来适配实际情况。比如针对STM32系列微控制器项目中涉及的相关头文件路径下的固定值替换处理方法[^2]: #### 4. 上位机端配置一致性 最后还需注意上位机软件接收端是否按照预期设置了相同的通讯速率以及其他属性选项(奇偶校验、停止位长度等),否则即便发射方一切正常也会因为双方协议不同步而导致解析失败从而表现为字符错乱的现象。 综上所述,通过以上几个方面的细致检查应该能够有效定位并修复大部分由软硬件配合不当造成的51单片机传输出现乱码的问题。
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

内有小猪卖

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值