0
点赞
收藏
分享

微信扫一扫

STC89C52单片机 串口通信

串口初始化

void UARTInit()
{
EA = 1; //打开总中断
ES = 1; //打开串口中断
SM0 = 0; SM1 = 1;//串口工作方式1,8位UART波特率可变
REN = 1;//串口允许接收
TR1 = 1;//启动定时器1
TMOD |= 0x20;//定时器1,工作模式2 8位自动重装
TH1 = 0xfd;   // 根据下面的公式计算得到
TL1 = 0xfd; //设置比特率9600
}

STC89C52单片机 串口通信_数码管
例如:计算9600的波特率

SMOD在没有设置的情况下,默认为0.
SMOD = 0
所以2的0次方为1
2^0 = 1
STC89C52单片机 串口通信_数码管_02

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

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

根据公式
1152 ÷ 32 = 36

36 ÷ 12 = 3

256 - T初 = 256 - 3 = 253

STC89C52单片机 串口通信_串口_03

将 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 char

sbit&nbsp;DU&nbsp;=&nbsp;P2^6;//数码管段选
sbit&nbsp;WE&nbsp;=&nbsp;P2^7;//数码管段选
uchar&nbsp;num;//数码管显示的值

//共阴数码管段选表0-9
uchar&nbsp;code&nbsp;SMGduan[]=&nbsp;{0x3F,&nbsp;0x06,&nbsp;0x5B,&nbsp;0x4F,&nbsp;0x66,&nbsp;0x6D,&nbsp;0x7D,&nbsp;0x07,&nbsp;0x7F,&nbsp;0x6F,};
//数码管位选码
uchar&nbsp;code&nbsp;SMGwei[]&nbsp;=&nbsp;{0xfe,&nbsp;0xfd,&nbsp;0xfb};

/*====================================
函数 :display(uchar i)
参数 :i 显示数值,取值范围0-255
返回值 :无
描述 :三位共阴数码管动态显示
====================================*/
void&nbsp;display(uchar&nbsp;i)
{
static&nbsp;uchar&nbsp;wei;&nbsp;
P0&nbsp;=&nbsp;0XFF;//清除断码
WE&nbsp;=&nbsp;1;//打开位选锁存器
P0&nbsp;=&nbsp;SMGwei[wei];
WE&nbsp;=&nbsp;0;//锁存位选数据
switch(wei)
{
case&nbsp;0:&nbsp;DU&nbsp;=&nbsp;1;&nbsp;P0&nbsp;=&nbsp;SMGduan[i&nbsp;/&nbsp;100];&nbsp;DU&nbsp;=&nbsp;0;&nbsp;break;
case&nbsp;1:&nbsp;DU&nbsp;=&nbsp;1;&nbsp;P0&nbsp;=&nbsp;SMGduan[i&nbsp;%&nbsp;100&nbsp;/&nbsp;10];&nbsp;DU&nbsp;=&nbsp;0;&nbsp;break;
case&nbsp;2:&nbsp;DU&nbsp;=&nbsp;1;&nbsp;P0&nbsp;=&nbsp;SMGduan[i&nbsp;%&nbsp;10];&nbsp;DU&nbsp;=&nbsp;0;&nbsp;break;
}
wei++;
if(wei&nbsp;==&nbsp;3)
wei&nbsp;=&nbsp;0;
}
//定时器0初始化
void&nbsp;timer0Init()
{
EA&nbsp;=&nbsp;1; //打开总中断
ET0&nbsp;=&nbsp;1;//打开定时器0中断
TR0&nbsp;=&nbsp;1; &nbsp;//启动定时器0
REN&nbsp;=&nbsp;1;//允许串口接收
TMOD&nbsp;|=&nbsp;0X01;&nbsp;//定时器工作模式1,16位定时模式
TH0&nbsp;=&nbsp;0xED;
TL0&nbsp;=&nbsp;0xFF;&nbsp;//定时5ms
}
//串口初始化
void&nbsp;UARTInit()
{
EA&nbsp;=&nbsp;1; //打开总中断
ES&nbsp;=&nbsp;1;&nbsp;//打开串口中断
SM0&nbsp;=&nbsp;0; SM1&nbsp;=&nbsp;1;//串口工作方式1,8位UART波特率可变
REN&nbsp;=&nbsp;1;//串口允许接收
TR1&nbsp;=&nbsp;1;//启动定时器1
TMOD&nbsp;|=&nbsp;0x20;//定时器1,工作模式2 8位自动重装
TH1&nbsp;=&nbsp;0xfd;
TL1&nbsp;=&nbsp;0xfd;//设置比特率9600
}
void&nbsp;main()//main函数自身会循环
{
timer0Init();//定时器0初始化
UARTInit();//串口初始化
while(1);
}&nbsp;

//定时器0中断函数
void&nbsp;timer0()&nbsp;interrupt&nbsp;1
{
TH0&nbsp;=&nbsp;0xED;
TL0&nbsp;=&nbsp;0xFF;&nbsp;//定时5ms
display(num);&nbsp;//数码管显示函数
}
//串口中断函数
void&nbsp;UART()&nbsp;interrupt&nbsp;4&nbsp;{
if(RI)//判断接收是否完成
{
num&nbsp;=&nbsp;SBUF;//读SBUF,读出串口接收到的数据
RI&nbsp;=&nbsp;0;//软件清零接收标志位
}
if(TI)//判断是否发送完成
TI&nbsp;=&nbsp;0;//清零发送完成标志位
}

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

  • 第一步让COM号保持一致
  • 第二步波特率设置为9600
  • 第三步打开串口
  • 第四步发送和接收格式选择HEX格式
    STC89C52单片机 串口通信_数码管_04

STC89C52单片机 串口通信_数码管_05

修改串口中断中的函数,实现接收缓冲区数据

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

对代码修改后可以通过
STC89C52单片机 串口通信_初始化_06

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

STC89C52单片机 串口通信_初始化_07
ASCII码规定了不同字符是用哪个整数去表示,所以其它字母或数字对应的值可以通过ASCII表查看。

通过串口发送字符串

puts()函数和printf()函数

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

void&nbsp;main()
{
UARTInit();&nbsp;//串口初始化
while(1)
{
TI&nbsp;=&nbsp;1;
printf(&quot;Hello&nbsp;Wolrd!&quot;);&nbsp;&nbsp;&nbsp;// 使用printf函数
while(!TI);
TI&nbsp;=&nbsp;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&nbsp;delay(uint&nbsp;z)
{
uint&nbsp;x,y;
for(x&nbsp;=&nbsp;z;&nbsp;x&nbsp;&gt;&nbsp;0;&nbsp;x--)
for(y&nbsp;=&nbsp;114;&nbsp;y&nbsp;&gt;&nbsp;0&nbsp;;&nbsp;y--);&nbsp;
}&nbsp;

//串口初始化
void&nbsp;UARTInit()
{
SM0&nbsp;=&nbsp;0; SM1&nbsp;=&nbsp;1;//串口工作方式1,8位UART波特率可变
TR1&nbsp;=&nbsp;1;//启动定时器1
TMOD&nbsp;|=&nbsp;0x20;//定时器1,工作模式2 8位自动重装
TH1&nbsp;=&nbsp;0xfd;
TL1&nbsp;=&nbsp;0xfd;//设置比特率9600
}

void&nbsp;main()
{
UARTInit();&nbsp;//串口初始化
while(1)
{
TI&nbsp;=&nbsp;1;
puts(&quot;Hello&nbsp;Wolrd!&quot;);&nbsp;&nbsp;&nbsp;// 每次打印都会换行   支持中文打印 
while(!TI);
TI&nbsp;=&nbsp;0;
delay(1000);
}
}

STC89C52单片机 串口通信_数码管_08

注:

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

举报

相关推荐

0 条评论