> 文档中心 > 【蓝桥杯】——定时器/计数器与串行口

【蓝桥杯】——定时器/计数器与串行口

目录

一、定时器/计数器

(一)什么是定时器/计数器

(二)、51单片机定时器/计数器的结构

1、控制寄存器TMOD

2、控制寄存器TCON

(三)定时器/计数器的编码思路

1、初始化函数

2、中断服务函数

二、51单片机串行口

(一)单片机串行的基本概念

(二)串行口结构

(三)、与串口相关的寄存器

(四)、串行接口控制寄存器SCON

(五)波特率的计算

三、例题


一、定时器/计数器

(一)什么是定时器/计数器

定时器/计数器,是一种可以对所接收到的信号进行响应,即对接收的内部时钟信号或外部输入信号进行计数,其呈现周期性的计数方式(有点类似于现实生活中时钟计数方式)。故定时器/计数器的最基本工作原理就是进行计数。

(二)、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的博客-CSDN博客

(三)定时器/计数器的编码思路

定时器/计数器的程序设计,通常包含两个函数:初始化函数中断服务函数

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:        TH1TL1:设置波特率参数。
   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,禁止串行口接收数据.

(五)波特率的计算

  1. 串行口工作方式0时,波特率固定为fosc/12。
  2. 串行口工作方式2时,波特率计算公式为:波特率=2SMOD64×fosc
  3. 串行口工作方式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();}}

ChineseCigarette