51触摸屏单片机串口通讯讯时开了串口中断不用清除中断标志也没事吗?

查看: 8189|回复: 0
基于51的串行通讯原理及协议详解(uart)
串行与并行通讯方式
并行:控制简单,传输速度快。线多,长距离成本较高且同时接受困难。
串行:将数据字节分成一位一位的行驶在一条传输线上进行传输。如图:
同步与异步串行通讯方式
同步串行通讯方式:同步通讯需要建立发送方对接收方时钟的直接控制,是双方达到完全同步。
异步串行通讯方式:通讯的发送和接收设备使用各自的时钟控制数据的发送和接收,为使双方收发协调,要求发送和接收的时钟尽可能一致。如图:
异步通讯方式的特点:
异步通讯以字符构成的帧为单位进行传输,字符与字符之间的间隙是任意的,但每个字符中的各位是以固定的时间传送的。其一帧字符信息由4部分组成:起始位、数据位、奇偶检验位、停止位。在单片机中的通讯一般情况下均使用这种帧格式。如图:
串行通讯的制式
单工:数据传输仅沿一个方向,不能实现反向传输
半双工:数据可以沿两个方向传输,但是需要分时
全双工:数据可以同时进行双向传输
串行通讯三种错误校验:奇偶校验、代码和校验、循环冗余校验
RS232电平与TTL电平的转换
PC使用的串口的电平为RS232的九针串口,MCU使用的电平是TTL电平,要使得PC
和MCU进行通讯,就需要对其电平极性转换。主要的几款电平转换芯片:MAX232、MAX202、HIN232,SIPEX320等
串行通讯速度的定义_波特率
串行通讯的速率用波特率表示,其定义为:
&&&&&&&&&&&&&&&&&&
每秒钟传送二进制代码的位数,即1波特=1位/秒,单位bps(位/秒)
eg:每秒钟传送240个字符,而每个字符格式包含10位(1起始、8数据、1停止),此时的波特率为:
&&&&&&&&&&&&&&&&&&
10位*240个/秒=2400bps
串行通讯波特率的计算
单片机的串行口可设定为四种工作方式,其中方式0和方式2波特率固定,方式1和方式3波特率可变,由定时器T1的溢出率来决定。计算公式如下:
其中:fosc为系统晶振频率,通常为12MHz(或者11.0592MHz),SMOD为PCON寄存器的最高位。T1的溢出率即定时器T1溢出的频率。
电源管理寄存器_PCON
SMOD;该位与串通信波特率有关。
SMOD=0;串口方式1、2、3时,波特率正常
SMOD=1;串口方式1、2、3时,波特率加倍
SMOD0,LVDF,P0F,此三位为STC_MCU 所特有的,可查看相关手册。
GF1、GF0;两个通用标志位,可随意使用。
PD;掉电模式设定位,
PD=0;MCU正常工作
PD=1;MCU进入掉电模式
IDL;空闲模式设定位
IDL=0;MCU正常工作
IDL=1;单片机进入空闲模式
单片机的两种模式状态:
掉电模式:进入掉电模式后,晶振停震,CPU,定时器,串行口全部停止工作,只有外部中断继续工作,
可有外部中断低电平触发或下降沿触发或硬件复位模式唤醒。
空闲模式:除CPU不够工作外,其余仍继续工作,在空闲模式下,可由任一个中断或者硬件复位唤醒
T1的溢出率
T1的溢出率就是T1定时器溢出的频率,只要算出T1定时器每一处一次所需的时间T,那么T的倒数即为他的溢出率。
51串行口结构
51单片机串行口是一个可编程全双工的通信接口,具有Uart(通用异步收发器)的全部功能,能同时进行数据的发送与接收,也可作为同步一位寄存器使用。
51_MCU主要由两个独立的串行数据缓冲寄存器SBUF
(一个发送,一个接收)和发送控制器、接收控制器,输入移位寄存器及若干控制门电路。如图:
串行口控制寄存器_SCON
SM0,SM1;工作方式选择位,串口有四中工作方式,如下:
SM2;多机通信可控制位,SM2主要用于方式2和方式3,当接收机的SM2=1时,可以利用收的RB8来控制是否激活RI;
RB8=0,不激活RI,收到的信息丢弃
RB8=1,收到的数据进入SBUF,并激活RI,进而在中断服务中将数据从SBUF读走,
当SM2=0时,无论收到的RB8是0还是1,均可以收收到的数据进入SBUF,并激活RI,通过控制SM2可实现多机通信。
在方式0时,SM2必须是0,
在方式1时,若SM2=1,则只有接收到有效停止位时,RI才置1
REN;允许串行接收位
REN=1;允许串行口接收数据
REN=0;禁止串行口接收数据
TB8;方式2、3中发送数据的第九位,可定义其作用,奇偶检验,地址帧标志等,方式0和1中,未使用
RB8;方式2、3中接收数据的第九位,可定义其作用,奇偶检验,地址帧标志等,方式1,若SM2=0,则RB8是接收到的停止位。
TI;发送中断标志位,方式0中,串行发送第8位数据结束时,或者其他方式,串行发送停止位时,由内部硬件置1,向CPU发出中断申请,在中断服务程序中,须用软件清零,取消此中断申请。
RI;接收中断标志位,
方式0中,串行接收第8位数据结束时,或者其他方式,串行接收停止位时,由内部硬件置1,向CPU发出中断申请,在中断服务程序中,须用软件清零,取消此中断申请
串口方式0,串行口为同步移位寄存器的输入输出方式,主要永不扩展并行输入输出接口,数据由RXD(P3.0)引脚输入或者输出,同步移位脉冲由TXD(P3.1)引脚输出,发送和接收均为8位数据,低位在先,高位在后。波特率固定fosc/12
串口方式1;10位数据一步通讯口,1起始,8数据,1停止,TXD(P3.1)为数据发送引脚,RXD(P3.0)为数据接收引脚。其传输波特率可变,对51而言,波特率有定时器1的溢出率而决定,一般而言,在单片基于单片机,单片机与计算机,计算机与计算机串口通讯时,基本都市选择方式1,所以此种方式必须掌握。
串口方士2,3;11位数据的异步通讯口,XD(P3.1)为数据发送引脚,RXD(P3.0)为数据接收引脚。在这两种方式下,1起始,9数据,1停止,一帧数据11位。方式2的波特率固定为晶晶振频率的1/64或1/32,方式3的波特率由定时器1的溢出率决定。
方式2和方式2的差别仅在于波特率的选取不同,两种方式下,接收到的停止位与SBUF,RB8,RI都无关。
串口方式1的编程实现
方式1数据输出时序图如下:
当数据被写入SBUF寄存器后,单片机自动开始从起始位发送数据,发送到停止位的开始时,
由内部硬件将TI置1,向CPU申请中断,接下来可在中断服务程序中进行相关处理,也可选择不进入中断。
用软件置REN为1时,接收器以所选择波特率的16倍速率采样RXD引脚电平,
检测到RXD引脚输入电平发声负跳变时,则说明起始位有效。
将其移入输入移位寄存器并开始接受这一帧信息的其余位。
接收过程中,数据从输入移位寄存器右边移入,起始位移至输入移位寄存器的最左边,
控制电路进行最后一次移位,当RI=0且SM2=0(或结收到的停止位为1)时,
将接受到的9位数据前8位数据装入接收SBUF,第九位(停止位)进入RB8,并置RI=1,向CPU申请中断,
在进行串口的相关操作之前,需要对单片机的一些特殊寄存器和进行初始化设置
主要是设置产生波特率的定时器1,串行口控制和中断控制,具体步骤如下:
确定T1的工作方式(编程TMOD寄存器)
计算T1的初值,装载TH1和TL1
启动T1(编程TCON中的TR1位)
确定串行口工作方式(编程SCON寄存器)
串行口工作在中断方式时,要进行中断设置(编程IE、IP寄存器)
-----------------------------------------------------------------------------------------------------------------------
//串口方式1
TMOD=0X20;&&&
//T1定时器,工作方式2
TH1=0XFD;&&&
//T1定时器装初值
TL1=0XFD;&&&
//T1定时器装初值
//启动T1定时器
//允许串口接收
//设定串口工作方式1
//设定串口工作方式1
&&& //开总中断
//开串口中断
-----------------------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------------
//串口中断服务程序
void ser() interrupt 4
//RI清零;因为收到数据或者或者发送了数据会由硬件置1
a=SBUF;&&&
&& //将SBUF中的数据读走给a
flag=1;&&&
&& //中断标志位置1
-----------------------------------------------------------------------------------------------------------------------
串行口为同步移位寄存器的输入输出方式,主要永不扩展并行输入输出接口,数据由RXD(P3.0)引脚输入或者输出,同步移位脉冲由TXD(P3.1)引脚输出,发送和接收均为8位数据,低位在先,高位在后。波特率固定fosc/12。
在该模式下,串行口的SBUF是作为同步移位寄存器使用的。
在串行口发送时。SBUF相当于一个并行进入,串行输出的移位寄存器,
由单片机的内部总线并行接收八位数据,并从RXD信号线串行输出,在接收操作时,他有相当于一个串行输入、并行输出的移位寄存器。该模式下,SM2,RB8,TB8不起作用。
方式0数据输出时序图如下:
发送操作在TI=0时进行,CPU将数据移入SBUF后,RXD线上即可发出8位数据,TXD上发送同步脉冲,
8位数据发送完后,TI由硬件置位,并在中断允许的情况下向CPU申请中断,
CPU相应中断后,先用软件是TI清零,然后再给SBUF送下一个需要发送的字符,如此重复上述过程。
方式0数据输入时序图如下:
接收过程在REN=1和RI=0的条件下启动,为此串行数据由RXD线输入,TXD线输出同步脉冲,
接收电路接收到8位数据后,RI自动置位并在中断允许的条件下向CPU发出中断请求,
CPU 查询到RI为1或者相应中断以后便将SBUF中的数据送到累加器,RI需要由软件复位,
需要注意的是:
串行口工作模式0并不是一个同步通讯串口通讯方式,
它的主要用途是与外面的同步移位寄存器相连已达到扩展单片机输入并行口和输出并行口的目的。
其可以通过芯片(74LS164)把串口数据转化成并口数据,通过芯片(74LS165)把并行输出的数据转换成串口输出
-----------------------------------------------------------------------------------------------------------------------
使用串口工作模式0间隔发送数据0XAA
void main()
SCON=0;&&&
//串行口工作方式0
&&& //开总中断
//允许串口中断
//发送中断标志位
SBUF=0XAA;&&&
-----------------------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------------
void ser0() interrupt 4
//清楚发送中断标志位
-----------------------------------------------------------------------------------------------------------------------
串口方式2和方式3
均为11位数据的异步通信口,唯一的区别在于传输速率的不同。
TXD数据发送引脚,RXD数据接收引脚,1起始,
9数据(含1位附加第9位,发送时为SCON中的TB8,接收时为RB8),1停止,一帧数据11位。
方式2的波特率固定为晶晶振频率的1/64或1/32,方式3的波特率由定时器1的溢出率决定。
串口方式2和方式3一帧数据传送格式,如图:
串口方式2和方式3输出时序图:
发送开始时,先把起始位0输出到TXD管脚,然后发送移位寄存器的的输出位(D0)到TXD引脚
每一个移位脉冲都使输出移位寄存器的各位右移一位,并由TXD引脚输出,
第一次移位时,停止位1移入输出移位寄存器的第9位,以后每次移位,左边都输入0
当停止移位至输出位时,左边其余位全为零,检测电路检测到这一条件时,使控制电路进行最后一次移位,并置TI=1;向CPU请求中断。
串口方式2和方式3输入时序图:
接受时,数据从右边移入输入移位寄存器,在起始位0移到最左边时,控制电路进行最后一次移位。
当RI=0且SM2=0(或接收到第9位数据位1)时,接收到的数据装入接收缓冲器SBUF和RB8(接收数据的第9位),置RI=1,向CPU申请中断,如果条件不满足,则数据丢失,且不置位RI,继续搜索RXD引脚的负跳变。
在方式2和方式3中,要用到SCON寄存器中的TB8位和RB8位,TB8为数据发送的第9位,用于方式2和方式3,由软件更改,RB8为数据接收的第9位,用于方式2和方式3,在方式1中,如果SM2=0,则RB8用于存放接收到的停止位,在方式0下不适用该位。
-----------------------------------------------------------------------------------------------------------------------
使用串口工作方式2发送0XAA
void main()
//SMOSM1为10,串行工作方式2
//11位异步收发(9位数据)
//数据发送的第9位
&&& //开总中断
//允许串口中断
//发送中断标志位
SBUF=0XAA;&&&
-----------------------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------------
void ser0() interrupt 4
//清楚发送中断标志位
-----------------------------------------------------------------------------------------------------------------------
单片机双机通信
通常单片机通信有以下四种实现方式:
TTL电平通信
RS-232C通信
RS-422A通信
RS-485通信
TTL电平通信:
RS-232C通信:
RS-422A通信
RS-422A驱动器为双端驱动器,其中一条线的逻辑为1,另一条线就为0,
具抗干扰型,能够200mv以上的电位差,
传输速率90Kbps,传输距离可达1200m,接口电路如下:(全双工)
RS-485通信
RS-485是RS-422A的变种,422A是全双工,485为半双工,
最多可使用32对差分器。如在一个网络中连接超过32个,还可使用中继器。
引起传输线采用差动信号,所以抗干扰性好,传输速率可达1Mbps,接口如下:
采用主从结构,在整个系统中,有且仅有一个主机,其余全是从机,多机通信所应遵循的原则如下:
A.所有从机的SM2=1;处于接收地址帧状态
B.主机发送一地址帧,其中8位是地址,第9位是地址/数据区分标志,该位置1表示地址帧。
所有从机收到地址帧后,与本季的地址比较,对于地址相符的从机,
是自己的SM2置0(已接收主机随后发来的数据帧),并把本机地址发回主机作为应答,
对于地址不符的,仍保持SM2=1,对主机随后发来的数据帧不予理睬.
C.从机发送数据结束后,要发送一帧校验和,并置第9位(TB8)为1,作为从机数据结束的标志。
D.主机验证数据时,先判断数据接收标志(RB8),若RB8=1;表示数据传送结束,并比较此帧校验和,
若正确则会送正确信号00H,命令该从机复位(即重新等待地址帧)。
若校验和出错,则发送0FFH,命令该从机重发数据。
若接受侦的RB8=0;则将数据存到缓存区,并准备接收下一帧信息。
E.主机接到从机应答地址后,确认地址是否相符,如果地址不符,
则发复位信号(数据帧中TB8=1),如果地址相符,则TB8清0,开始发送数据。
从机收到复位命令后,会到监听地址状态(SM2=1),否则开始接收数据和命令。
编程时,可按以下方式操作:
主机发送的地址联络信号为00H,01H,02H,...(即从机设备地址);地址FFH为命令各从机复位,即回复SM2=1;
主机命令编码如下:
01H:主机命令从机接收数据;
02H:主机命令从机发送数句;
若有其他数据,则都按02H对待。
从机状态字格式如图:
若ERR =1;从机收到非法命令。
若TRDY=1;从机发送准备就绪
若RRDY=1;从机接收准备就绪
通常,从机以中断方式控制和主机通讯。
多机通信主机流程图如下:
程序代码如下:
-----------------------------------------------------------------------------------------------------------------------
#define& uchar unsigned char
#define uint unsigned int
#define SLAVE 0X02&& //从机地址
#define& NB 16
uchar rbuf[16];
uchar code tbuf[16]={"master transmit"};
void err()
SBUF=0XFF;
while(!TI=1);
-----------------------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------------
uchar master(uchar add,uchar com)
SBUF=SLAVE;&&&
//发呼叫地址
while(!TI=1);
while(!RI=1);
//等待从机应答
if(SBUF!=add)
//地址错误,发复位信号
&&& //地址相符
//清地址标志
&&& //发命令
while(!TI=1);
while(!RI=1);
aa=SBUF;&&&
&&& //接收状态
if(aa&0x08==0x08)&&&
//若命令未被接收,发复位信号
&&& TB8=1;
&&& err();
if(cmd==0X01)&&&
& //发送命令
if(aa&0x01==0x01)&&&
&//从机准备好接受
& //清校验和
SBUF=tbuf[i];&&&
//发送一数据
p+=tbuf[i];
while(!TI=1);
SBUF=p;&&&
//发送检验和
while(!TI=1);
while(!RI=1);
while(SBUF!=0);&&&
//接收不正确,重新发送
//置地址标志
return(0);
if(aa&0x02==0x02)&&&
//是接收命令,从机准备好发送
&&& //清检验和
while(!RI=1);
rbuf[i]=SBUF;&&&
//接收一数据
p+=rbuf[i];
while(!RI=1);
if(SBUF==p)
SBUF=0x00;&&&
//校验和相同发0X00
while(!TI=1);
SBUF=0xFF;
while(!TI=1);
//置地址标志
return(0);
-----------------------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------------
void main()
TMOD=0x20;&&&
//T/C1定义为方式2
TL1=0XFD;&&&
PCON=0X00;
&&& TR1=1;
SCON=0XF0;&&&
//串行口方式3
master(SLAVE,0x01);
master(SLAVE,0X02);
-----------------------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------------
多机通信从机流程图:
程序如下:
-----------------------------------------------------------------------------------------------------------------------
#define uchar unsigned char
#define uint unsigned int
#define& SLAVE 0X02
#define BN& 16
uchar trbuf[16];
uchar rebuf[16];
void str(void);
void sre(void);
void main()
TMOD=0x20;&&&
//T/C1定义为方式2
PCON=0X00;
&&& TR1=1;
SCON=0XF0;
&//开串行口中断
&//开总中断
rready=1;&&&
&//假定准备好发送和接受
-----------------------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------------
void ssio(void) interrupt 4
if(SBUF!=SLAVE)
//非本机地址继续监听
//取消监听状态
SBUF=SLAVE;&&&
//从本地址发回
while(!TI=1);
while(!RI=1);
&&& SM2=1;
//是复位信号,恢复监听
a=SBUF;&&&
&&& //接收命令
if(a==0X01)
if(rready=1)
SBUF=0X01;&&&
//接收准备好发状体
SBUF=0X00;
while(!TI=1);
while(!RI=1);
if(RB8==1)
&&& SM2=1;
&&& //接收数据
if(a==0X02)&&&
//从机向主机发送数据
if(tready=1)
SBUF=0X02;&&&
//发送准备好发状体
SBUF=0X00;
while(!TI=1);
while(!RI=1);
if(RB8==1)
&&& SM2=1;
&&& //发送数据
SBUF=0X80;&&&
//命令非法,发状态
while(!TI=1);
&&& SM2=1;
&&& //恢复监听
-----------------------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------------
str(void)&&&
//发送数据块
&&& //清校验和
SBUF=trbuf[i];&&&
//发送一数据
p+=trbuf[i];
while(!TI=1);
&&& SBUF=p;
//发送校验和
while(!TI=1);
while(!RI=1);
}while(SBUF!=0);&&&
//主机接收不正确,从新发送
&&& SM2=1;
-----------------------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------------
sre(void)&&&
//接收数据块
&&& //清校验和
while(!RI=1);
rebuf[i]=SBUF;&&&
&&& //接收数据
p+=rebuf[i];
while(!RI=1);
if(SBUF==p)
SBUF=0X00;
& //校验和相同发00
SBUF=0XFF;&&&
//校验值不同发0FF,重新接收
while(!TI=1);
&&& SM2=1;
-----------------------------------------------------------------------------------------------------------------------
以上是51串口的通讯的协议内容,也可以说是串口通讯协议。其与Uart等具有相同的传输性质:双向传输,全双工!
Powered by2044人阅读
【电子嵌入式】(60)
51单片机+Proteus仿真(5)
【若有疑问错误或版权等问题请联系我】&
【转载请注明出处:】
51单片机默认使用定时器1作为串口通信的波特率发生器、定时器1中断通信,串口与定时器1冲突,在遇到定时器不够用的时候可以用定时器2
#include &reg52.h&
void DelayMs(unsigned int i);
void SerialInit();
void SendByte(unsigned char sbyte);
void SendString(unsigned char *pstr);
void main(void)
SerialInit();
//注:必需要无限循环
//单片机时钟周期:11.0592MHz
以时钟1作为波特率发生器
void SerialInit(){
TMOD=0x20;
//设置T1工作方式为方式2
TH1=0 //给定时器高位装初值
TL1=0 //给定时器低位装初值
//开定时器
//以上是设置波特率
//设置串口通讯方式为方式1
//串口是否接收数据的开关
EA=1; //总中断打开,采用查询法时不用打开中断
ES=1; //串口中断开关,采用查询法时不用打开中断
//单片机时钟周期:11.0592MHz
以时钟T2作为波特率发生器
void SerialInit(){
PCON &= 0x7F;
//波特率不倍速 SMOD=0
SCON = 0x50;
//方式1,8位数据,可变波特率,接收允许
RCAP2H = 0xFF;
RCAP2L = 0xDC;
EA=1; //总中断打开,采用查询法时不用打开中断
//串口中断开关,采用查询法时不用打开中断
//串口中断函数:
void SerialPortInte(void) interrupt 4 //采用串口中断法收发数据
//RI=1,判定为串口接收到了数据,RI要清零,
rbyte=SBUF;
if(rbyte==0x0A){
SendString(&换行&);
}else if(rbyte==0x0D){
SendString(&回车&);
SendByte(rbyte);
//串口发送一个字节:
void SendByte(unsigned char sbyte)
SBUF= //发送数据
while(!TI); //等待发送完成
TI=0; //清零发送标志位
//串口发送一个字符串:
void SendString(unsigned char *pstr) //定义指针
while(*pstr!='\0') //字符串是否发完
SendByte(*pstr);//发送字符串数据
pstr++; //指向下一个字符
void DelayMs(unsigned int i)
//延时i ms
while(i--)
for(j = 0; j & 125; j++);
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:175796次
积分:3080
积分:3080
排名:第11063名
原创:102篇
转载:38篇
译文:13篇
评论:59条
欢迎评论交流
正常情况每天都会查看^_^
Ename: Leytton
started from
阅读:5241
阅读:7935
阅读:32805
(6)(6)(9)(6)(4)(1)(3)(3)(1)(13)(6)(7)(8)(12)(10)(1)(4)(31)(10)(8)(4)2010年6月 硬件/嵌入开发大版内专家分月排行榜第二
本帖子已过去太久远了,不再提供回复功能。51单片机串口通信【程序+图文】-51单片机-单片机入门教程日记
51单片机串口通信【程序+图文】
51单片机串口通信【程序+图文】
阅读:(16502)
什么是通信关于通信的概念我想大家肯定都心知肚明,就是“聊天”呗。我们把制作好的单片机系统叫做下位机,把电脑称为上位机,它们之间通常是需要相互通信的。比如:单片机:主人,发现有人进入我们的领地。电脑:来者即是客,好生招待。单片机:好的,那该如何招待?电脑:杀死。单片机:。。。单片机与单片机、单片机与电脑、电脑与电脑之间都需要通信,以了解彼此的工作状态或者进行相关控制,当然,他们之间的通信肯定不是吧啦吧啦地真在那聊天,要真那样就见鬼了,它们之间还是得通过一定的协议,一定的方法来传输“”之类的二进制数而已,然后通过识别不同的数字来实现不同的功能。通信方式机器之间的通信实际上就是指收发各种字节,通常有两种方式:并行通信,串行通信。并行数据通信是指数据的各位同时进行传送的通信方式。其优点是传送速度快;缺点是数据有多少位,就需要多少根传送线。串行数据通信是指数据是一位一位顺序传送的通信方式,它的突出优点是只需一对传送线,这样就大大降低了传送成本,特别适应于远距离通信;其缺点是传送速度较低。假设并行传送N位数据所需时间为T,那么串行传送的时间至少为N*T。更多时候我们会使用串行通信。在串行通信中,按照收发双方是否具有同步时钟又可分为同步通信和异步通信同步通信时要建立发送方时钟对接收方时钟的直接控制,使双方达到完全同步。此时,传输数据的位之间的距离均为“位间隔”的整数倍,同时传送的字符间不留间隙,即保持位同步关系,也保持字符同步关系。发送方对接收方的同步可以通过外同步和自同步两种方法实现[7][8]。为自同步原理图如图所示。异步通信是指通信的发送与接收设备使用各自的时钟控制数据的发送和接收过程。为使双方的收发协调,要求发送和接收设备的时钟尽可能一致。异步通信以字符(构成的帧)为单位进行传输,字符与字符之间的间隙(时间间隔)也是任意的,但每个字符中的各位是以固定的时间传送的。原理图如图所示。数据传输模式又分为单工、半双工、全双工和多工工作方式。单工方式时,数据仅按一个固定方向传送。因而这种传输方式的用途有限,常用于串行口的打印数据传输与简单系统间的数据采集。半双工方式时数据可实现双向传送,但不能同时进行,实际的应用采用某种协议实现收/发开关转换,生活中的对讲机就是半双工模式。全双工方式时允许双方同时进行数据双向传送,比如电话手机等。这三种传输方式都是用同一线路传输同一种频率信号,为了充分利用线路资源,可通过使用多路复用器或多路集线器,采用频分、时分或码分复用技术,即可实现在同一线路上共享功能,我们称之为多工传输方式。几种传输方式框图如图2-2所示。从前往后依次为单工、半双工和全双工。按照上述的通信方式,在单片机的世界里集成了好多种通信模块,常见的有I2C、SPI、URAT(串口通信)等。它们之间的不同之处目前可以简单的理解为需要双方对的暗号不一样,打一个比较高尚的比方,比如:甲:锄禾日当午乙:黄河入海流甲:举头望明月乙:我爱喝酱油甲:哦,原来是I2C兄啊,失敬失敬。乙:嗯,上级让我给您传个信儿。。。SPI可能又是另外一套暗号,关于I2C和SPI的靠谱点的详细介绍以及传输协议等等的,我们现在没有必要去深究,等用的时候再说吧。这一节,我们主要学习51单片机上的“异步串行通信模块”即人们常说的“串口通信”,它是一种全双工工作模式。串口通信(1)结构MCS-51单片机内部有一个全双工的串行通信口,即串行接收和发送缓冲器(SBUF),这两个在物理上独立的接发送器,但它们共占用一个地址99H,所以它们的名字都叫SBUF,而且既可以接收数据也可以发送数据。但接收缓冲器只能读出不能写入,而发送缓冲器刚只能写入不能读出。这个通信口既可以用于网络通信,亦可以实现串行异步通信,还可以构成同步移位寄存器使用。如果在传行口的输入输出引脚上加上电平转换器,就可以方便地构成标准的RS-232接口。80C51单片机的串行口的结构如图所示。TXD对应单片机上的P3.1管脚,是数据发送管脚;RXD对应单片机上的P3.0管脚,是数据接收管脚;TH1、TL1您看着熟悉吗?没错,就是上文中T1定时器模块的计数器寄存器,在这用来设置串口通信的波特率(传播速度,下文中会详细介绍);TI和RI分别为发送数据成功标志位和接收数据成功标志位,当这两个标志位有一个置1的同时若串口通信中断允许位ES也为1的话,将进入串口通信中断函数。(2)相关寄存器1.特殊功能寄存器SCON&&& SCON 是一个特殊功能寄存器,用以设定串行口的工作方式、接收/发送控制以及设置状态标志,字节地址为98H。SCON寄存器的各位定义如表3-1所示。位76543210SCON字节地址:98HSM0SM1SM2RENTB8RB8TIRI表3-1 SCON寄存器SM0、SM1:工作方式选择位,可选择四种工作方式,如表3-2所示。SM0SM1方式说明波特率000移位寄存器fosc/1201110位异步收发器(8位数据)可变10211位异步收发器(9位数据)fosc/64或fosc/3211311位异步收发器(9位数据)可变表3-2 串口通信4种工作方式SM2:多机通信控制位。主要用于方式2和方式3。当接收机的SM2=1时可以利用收到的RB8来控制是否激活RI(RB8=0时不激活RI,收到的信息丢弃;RB8=1时收到的数据进入SBUF,并激活RI,进而在中断服务中将数据从SBUF读走)。当SM2=0时,不论收到的RB8为0和1,均可以使收到的数据进入SBUF,并激活RI(即此时RB8不具有控制RI激活的功能)。通过控制SM2,可以实现多机通信。在方式0时,SM2必须是0。在方式1时,若SM2=1,则只有接收到有效停止位时,RI才置1。REN:允许串行接收位。由软件置REN=1,则启动串行口接收数据;若软件置REN=0,则禁止接收。TB8:用在方式2或方式3中,是发送数据的第九位,可以用软件规定其作用。可以用作数据的奇偶校验位,或在多机通信中,作为地址帧/数据帧的标志位(在方式0和方式1中,该位未用) 。RB8:用在方式2或方式3中,是接收到数据的第九位,作为奇偶校验位或地址帧/数据帧的标志位。在方式1时,若SM2=0,则RB8是接收到的停止位。TI:发送中断标志位。在方式0时,当串行发送第8位数据结束时,或在其它方式,串行发送停止位的开始时,由内部硬件使TI置1,向CPU发中断申请。在中断服务程序中,必须用软件将其清0,取消此中断申请。RI:接收中断标志位。在方式0时,当串行接收第8位数据结束时,或在其它方式,串行接收停止位的中间时,由内部硬件使RI置1,向CPU发中断申请。也必须在中断服务程序中,用软件将其清0,取消此中断申请。2.特殊功能寄存器PCONPCON的字节地址为87H,它的第7位SMOD是与串口通信波特率的设置有关的选择位。SMOD(PCON.7)为波特率倍增位。在串行口方式1、方式2、方式3时,波特率与SMOD有关,当SMOD=1时,波特率提高一倍。复位时,SMOD=0。(3)工作方式根据SM0和SM1的值,串口通信有这么四种工作方式。1.方式0& & 设置SCON寄存器的SM0、SM1=0 0时,串行口工作于方式0。此时,串行口为同步移位寄存器的输入输出方式。主要用于扩展并行输入或输出口。数据由RXD(P3.0)引脚输入或输出,同步移位脉冲由TXD(P3.1)引脚输出。发送和接收均为8位数据,低位在先,高位在后。波特率固定为fosc/12。其中fosc为时钟频率。& & 2.方式1& & 设置SCON寄存器的SM0、SM1=0 1时,串行口工作于方式1。方式1是10位数据的异步通信口。TXD为数据发送引脚,RXD为数据接收引脚,传送一帧数据的格式如图所示。其中1位起始位,8位数据位,1位停止位。用软件置REN为1时,接收器以所选择波特率的16倍速率采样RXD引脚电平,检测到RXD引脚输入电平发生负跳变时,则说明起始位有效,将其移入输入移位寄存器,并开始接收这一帧信息的其余位。接收过程中,数据从输入移位寄存器右边移入,起始位移至输入移位寄存器最左边时,控制电路进行最后一次移位。当RI=0,且SM2=0(或接收到的停止位为1)时,将接收到的9位数据的前8位数据装入接收SBUF,第9位(停止位)进入RB8,并置RI=1,向CPU请求中断。方式一的输入输出图如图3-8、3-9所示。图3-8 方式1输入图3-9 方式1输出3.方式2和方式3设置SCON寄存器的SM0、SM1=1 0时,串行口工作于方式2,当SM0、SM1=1 1时,串行口工作于方式3。方式2或方式3为11位数据的异步通信口。TXD为数据发送引脚,RXD为数据接收引脚 。方式2和方式3时起始位1位,数据9位(含1位附加的第9位,发送时为SCON中的TB8,接收时为RB8),停止位1位,一帧数据为11位。方式2的波特率固定为晶振频率的1/64或1/32,方式3的波特率由定时器T1的溢出率决定。方式2和方式3输出:发送开始时,先把起始位0输出到TXD引脚,然后发送移位寄存器的输出位(D0)到TXD引脚。每一个移位脉冲都使输出移位寄存器的各位右移一位,并由TXD引脚输出。第一次移位时,停止位“1”移入输出移位寄存器的第9位上 ,以后每次移位,左边都移入0。当停止位移至输出位时,左边其余位全为0,检测电路检测到这一条件时,使控制电路进行最后一次移位,并置TI=1,向CPU请求中断。发送时序图如下图3-10所示。图3-10 方式2或方式3的发送时序图方式2和方式3输入:接收时,数据从右边移入输入移位寄存器,在起始位0移到最左边时,控制电路进行最后一次移位。当RI=0,且SM2=0(或接收到的第9位数据为1)时,接收到的数据装入接收缓冲器SBUF和RB8(接收数据的第9位),置RI=1,向CPU请求中断。如果条件不满足,则数据丢失,且不置位RI,继续搜索RXD引脚的负跳变。接收时序图如图3-11所示。图3--11 方式2或方式3的接收时序图4.波特率的计算在串行通信中,收发双方对发送或接收数据的速率要有约定。通过软件可对单片机串行口编程为四种工作方式,其中方式0和方式2的波特率是固定的,而方式1和方式3的波特率是可变的,由定时器T1的溢出率来决定。串行口的四种工作方式对应三种波特率。由于输入的移位时钟的来源不同,所以,各种方式的波特率计算公式也不相同。方式0的波特率= &fosc/12方式2的波特率=(2SMOD/64)· fosc方式1的波特率=(2SMOD/32)·(T1溢出率)方式3的波特率=(2SMOD/32)·(T1溢出率)当T1作为波特率发生器时,最典型的用法是使T1工作在自动再装入的8位定时器方式(即方式2,且TCON的TR1=1,以启动定时器)。这时溢出率取决于TH1中的计数值。计算公式如3-1所示:& & & & & & & T1 溢出率 = fosc /{12×[256 -(TH1)]} & & & & &(3-1)在单片机的应用中,常用的晶振频率为:12MHz和11.0592MHz。所以,选用的波特率也相对固定。(4)实例程序上面说了不少,大家可能还在为串口通信不同工作方式下的时序图而纠结呢,我告诉大家一个秘密。那个时序图大家其实不用太在意,编程的时候是没有它们的事的,所有的时序都由硬件自动完成,除非该单片机没有集成串口通信模块,那就得自己编程来模拟整个时序过程了,万幸的是51单片机(甚至所有单片机)都集成了串口通信模块。接下来利用串口通信能力实现一个单片机和电脑通信的功能。硬件电路图如下所示:这里单片机和电脑相连,单片机的电平为TTL电平,它默认VCC(5V)为逻辑正,0为逻辑负,而电脑使用的是RS232电平,它默认+12V为逻辑负,-12V为逻辑正,为了让这俩正常通讯,比如单片机发高电平5V,电脑也能感受到高电平,就需要让单片机的电平发生一个转换,5V转换为-12V,0转换为+12V,MAX232芯片就有这样的转换能力。J1是一个串口接头,一般的笔记本上没有串口,我们可以用一根USB转串口线来代替,不过提前得安装一个USB转串口的驱动程序。什么?你没有USB转串口线?少年,太落伍了,赶紧去买一根,也不贵,十几块钱左右吧。什么?你没钱?也好办,把手里的这本书卖了换钱去。什么?卖了就没书看了?简单啊,再把USB转串口线卖了买书。编写一个单片机向电脑发送字符串的程序,如下所示#include &reg52.h&#define uintunsigned int/**********************************************************函数名: delay(uint x)**返回:无**函数功能描述:延时函数,延时大概x毫秒**********************************************************/void delay(uint x) & & & & & &//延时函数。{ && & uinti,j;& & for(i=0;i&=x;i++)& & & &for(j=0;j&=100;j++);}char &code MESSAGE[]= &123456&;&/**********************************************************函数名:main(void)**返回:无**函数功能描述:单片机通过串口向电脑发送数据**********************************************************/&void main(void){& & & & SCON = 0x50; & //REN=1允许串行接受状态,串口工作模式2 & & & && & & &TMOD|= 0x20; & //定时器工作方式2 & & & & & & & & & & && & & & PCON|= 0x80; & //波特率提高一倍 & & & & & & & & & & & & & & & & & & & & & & & & &&& & & &TH1 = 0xF3; // &波特率4800、数据位8、停止位1。效验位无 (12M)& & & & TL1= 0xF3;& & & & TR1 = 1; & & & &//开启定时器1 & & & & & & & & & & & & & & & & & & & & & & & & & &&& & & & ES &= 0; & & & &//开串口中断 & & & & & & & &&& & & & EA &= 0; & & & &// 开总中断& & & while(1)& & & {a=0; &&& & & while(MESSAGE[a] != '\0')& & & {& & & & SBUF = MESSAGE[a];//SUBF接受/发送缓冲器(又叫串行通信特殊功能寄存器)& & & & &while(!TI); // 等特数据传送(TI发送中断标志)& & & & &TI = 0; & &//清除数据传送标志 & && & & & &a++; & & & & & & & & & & & // 下一个字符& & & &}& & & & delay(1000);&& & &}}然后赶紧在电脑上安装一个串口通信调试助手来观察一下结果吧。可能您又会纳闷,串口通信不是发的二进制数据吗,为啥写了数字也能发送呢。这里你可以把数字看成一个个的字符,其实每一个字符都对应着一个(或几个)二进制编码,单片机发送的时候会自动将它变成二进制数,到电脑里电脑再识别回数字,这就是著名的ASIIC编码。下表为ASIIC编码一览表。我们勾选上软件中的“HEX显示”复选框,再看接收到的信息就不再是“123456”而是“31 32 33 34 35 36”了,这是因为ASIIC编码表中的数字“1”对应二进制“”转换成16进制正是“31”,其他数字以此类推。本章总结这一章的主要目的就是让大家快速入门单片机这门看似神秘的课程,我们尽量使用通俗的语言生动介绍什么叫做单片机以及如何学习单片机等等,重点给大家介绍了的几个常用模块的原理和编程实现,大家以后再学习单片机其他模块的时候思路是一样的,比如AD转换,比如I2C,比如SPI、比如液晶显示、比如各种芯片的使用等等,基本上都是先了解基本原理,然后重点研究相关寄存器,然后老老实实地编程验证,单片机是一门实验性极强的课程,相信大家认真思考,认真试验的话肯定能很快掌握它。最后的最后我们再给出8051单片机的内核结构图,现在再看这些东西,您是不是会有新的体会呢?1、CPU:单片机的核心,俗称大脑,主要完成运算和控制功能,CPU里含有运算器、控制器和若干寄存器,能够处理8位二进制数或代码。2、RAM数据存储器:8051共含有256B的RAM数据存储器,其中128B被专用寄存器占用,另外的128B用来存放可读写的数据,它主要由数据存储区、通用工作寄存区、堆栈、位地址空间等构成。3、ROM程序存储器:8051共有4K的ROM程序存储器,用于存放程序、原始数据或表格。4、定时器/计数器:8051单片机有2个16位定时器,52多了一个。主要用于外部信号脉冲的计数或内部定时。5、可编程I/O口:8051具有4个8位可编程I/O口(P0、P1、P2、P3),用以进行数据输出输出。6、中断系统:8051有5个中断源,其中外部中断2个,定时器中断2个,串行通信中断1个,每个中断均可设置中断优先级。7、可编程串行口:8051具有一个全双工通用异步收发器,俗称串行口,用以实现单片机和其他设备之间的数据串行通信。8、时钟电路:8051内置12MHz的时钟电路,用于产生整个单片机运行的时钟脉冲,但需要外接晶振和电容。外部晶振为12MHz的情况下,单周期指令的执行时间为1us。9、总线控制:8051总线控制用于仲裁总线上数据、指令的访问于操作

我要回帖

更多关于 单片机串口通讯 的文章

 

随机推荐