目录
一、定时器/计数器
(一)什么是定时器/计数器
定时器/计数器,是一种可以对所接收到的信号进行响应,即对接收的内部时钟信号或外部输入信号进行计数,其呈现周期性的计数方式(有点类似于现实生活中时钟计数方式)。故定时器/计数器的最基本工作原理就是进行计数。
(二)、51单片机定时器/计数器的结构
51单片机定时器/计数器的结构如图1
图1 51单片机定时器/计数器的结构
其中TMOD用于选择定时器/计数器T0、T1的工作模式和工作方式,TCON用于控制定时器/计数器T0,T1的启动和停止,同时还包括定时器/计数器的T0、T1的状态,它的内容有软件设计或查询,单片机复位时,TMOD、TCON的各位皆位0.
1、控制寄存器TMOD
工作方式控制寄存器TMOD用于选择定时器/计数器T0、T1的工作模式和工作方式,它是字节地址为89H,不可位寻址。
GATE | C/T | M1 | M0 | GATE | C/T | M1 | M0 |
定时器/计数器T1 | 定时器/计数器T0 |
注:高八位为定时器/计数器T1的方式控制字段;低八位为定时器/计数器T1的方式控制字段。
(1)GATE:门控位
GATE=0,由TR0和TR1启动定时器/计数器;GATE=1,由外部中断INT1和INT0启动定时器/计数器。
(2)C/T:定时器/计数器工作模式选择位
C/T=0,为定时功能;C/T=1,为计数功能;
(3)M1,M0:定时器/计数器工作方式选择位
如图2所示
M1 | M0 | 工作方式 |
0 | 0 | 方式0,为13位定时器/计数器 |
0 | 1 | 方式1,为16位定时器/计数器 |
1 | 0 | 方式2,为8位自动重装计数初值的定时器/计数器 |
1 | 1 | 方式3,定时器/计数器T0分成两个独立的8位定时器/计数器,只适用于定时器/计数器T0,不能用于定时器/计数器T1 |
2、控制寄存器TCON
对于TCON的讲解见:【蓝桥杯】——单片机的中断系统_m0_50708613的博客-优快云博客
(三)定时器/计数器的编码思路
定时器/计数器的程序设计,通常包含两个函数:初始化函数和中断服务函数
1、初始化函数
(1)确定工作方式(即对TMOD赋值)
(2)预值定时器/计数器的初值,即TH0、TL0或者TH1、TL1的确定。
(3)根据需要决定是否开放定时器/计数器的中断,直接对IE对应位赋。
(4)启动定时器/计数器。
2、中断服务函数
(1)判断工作方式,如果不是自动重装模式,需要对THx和TLx重新赋值。
(2)进行间隔定时到达的逻辑处理。
二、51单片机串行口
(一)单片机串行的基本概念
1、串口通信是串行数据一帧一帧进行发送和接收。
2、串口通信的模式有:单工、半双工和全双工三种。
3、异步通信:就是接收和发送双方不使用共同的同步时钟来控制收、发双方的同步。而是依靠各自的时钟来控制数据的传送。
4、波特率:是指串行口每秒发送或接收数据的位数,单位为b/s。每发送一位所需的时间为T,则其波特率为1/T
(二)串行口结构
如图3所示
串行数据缓冲器SBUF
SBUF是两个物理上独立的发送缓冲器和接收缓冲器,可同时发送、接收数据、可实现全双工串行通信。两个缓冲器共用于一个特殊功能的寄存器字节地址99H。串行发送时,从内部总线向发送缓冲器SBUF写入数据;串行接收时,从接收缓冲器SBUF中读取数据。
(三)、与串口相关的寄存器
51单片机中与串口相关的寄存器有四类:
a: TH1和TL1:设置波特率参数。
b: TMOD:设置定时器1的工作模式。
c: SBUF:串行通信数据的发送和接收缓冲器。
d: SCON:串行接口控制寄存器。
(四)、串行接口控制寄存器SCON
SM0 | SM1 | SM2 | REN | TB8 | RB8 | TI | RI |
串行口工作方式控制位 | 串行口工作方式控制位 | 多机通信控制位 | 允许接收控制位 | 发送的第9位控制位 | 接收的第9位控制位 | 发送中断标志 | 接收中断标志 |
1、SM0、SM1:串行口方式控制位
其串行口有4中工作方式,如表所示
SM0 | SM1 | 工作方式 |
0 | 0 | 方式0,移位寄存器方式,用于并行I/O扩展,不可用于通信 |
0 | 1 | 方式1,8位通用异步通信方式,比特率可变 |
1 | 0 | 方式2,9位通用异步通信方式,比特率可为fosc//64或fosc/32 |
1 | 1 | 方式3,9位通用异步通信方式,比特率可变 |
2、REN
REN=1,允许串行口接收数据;REN=0,禁止串行口接收数据.
(五)波特率的计算
- 串行口工作方式0时,波特率固定为fosc/12。
- 串行口工作方式2时,波特率计算公式为:波特率=2SMOD64×fosc
- 串行口工作方式1和3时, 波特率计算公式为: 波特率=2SMOD32×定时器T1的溢出速率=2SMOD32×fosc12×(2n-定时器、计数器1的初值x)
三、例题
在CT107D综合训练平台上,采用定时器中断实现一个简易时钟的操作,格式为yy-mm-dd;
其中S5具有清零功能,S4具有暂定和启动的功能。
#include "reg52.h"
sbit S4=P3^3;
sbit S5=P3^2;
unsigned char hour=0;
unsigned char minter=0;
unsigned char t_ms=0;
/**********数码管段码***********/
unsigned char code SMG_NoDot[18]=
{
0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,
0x80,0x90,0x88,0x80,0xc6,0xc0,0x86,0x8e,
0xbf,0x7f};
/********锁存器是选择**********/
void Init74HC138(unsigned char channel)
{
switch(channel)
{
case 4:
P2=(P2 & 0x1f) | 0x80;
break;
case 5:
P2=(P2 & 0x1f) | 0xa0;
break;
case 6:
P2=(P2 & 0x1f) | 0xc0;
break;
case 7:
P2=(P2 & 0x1f) | 0xe0;
break;
}
}
void DisplaySMG(unsigned int t)
{
while(t--);
}
/*****************显示单位数码管函数**********/
void DisplaySMG_Bit(unsigned char pos,unsigned char value)
{
Init74HC138(7);
P0=0xff; //消隐
Init74HC138(6);
P0=0X01<<pos; //选择数码管的位置
Init74HC138(7);
P0=value; //输出数码管显示内容
}
void DisplayTimer()
{
DisplaySMG_Bit(0,SMG_NoDot[hour/10]);
DisplaySMG(500);
DisplaySMG_Bit(1,SMG_NoDot[hour%10]);
DisplaySMG(500);
DisplaySMG_Bit(2,SMG_NoDot[16]);
DisplaySMG(500);
DisplaySMG_Bit(3,SMG_NoDot[minter/10]);
DisplaySMG(500);
DisplaySMG_Bit(4,SMG_NoDot[minter%10]);
DisplaySMG(500);
DisplaySMG_Bit(5,SMG_NoDot[16]);
DisplaySMG(500);
DisplaySMG_Bit(6,SMG_NoDot[t_ms/10]);
DisplaySMG(500);
DisplaySMG_Bit(7,SMG_NoDot[t_ms%10]);
DisplaySMG(500);
}
/*********定时器中断**********/
void InitTimer0()
{
TMOD=0x01;
TH0=(65535-50000)/256;
TL0=(65535-50000)%256;
ET0=1;
EA=1;
TR0=1;
}
void ServiceTerrupt() interrupt 1
{
TH0=(65535-50000)/256;
TL0=(65535-50000)%256;
t_ms++;
if(t_ms==60)
{
minter++;
t_ms=0;
if(minter==60)
{
hour++;
minter=0;
}
if(hour==24)
hour=0;
}
}
void Delay(unsigned int t)
{
while(t--);
}
void Scan_Keys()
{
if(S4==0) //暂停和启动
{
Delay(100);
if(S4==0)
{
TR0=~TR0;
while(S4==0)
{
DisplayTimer();
}
}
}
if(S5==0) //清零
{
Delay(100);
if(S5==0)
{
t_ms=0;
minter=0;
hour=0;
while(S5==0)
{
DisplayTimer();
}
}
}
}
void main()
{
InitTimer0();
while(1)
{
DisplayTimer();
Scan_Keys();
}
}