51单片机采用中断方式的串口通信过程及程序分析:
所谓中断方式,就是串口收/发标志位出发中断后,在中断中执行既定操作,可通过函数调用来实现。
接收数据时: 等待中断->然后在中断中接收数据
发送数据时: 发送数据->等待中断->然后在中断中发送数据
具体步骤如下:
- 确定T1的工作方式(编程TMOD寄存器);
- 计算T1的初值,装载TH1、TL1;
- 启动T1(编程TCON中的TR1位);
- 确定串行口控制(编程SCON寄存器);
- 串行口在中断方式工作时,要进行中断设置(编程IE、IP寄存器)。
注:SCON 是一个特殊功能寄存器,用以设定串行口的工作方式、接收/发送控制以及设置状态标志:
有关波特率的计算方法:
在串行通信中,收发双方对发送或接收数据的速率要有约定。通过软件可对单片机串行口编程为四种工作方式,其中方式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中的计数值。
- T1 溢出率 = fosc /{12×[256 -(TH1)]}
注:PCON中只有一位SMOD与串行口工作有关, SMOD(PCON.7) 波特率倍增位。在串行口方式1、方式2、方式3时,波特率与SMOD有关,当SMOD=1时,波特率提高一倍。复位时,SMOD=0。
在单片机的应用中,常用的晶振频率为:12MHz和11.0592MHz。所以,选用的波特率也相对固定。常用的串行口波特率以及各参数的关系如表所示。
80C51串行口的工作方式1:
方式1是10位数据的异步通信口。TXD为数据发送引脚,RXD为数据接收引脚,传送一帧数据的格式如图所示。其中1位起始位,8位数据位,1位停止位。
- (1) 方式1输出
- (2) 方式1输入
用软件置REN为1时,接收器以所选择波特率的16倍速率采样RXD引脚电平,检测到RXD引脚输入电平发生负跳变时,则说明起始位有效,将其移入输入移位寄存器,并开始接收这一帧信息的其余位。接收过程中,数据从输入移位寄存器右边移入,起始位移至输入移位寄存器最左边时,控制电路进行最后一次移位。当RI=0,且SM2=0(或接收到的停止位为1)时,将接收到的9位数据的前8位数据装入接收SBUF,第9位(停止位)进入RB8,并置RI=1,向CPU请求中断。
定时/计数器的结构与原理
定时/计数器的实质是加1计数器(16位),由高8位和低8位两个寄存器组成。TMOD是定时/计数器的工作方式寄存器,确定工作方式和功能;TCON是控制寄存器,控制T0、T1的启动和停止及设置溢出标志。
加1计数器输入的计数脉冲有两个来源,一个是由系统的时钟振荡器输出脉冲经12分频后送来;一个是T0或T1引脚输入的外部脉冲源。每来一个脉冲计数器加1,当加到计数器为全1时,再输入一个脉冲就使计数器回零,且计数器的溢出使TCON中TF0或TF1置1,向CPU发出中断请求(定时/计数器中断允许时)。如果定时/计数器工作于定时模式,则表示定时时间已到;如果工作于计数模式,则表示计数值已满。
可见,由溢出时计数器的值减去计数初值才是加1计数器的计数值。
设置为定时器模式时,加1计数器是对内部机器周期计数(1个机器周期等于12个振荡周期,振荡周期也叫时钟周期,时钟周期即晶振的单位时间发出的脉冲数,如12MHZ=12×10的6次方,即每秒发出12000000个脉冲信号,那么发出一个脉冲的时间就是时钟周期,即1/12微秒;如11.0592MHZ=11.0592×10的6次方,即每秒发出11059200个脉冲信号,那么发出一个脉冲的时间就是时钟周期,即1/11.0592微秒)。计数值N乘以机器周期Tcy就是定时时间t 。
定时/计数器的控制
80C51单片机定时/计数器的工作由两个特殊功能寄存器控制。TMOD用于设置其工作方式;TCON用于控制其启动和中断申请。
- 工作方式寄存器TMOD
工作方式寄存器TMOD用于设置定时/计数器的工作方式,低四位用于T0,高四位用于T1。其格式如下:
M1M0:工作方式设置位。定时/计数器有四种工作方式,由M1M0进行设置:
控制寄存器TCON
TCON的高4位用于控制定时/计数器的启动和中断申请。其格式如下:
- TF1(TCON.7):T1溢出中断请求标志位。T1计数溢出时由硬件自动置TF1为1。CPU响应中断后TF1由硬件自动清0。T1工作时,CPU可随时查询TF1的状态。所以,TF1可用作查询测试的标志。TF1也可以用软件置1或清0,同硬件置1或清0的效果一样。
- TR1(TCON.6):T1运行控制位。TR1置1时,T1开始工作;TR1置0时,T1停止工作。TR1由软件置1或清0。所以,用软件可控制定时/计数器的启动与停止。
- TF0(TCON.5):T0溢出中断请求标志位,其功能与TF1类同。
- TR0(TCON.4):T0运行控制位,其功能与TR1类同。
定时器1的工作方式2
方式2为自动重装初值的8位计数方式。
计数个数与计数初值的关系为:X = 2^8 - N
其中:X为要装的初值 N为要定时/记数的次数。
注:工作方式2特别适合于用作较精确的脉冲信号发生器。所以在进行串口通信时一般选用定时器1工作在方式2 这种经典模式。
程序:
/*51单片机采用中断方式的串口通信程序分析:
接收数据时 等待中断->然后在中断中接收数据
发送数据时 发送数据->等待中断->然后在中断中发送数据
具体步骤如下:
确定T1的工作方式(编程TMOD寄存器);
计算T1的初值,装载TH1、TL1;
启动T1(编程TCON中的TR1位);
确定串行口控制(编程SCON寄存器);
串行口在中断方式工作时,要进行中断设置(编程IE、IP寄存器)。
*/
#include <reg52.h>
#define uchar unsigned char
uchar Temp,RIflag,TIflag;
//串口初始化函数
void serialportinit() {
TMOD=0x20;//设置定时器1为工作方式2 8位自动重装载 作用是产生波特率
TH1=0xfd;//设置波特率位9600bps
TL1=0xfd;
TR1=1;//开启定时器1
//设置串口工作在方式1
//方式1: 8位异步收发 波特率可变(由定时器控制) 收发一帧的数据为10位 一个起始位(0)8个数据位 1个停止位(1)
//先发送或接收最低位
SCON=0x50;//等价于 SM0=0; SM1=1; REN=1;
//SM0=0;
//SM1=1;
//REN=1;//允许串行接收位 允许串行口接收数据
PCON=0x00;//SMOD=0 波特率不加倍
EA=1;//开总中断
ES=1;//开串口中断 注意:如果使用查询方式进行串口通信时,要把串口中断ES关闭、
}
//定义数据发送函数
void sentTemp() {
SBUF=Temp;//把Temp接收的数据再发送到发送缓冲器SBUF中
//注意:51单片机内部有两个物理上独立的接收、发送缓冲器SBUF(属于特殊功能寄存器) 两个缓冲器共用一个特殊功能寄存器 字节地址(99H?
while(!TI);//等待从机向主机发送数据完成
TI=0;//若发送完成 把发送中断标志位软件清0 因为TI必须由软件清零
}
void main() {
serialportinit();
while(1) {
if(RIflag==1) {
ES=0;//关串口中断
RIflag=0;//接收标志位清0
sentTemp();//调用数据发送函数
ES=1;//开串口中断
}
}
}
//串口中断服务函数
void serialportint() interrupt 4 { //串口中断函数
if(RI) {
RI=0;//接收中断标志位RI必须由软件清0
Temp=SBUF;//把接收缓冲器中收到的数据赋值给led
P1=Temp;//通过开发板监测是否接收到主机发送的数据
RIflag=1;//接收标志位置1 表示从机接收收据完成
}
}
此文章同时同步到我的个人博客緣來來來»51单片机采用中断进行串口通信