欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程资源 > 编程问答 >内容正文

编程问答

STC89C52单片机 串口通信

发布时间:2025/5/22 编程问答 43 豆豆
生活随笔 收集整理的这篇文章主要介绍了 STC89C52单片机 串口通信 小编觉得挺不错的,现在分享给大家,帮大家做个参考.
串口初始化
void UARTInit() {EA = 1; //打开总中断ES = 1; //打开串口中断SM0 = 0; SM1 = 1;//串口工作方式1,8位UART波特率可变REN = 1;//串口允许接收TR1 = 1;//启动定时器1TMOD |= 0x20;//定时器1,工作模式2 8位自动重装TH1 = 0xfd; // 根据下面的公式计算得到TL1 = 0xfd; //设置比特率9600 }


例如:计算9600的波特率

SMOD在没有设置的情况下,默认为0.
SMOD = 0
所以2的0次方为1
2^0 = 1

晶震频率计算:fosc = 11.0592 兆赫兹 = 11.0592 x 1000000 = 11059200赫兹

11059200 ÷ 9600 = 1152 得到波特率公式的被除数

根据公式
1152 ÷ 32 = 36

36 ÷ 12 = 3

256 - T初 = 256 - 3 = 253

将 253 转换为16进制得到 0xFD

TH1 = 0xFD;
TL1 = 0xFD; 设置波特率9600

串口中断
void UART() interrupt 4 {if(RI)//判断接收是否完成{num = SBUF;//读SBUF,读出串口接收到的数据RI = 0;//软件清零接收标志位 }if(TI)//判断是否发送完成TI = 0;//清零发送完成标志位 }

串口工作方式1,8位UART比特率9600

#include <reg52.h> #include <intrins.h>#define uint unsigned int #define uchar unsigned charsbit DU = P2^6;//数码管段选 sbit WE = P2^7;//数码管段选 uchar num;//数码管显示的值//共阴数码管段选表0-9 uchar code SMGduan[]= {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F,}; //数码管位选码 uchar code SMGwei[] = {0xfe, 0xfd, 0xfb};/*==================================== 函数 :display(uchar i) 参数 :i 显示数值,取值范围0-255 返回值 :无 描述 :三位共阴数码管动态显示 ====================================*/ void display(uchar i) {static uchar wei; P0 = 0XFF;//清除断码WE = 1;//打开位选锁存器P0 = SMGwei[wei];WE = 0;//锁存位选数据switch(wei){case 0: DU = 1; P0 = SMGduan[i / 100]; DU = 0; break;case 1: DU = 1; P0 = SMGduan[i % 100 / 10]; DU = 0; break; case 2: DU = 1; P0 = SMGduan[i % 10]; DU = 0; break; }wei++;if(wei == 3)wei = 0; } //定时器0初始化 void timer0Init() {EA = 1; //打开总中断ET0 = 1;//打开定时器0中断TR0 = 1; //启动定时器0REN = 1;//允许串口接收TMOD |= 0X01; //定时器工作模式1,16位定时模式TH0 = 0xED;TL0 = 0xFF; //定时5ms } //串口初始化 void UARTInit() {EA = 1; //打开总中断ES = 1; //打开串口中断SM0 = 0; SM1 = 1;//串口工作方式1,8位UART波特率可变REN = 1;//串口允许接收TR1 = 1;//启动定时器1TMOD |= 0x20;//定时器1,工作模式2 8位自动重装TH1 = 0xfd;TL1 = 0xfd;//设置比特率9600 } void main()//main函数自身会循环 { timer0Init();//定时器0初始化UARTInit();//串口初始化while(1); } //定时器0中断函数 void timer0() interrupt 1 {TH0 = 0xED;TL0 = 0xFF; //定时5msdisplay(num); //数码管显示函数 } //串口中断函数 void UART() interrupt 4 {if(RI)//判断接收是否完成{num = SBUF;//读SBUF,读出串口接收到的数据RI = 0;//软件清零接收标志位 }if(TI)//判断是否发送完成TI = 0;//清零发送完成标志位 }

通过串口发送数据前需要进行的设置
在右边的菜单栏找到串口助手然后

  • 第一步让COM号保持一致
  • 第二步波特率设置为9600
  • 第三步打开串口
  • 第四步发送和接收格式选择HEX格式

修改串口中断中的函数,实现接收缓冲区数据
//串口中断函数 void UART() interrupt 4 {uchar temp;if(RI)//判断接收是否完成{num = SBUF;//读SBUF,读出串口接收到的数据RI = 0;//软件清零接收标志位 temp = num;//SBUF = temp;//写SBUF,把要发送的数据送给发送缓存器}if(TI)//判断是否发送完成TI = 0;//清零发送完成标志位 }

对代码修改后可以通过

串口助手选择文本模式接收和发送数据


ASCII码规定了不同字符是用哪个整数去表示,所以其它字母或数字对应的值可以通过ASCII表查看。


通过串口发送字符串

puts()函数和printf()函数
void main() {UARTInit(); //串口初始化while(1){TI = 1;puts("Hello Wolrd!"); // 使用puts函数while(!TI);TI = 0;delay(1000);} } void main() {UARTInit(); //串口初始化while(1){TI = 1;printf("Hello Wolrd!"); // 使用printf函数while(!TI);TI = 0;delay(1000);} }

注:puts()函数和printf()函数区别是

  • puts函数会执行换行操作
  • printf函数不会执行换行操作

打开串口助手选择对应COM号,设置波特率9600接收格式选择【文本格式】。

#include <reg52.h> #include <stdio.h> // 打印字符串需要调用 stdio.h 库#define uint unsigned int #define uchar unsigned char//毫秒级延时函数定义 void delay(uint z) {uint x,y;for(x = z; x > 0; x--)for(y = 114; y > 0 ; y--); } //串口初始化 void UARTInit() {SM0 = 0; SM1 = 1;//串口工作方式1,8位UART波特率可变TR1 = 1;//启动定时器1TMOD |= 0x20;//定时器1,工作模式2 8位自动重装TH1 = 0xfd;TL1 = 0xfd;//设置比特率9600 }void main() {UARTInit(); //串口初始化while(1){TI = 1;puts("Hello Wolrd!"); // 每次打印都会换行 支持中文打印 while(!TI);TI = 0;delay(1000);} }

注:

  • 使用printf()函数或puts()函数需要引入头文件#include <stdio.h>
  • 使用printf()函数或puts()函数前都应软件置位TI = 1;
    如果没有软件置位TI = 1,则会一直处于等待状态,while(!TI)一直在循环中。

总结

以上是生活随笔为你收集整理的STC89C52单片机 串口通信的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。