51单片机字符串口通信为什么乱码?终于找到原因了
2022-05-25 来源:eefocus
被这个问题卡了3天,代码很简单就是乱码出问题,烦恼!
后来查资料找到原因,晶振12MHz和11.0592Hz的问题。
如果你用的是12Mhz的单片机,定时器初值TH1一般要设置到E6(2400bps)、F3(4800bps)。
对应的在上位机配置UART串口时,选取2400 4800bps。如果试了不行,那就换更低的1200bps。
修改前
修改后
做了半天才发现我的晶振是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
}