资讯动态

51单片机电子秤系列UART

发布时间:2026/10/15 3:58:48 来源:尧图企业网站定制
#includeREGX52.HvoidURAT_Init(baud){PCON0x7F;//波特率不倍速SCON0x50;//8位数据,可变波特率TMOD0x0F;//清除定时器1模式位TMOD|0x20;//设定定时器1为8位自动重装方式TL10xFD;//设定定时初值TH10xFD;//设定定时器重装值ET10;//禁止定时器1中断TR11;//启动定时器1ES1;}//串口发送1个字节voidUART_SendByte(unsignedcharByte)//发送字节{SBUFByte;//发送字节while(TI0);//如果TI1就让它变回0发送后电脑自动TI1会向主机请求中断手动软件关闭中断复位TI0;//发送中断请求关闭}voidSend_Word(unsignedchar*p)//发送字符串{while(*p){SBUF*(p);while(TI0){;;;};TI0;}}//void UART_Init()//串口发送T1定时器//{ // 0 1 0 0 0 0 0 0// SCON0x40; //0100 0000串口工作模式1T1与SMOD决定SMOD SM0/FE SM1 SM2 REN TB8 RB8 TI RI 不接收发送// PCON | 0x80; //使能波特率倍速位SMOD//最高位置1//4800波速率// //串口// TMOD 0x0F; //清除定时器1模式位//定时器T1设置//高位置0//8位自动重组初始化// TMOD | 0x20; //设定定时器1为8位自动重装方式//开始设置// TL1 0xF4; //设定定时初值//范围// TH1 0xF4; //设定定时器重装值// ET1 0; //禁止定时器1中断分开关静止中断// TR1 1; //启动定时器1//}//TH1256-11059200/32/12/9600//void URAT_Init(baud)//{// PCON 0x7F; //波特率不倍速// SCON 0x50; //8位数据,可变波特率// TMOD 0x0F; //清除定时器1模式位// TMOD | 0x20; //设定定时器1为8位自动重装方式// TL1 0xFD; //设定定时初值// TH1 0xFD; //设定定时器重装值// ET1 0; //禁止定时器1中断// TR1 1; //启动定时器1// ES1;//}////串口发送1个字节//void senddata(char dat)//{// SBUF dat;// while(TI0);// TI 0;//}//void sendstring(unsigned char *str)//{// while(*str!\0)// {// senddata(*str);// }//}//char putchar(char c)// {// //输出重定向到串口// senddata(c);// return c;//返回给函数调用者printf//}//void UART_SendByte(unsigned char Byte)//发送字节//{// SBUFByte;//发送字节// while (TI0);//如果TI1就让它变回0发送后电脑自动TI1会向主机请求中断手动软件关闭中断复位// TI0;//发送中断请求关闭//}//void UART_Init()//串口发送T1定时器//{ // 0 1 0 1 0 0 0 0// SCON0x50; //0100 0000串口工作模式1T1与SMOD决定SMOD SM0/FE SM1 SM2 REN TB8 RB8 TI RI REN1允许接收// PCON | 0x80; //使能波特率倍速位SMOD//最高位置1//4800波速率 //sm1 sm2决定工作模式// //串口// TMOD 0x0F; //清除定时器1模式位//定时器T1设置// TMOD | 0x20; //设定定时器1为8位自动重装方式// TL1 0xF4; //设定定时初值//范围// TH1 0xF4; //设定定时器重装值// ET1 0; //禁止定时器1中断分开关静止中断// TR1 1; //启动定时器1// EA1;//总开关启动中断// ES1 ; //启动串口中断//}/************************* 串口中断函数模版 ***************************///void UART_Routine() interrupt 4//串口中断//{// //P10x00;//要在缓冲区发送f0发送数据进入中断// if(RI1)//接收中断请求标志RI会自动置1请求中断然后需软件复位// {// RI0;// }/*********************** ***********************///串口初始化//void UART_Init(unsigned int BAUD)//BAUD是波特率//{ //0 0 1 0 0 0 0 0// TMOD(TMOD0x0f)|0x20;//TMOD定时器/计数器模式控制寄存器 GATE c/t m1 m0 GATE c/t m1 m0 低位T0计数器设置高位T1计数器设置 //看定时器图具体// //GATE门控位GATE0时TCON中的TRO或TR1为1启动定时器/计数器工作// // GATE1时,使TCON中的TRO或TR1为1且需要外部引脚也为高电平才能工作// //C/T定时/计数模式切换C/T0时为定时模式C/T1时为计数模式// //M1M0用来选择定时计/计数器的工作方式一般使用都是采用16位的计时计数器// //有4种模式00//13位计时器 01//16位计时器 10//8位重组计时器 自动重新载入计数值 11//两组独立计时器T1 T0不能同时用// //模式0-3 8192 65536 256 256// //波特率9600晶振11.0592 SMOD0// TH1256-11059200/32/12/BAUD//2530xfd范围高值// TL1TH1;// TR11;//定时器1开始计时// ET10;//定时器只做波特率发生器不中断// SCON0x50;//模式1 01010000 可变波特率 REN1允许中断 串口模式// ES1;//串口中断打开// PS0;//设串口为低级中断//}////PCON功率控制寄存器 SMOD SMOD0 ... SMOD0 /32 不加倍 SMOD1 /16 加倍// // 1 0 000//void main()//{// UART_Init(9600);//初始化串口// EA1;//打开总开关// while(1);//}////发送函数//void SendData(unsigned char dat)//{// SBUFdat;//写数据到UART数据寄存器// while(TI0);//等待前面数据发送完成TI自动1发生中断// TI0;//手动关闭中断//}//文本模式ASCALL码值对应发送HEX 16进制////UART中断服务程序// void Uart() interrupt 4// {// if(RI)// {// RI0;// tempSBUF;// SBUFtemp;// }// }//void helloword()//{// senddata(L);// senddata(a);// senddata(s);// senddata(l);// senddata(o);// senddata(w);// senddata(o);// senddata(r);// senddata(d);//}#ifndef__UART_H__#define__UART_H__voidURAT_Init(baud);voidUART_SendByte(unsignedcharByte);voidSend_Word(unsignedchar*p);//void UART_Init();//void UART_SendByte(unsigned char Byte);//void URAT_Init(baud);//void senddata(char dat);#endif3. 代码讲解下面逐函数讲解这段 UART 串口通信代码的实现原理。3.1 串口初始化函数URAT_InitvoidURAT_Init(baud){PCON0x7F;//波特率不倍速SCON0x50;//8位数据,可变波特率TMOD0x0F;//清除定时器1模式位TMOD|0x20;//设定定时器1为8位自动重装方式TL10xFD;//设定定时初值TH10xFD;//设定定时器重装值ET10;//禁止定时器1中断TR11;//启动定时器1ES1;}这个函数完成串口通信的初始化配置逐行分析如下代码作用说明PCON 0x7F波特率不倍速将 SMOD 位清零波特率按 1/32 分频SCON 0x50配置串口模式8 位数据、可变波特率、允许接收REN1TMOD 0x0F清除定时器 1 模式位只保留定时器 0 的配置TMOD | 0x20定时器 1 设为 8 位自动重装模式 2自动重载计数值TL1 0xFD设定定时初值低 8 位初值 253TH1 0xFD设定重装值溢出后自动重装 253ET1 0禁止定时器 1 中断定时器 1 只作波特率发生器TR1 1启动定时器 1开始计数ES 1使能串口中断允许串口产生中断关键点TH1 0xFD对应波特率 9600。初值计算公式为TH1 256 - 晶振频率 / (32 × 12 × 波特率) 256 - 11059200 / (32 × 12 × 9600) 256 - 3 253 0xFD3.2 发送单字节函数UART_SendBytevoidUART_SendByte(unsignedcharByte)//发送字节{SBUFByte;//发送字节while(TI0);//如果TI1就让它变回0发送后电脑自动TI1会向主机请求中断手动软件关闭中断复位TI0;//发送中断请求关闭}代码作用SBUF Byte把要发送的数据写入串口发送缓冲区硬件自动开始发送while (TI 0)等待发送完成。TI 是发送中断标志发送完成后硬件自动置 1TI 0软件清除发送中断标志为下一次发送做准备执行流程否继续等待是发送完成调用 UART_SendByte(Byte)SBUF Byte 写入缓冲区TI 1 ?TI 0 清除标志函数返回3.3 发送字符串函数Send_WordvoidSend_Word(unsignedchar*p)//发送字符串{while(*p){SBUF*(p);while(TI0){;;;};TI0;}}代码作用while (*p)遍历字符串直到遇到字符串结束符\0值为 0SBUF *(p)取出当前字符写入缓冲区指针后移指向下一个字符while (TI 0)等待当前字符发送完成TI 0清除发送标志继续发送下一个字符执行流程是否等待是否字符串结束调用 Send_Word(p)*p ! \\0 ?SBUF *ppTI 1 ?TI 0函数返回3.4 头文件uart.h#ifndef__UART_H__#define__UART_H__voidURAT_Init(baud);voidUART_SendByte(unsignedcharByte);voidSend_Word(unsignedchar*p);#endif头文件使用#ifndef防止重复包含声明了三个对外接口函数供主程序调用。4. 波特率计算详解4.1 计算公式波特率计算公式如下波特率 晶振频率 / (32 × 12 × (256 - TH1))其中晶振频率51 单片机常用 11.0592MHz32SMOD0 时的分频系数SMOD1 时为 1612机器周期 12 个时钟周期256 - TH1定时器1的重装计数值4.2 常见波特率对照表目标波特率晶振频率SMODTH1 初值实际波特率误差960011.0592MHz00xFD (253)96000%480011.0592MHz00xFA (250)48000%1920011.0592MHz00xFD (253)192000%240011.0592MHz00xF4 (244)24000%为什么选择 11.0592MHz 晶振因为 11059200 可以被 9600、4800、19200 等常用波特率整除误差为 0%保证通信稳定。5. 寄存器配置详解5.1 SCON 寄存器串口控制寄存器位名称值说明7SM00与 SM1 组合选择工作模式6SM11SM00, SM11 → 模式18位UART可变波特率5SM20多机通信控制位单机通信置04REN1允许接收3TB80发送第9位数据模式2/3用2RB80接收第9位数据1TI0发送中断标志0RI0接收中断标志5.2 TMOD 寄存器定时器模式寄存器位名称值说明7GATE0门控位0仅TR1控制启停6C/T0定时模式5-4M1M010模式28位自动重装3GATE0定时器0门控2C/T0定时模式1-0M1M000定时器0模式06. 案例串口控制 LED// 通过串口接收指令控制 LEDvoidUART_Interrupt()interrupt4{unsignedcharcmd;if(RI)// 收到数据{RI0;// 清除接收标志cmdSBUF;// 读取数据if(cmd1)P10x00;// 点亮所有 LEDelseif(cmd0)P10xFF;// 熄灭所有 LED}}代码作用interrupt 4声明这是串口中断服务函数中断号 4if (RI)判断是否收到数据RI 为接收中断标志RI 0清除接收标志cmd SBUF读取接收缓冲区中的数据P1 0x00收到字符 ‘1’ 时点亮 LED低电平点亮P1 0xFF收到字符 ‘0’ 时熄灭 LED7. 调试建议7.1 调试工具配置工具配置项推荐值串口调试助手波特率9600与代码一致数据位88停止位11校验位None无7.2 常见问题排查现象可能原因解决方法乱码波特率不匹配检查晶振频率和 TH1 初值计算无数据未打开总中断确认EA1已执行发送卡死TI 标志未清除确认发送循环中TI0接收不到REN 未置1确认SCON0x50中 REN18. 总结本文逐函数讲解了 51 单片机 UART 串口通信的代码实现包括初始化配置、单字节发送、字符串发送和中断接收。核心要点初始化通过 SCON、TMOD、TH1/TL1 配置串口模式和波特率发送写入 SBUF 后轮询 TI 标志确认发送完成接收通过中断服务函数读取 SBUF 数据波特率由晶振频率和定时器初值共同决定11.0592MHz 晶振可精确匹配常用波特率4. 寄存器配置详解4.1 SCON 寄存器串口控制寄存器位名称值说明7SM00与 SM1 组合选择工作模式6SM11SM00, SM11 → 模式18位UART可变波特率5SM20多机通信控制位单机通信置04REN1允许接收3TB80发送第9位数据模式2/3用2RB80接收第9位数据1TI0发送中断标志0RI0接收中断标志4.2 TMOD 寄存器定时器模式寄存器位名称值说明7GATE0门控位0仅TR1控制启停6C/T0定时模式5-4M1M010模式28位自动重装3GATE0定时器0门控2C/T0定时模式1-0M1M000定时器0模式05. 案例补充建议5.1 案例一串口控制 LED// 通过串口接收指令控制 LEDvoidUART_Interrupt()interrupt4{unsignedcharcmd;if(RI)// 收到数据{RI0;// 清除接收标志cmdSBUF;// 读取数据if(cmd1)P10x00;// 点亮所有 LEDelseif(cmd0)P10xFF;// 熄灭所有 LED}}5.2 案例二串口发送传感器数据// 定时采集温度并发送voidmain(){unsignedinttemp;UART_Init(9600);EA1;while(1){tempRead_Temperature();// 读取温度传感器UART_SendString(Temp: );UART_SendByte(temp/100);// 发送十位UART_SendByte(temp%100);// 发送个位UART_SendString( C\r\n);Delay(1000);// 延时1秒}}6. 调试建议6.1 调试工具配置工具配置项推荐值串口调试助手波特率9600与代码一致数据位88停止位11校验位None无6.2 常见问题排查现象可能原因解决方法乱码波特率不匹配检查晶振频率和 TH1 初值计算无数据未打开总中断确认EA1已执行发送卡死TI 标志未清除确认发送循环中TI0接收不到REN 未置1确认SCON0x50中 REN17. 总结本文通过系统讲解 UART 串口通信的寄存器配置、波特率计算和代码实现帮助读者掌握 51 单片机串口通信的核心要点。建议读者动手实践在开发板上运行改进后的代码观察串口输出逐步调试使用串口调试助手验证波特率配置扩展学习尝试中断接收、多机通信、与 PC 上位机交互等进阶功能

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑