51单片机采用中断进行串口通信

所谓中断方式,就是串口收/发标志位出发中断后,在中断中执行既定操作,可通过函数调用来实现。

接收数据时: 等待中断->然后在中断中接收数据

发送数据时: 发送数据->等待中断->然后在中断中发送数据

具体步骤如下:

确定 T1 的工作方式(编程 TMOD 寄存器);
计算 T1 的初值,装载 TH1、TL1;
启动 T1(编程 TCON 中的 TR1 位);
确定串行口控制(编程 SCON 寄存器);
串行口在中断方式工作时,要进行中断设置(编程 IE、IP 寄存器)。
注:SCON 是一个特殊功能寄存器,用以设定串行口的工作方式、接收/发送控制以及设置状态标志:

有关波特率的计算方法

在串行通信中,收发双方对发送或接收数据的速率要有约定。通过软件可对单片机串行口编程为四种工作方式,其中方式 0 和方式 2 的波特率是固定的,而方式 1 和方式 3 的波特率是可变的,由定时器 T1 的溢出率来决定。

串行口的四种工作方式对应三种波特率。由于输入的移位时钟的来源不同,所以,各种方式的波特率计算公式也不相同。

1
2
3
4
方式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 是 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 位用于控制定时/计数器的启动和中断申请。其格式如下:

  1. TF1(TCON.7):T1 溢出中断请求标志位。T1 计数溢出时由硬件自动置 TF1 为 1。CPU 响应中断后 TF1 由硬件自动清 0。T1 工作时,CPU 可随时查询 TF1 的状态。所以,TF1 可用作查询测试的标志。TF1 也可以用软件置 1 或清 0,同硬件置 1 或清 0 的效果一样。
  2. TR1(TCON.6):T1 运行控制位。TR1 置 1 时,T1 开始工作;TR1 置 0 时,T1 停止工作。TR1 由软件置 1 或清 0。所以,用软件可控制定时/计数器的启动与停止。
  3. TF0(TCON.5):T0 溢出中断请求标志位,其功能与 TF1 类同。
  4. TR0(TCON.4):T0 运行控制位,其功能与 TR1 类同。

定时器 1 的工作方式 2

方式 2 为自动重装初值的 8 位计数方式。

计数个数与计数初值的关系为:X = 2^8 - N

其中:X 为要装的初值 N 为要定时/记数的次数。

注:工作方式 2 特别适合于用作较精确的脉冲信号发生器。所以在进行串口通信时一般选用定时器 1 工作在方式 2 这种经典模式。

程序:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76

/*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 表示从机接收收据完成
}
}