STC89C52单片机 串口通信
生活随笔
收集整理的这篇文章主要介绍了
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单片机 串口通信的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇: C++ 指向常量的指针与指针类型的常量
- 下一篇: STC89C52单片机 LCD1602液