51单片机—串口通信

计算机串行通信:
在这里插入图片描述
并行通信:
在这里插入图片描述
串行通信:
在这里插入图片描述
异步通信:
在这里插入图片描述在这里插入图片描述
同步通信:
在这里插入图片描述
串行通信的传输方向:
在这里插入图片描述
串行通信常见的错误校验:
在这里插入图片描述
传输速率比特率(波特率):
在这里插入图片描述在这里插入图片描述(fosc是晶振频率,要将Mhz转化为hz(乘10的6次方),若不设置SMOD则默认是0,有想设置的波特率就可以求出T初了,将它赋给TH和TL就行了)

串行通信接口标准:
在这里插入图片描述在这里插入图片描述在这里插入图片描述
传输距离与传输速率的关系:
在这里插入图片描述
采用RS-232C接口存在的问题:在这里插入图片描述
串行接口的结构:
在这里插入图片描述在这里插入图片描述
使用串口前的准备工作:
在这里插入图片描述
与串行通信相关的寄存器:
在这里插入图片描述可可违法及在这里插入图片描述
可位寻址的意思是可以写为像以下这样的形式:

 SM0=0;  SM1=1;//串口工作方式1,8位UART波特率可变
 REN=1;//串口允许接收

定时计数器控制寄存器TCON:
在这里插入图片描述在这里插入图片描述
单片机同优先级中内部查询顺序:
在这里插入图片描述
串口通信示例(通过定时中断刷新数码管显示PC端发送的数据):

#include <reg52.h>
#include <intrins.h>

#define uint unsigned int
#define uchar unsigned char

sbit DU = P2^6;//数码管段选
sbit WE = P2^7;//数码管位选
sbit key_s2 = P3^0;//独立按键S2
sbit key_s3 = P3^1;//独立按键S3
uchar num;//数码管显示的值

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

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;	 //启动定时器0
	TMOD |= 0X01; //定时器工作模式,16位定时模式
	TH0 = 0xED;
	TL0 = 0xFF; //定时5ms
}
//串口初始化
void UARTInit()
{
   EA=1;//打开总中断
   ES=1;//打开串口中断
   SM0=0;  SM1=1;//串口工作方式1,8位UART波特率可变
   REN=1;//串口允许接收
   TR1=1;//启动定时器一(用来串口通信设置波特率)
   TMOD |=0x20;// 定时器1,工作模式2 8位自动重装
   TH1=0xfd;
   TL1=0xfd;//设置波特率9600
}

void main()//main函数自身会循环
{	
	timer0Init();//定时器0初始化
	UARTInit();//串口初始化
	while(1);
} 

//定时器中断函数,达到时间后进入中断函数
void timer0() interrupt 1
{
	TH0 = 0xED;
	TL0 = 0xFF; //定时5ms
	display(num); //数码管显示函数	
} 
//串口中断函数
void UART() interrupt 4
{
	uchar temp;
	if(RI)//判断接收数否完成
	{
		num=SBUF;//读SBUF,读串口接收到的数据
		RI=0;//软件清0接收标志位
		temp=num;
		SBUF=++temp;//写SBUF,把要发送的数据发送给缓存器
	}
	if(TI)//判断是否发送完成
		TI=0;//清0发送完成标志位
} 

当单片机接收到一帧数据后,RI会置1,向CPU申请中断,若之前有中断允许,则产生了中断,进入中断服务程序。当然,单片机发送完一帧数据,TI也会置1,同样会产生中断!

补充:其实,不管你有没有允许中断,上位机(此时即给单片机发送信息的机器)只要给单片机发送数据,单片机就会自动接收数据,并把它放在数据缓冲器SBUF中,如果你之前有允许串行口中断,RI就会置1,向单片机CPU申请中断,并进入中断服务程序,即你问题中的serial()函数,做完这个函数后就会自动返回断点。如果你没有允许中断,便不会产生串行中断。

  • 1
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值