单片机实验(十二)RS232串口通信

80S52:RS232双工串口通信模块

功能:和PC机通信说骚话

模块介绍

串口通信主要四个要点

SBUF寄存

SBUF主要用来储存从PC接收的信息和准备向PC发送的信息,大小为8位

波特率匹配

要与PC通信必须遵守规则,也就是必须有相同的发送/接收频率(波特率)51单片机中使用T1定时/计数器来设置波特率定时器溢出一次代表传输一次数据

SCON串口控制寄存器(主要用方式1)

在这里插入图片描述

SM0、SM1:----确定工作方式
一般使用方式1,SM0=0,SM1=1;

SM2:----多机通信控制位(可以先不理)

多机通信是工作在方式2和方式3的,所以SM2主要用于方式2和方式3,多级通信时,SM2=1,当SM2=1时,只有当接收到的数据帧第9位(RB8)为1时,

单片机才把前八位数据放入自己的SBUF中,否则,将丢弃数据帧。当SM2=0时,不论RB8的值是什么,都会把串口收到的数据放到SBUF中。

REN:-----允许接收位

REN用于控制是否允许接收数据,REN=1时,允许接收数据,REN=0时,拒绝接收数据

TB8:-------是要发送的第9位数据位

在方式2和方式3中,TB8是要作为数据帧第9位被发送出去的,在多机通信中,可用于判断当前数据帧的数据是地址还是数据,TB8=0为数据,TB8=1为地址

RB8:-------接收到的第9位数据位

当单片机已经接收一帧数据帧时,会把数据帧中的第9位放到 RB8中。方式0不使用RB8,在方式2和方式3中,RB8为接收到的数据帧的第9位数据位。

TI:-----发送中断标志位

方式0中,不用管他。其他方式下,当发送数据完毕,硬件会将其置1,当 TI 被置1,会向CPU发送中断请求。我们记得要在中断服务程序中把 IT 置回0.

RI:-----接收中断标志位

当接受完一帧数据时,RI 由硬件置1,当RI 被置1,会向CPU请求中断。同样要在中断服务程序中把 RI 置回0。

PCON功率控制寄存器

在这里插入图片描述

这个寄存器只有一个位SMOD,在方式1,2.,3时,波特率都与SMOD有关,当SMOD=1时,波特率会增加一倍。复位时,SMOD变回0

部分介绍摘自:https://blog.csdn.net/u014453898/article/details/57123007

准备工作

设定两个寄存器,并打开波特率定时器

void InitUART(void)
{
    TMOD = 0x20;//设置T1为定时器
    SCON = 0x50;//工作方式1
    TH1 = 0xF3;
    TL1 = TH1;//定时与波特率匹配
    PCON = 0x00;//不加倍(~~反手一个超级加倍~~)
    EA = 1;
    ES = 1;//中断开开
    TR1 = 1;//计时
}

发送模块

每个字节发送完成后要将完成标识TI手动置0

void SendOneByte(unsigned char c)
{
    SBUF = c;//向SBUF中放入数据
    while(!TI);//等待发送结束标识
    TI = 0;
}

接收模块

利用串口中断来执行读入操作,和发送类似接收完成标识RI也需要置0

void UARTInterrupt(void) interrupt 4
{
	ES=0;//防止打扰
    if(RI)
    {
        RI = 0;
        res=SBUF
    }
    ES=1;
}

附上沙雕程序一枚

我是复读机。。。233333
波特率2400

#include <reg51.h>
typedef unsigned char u8;
typedef unsigned int u16;
u8 res ,b,num;
u8 save[10];
void InitUART(void)
{
    TMOD = 0x20;
    SCON = 0x50;
    TH1 = 0xF3;
    TL1 = TH1;
    PCON = 0x00;
    EA = 1;
    ES = 1;
    TR1 = 1;
}

void SendOneByte(unsigned char c)
{
    SBUF = c;
    while(!TI);
    TI = 0;
}

void SendString(u8*t){
  while(*t!='\0')
		SendOneByte(*t++);
}
void main(void)
{
    InitUART();
	  SendString("Hello I am a repeater!");
	  while(1){
		  if(b){
				SendString(save);
				b=0;
			}
		}
}

void UARTInterrupt(void) interrupt 4
{
	  ES=0;
    if(RI)
    {
        RI = 0;
        res=SBUF;
			  if(res!='#')
			    save[num++]=res;
				else
				{
				  b=1;
					num=0;
				}
    }
		ES=1;
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

发布了9 篇原创文章 · 获赞 7 · 访问量 1591

猜你喜欢

转载自blog.csdn.net/SuperRabbit007/article/details/104374780