表4-3 C51支持的数据类型续表注:数据类型中加底色的部分为C51语言扩展的数据类型。C51语言中使用的数据类型包括C语言中标准的数据类型和C51语言扩展的数据类型。C51语言扩展的数据类型有位类型、可位寻址的位类型、特殊功能寄存器和16位特殊功能寄存器型等。另外,C51语言还支持由基本数据类型组成的数组、结构体、联合体和枚举类型等结构类型数据。......
2023-11-17
定时/计数器从电路上来讲是一个脉冲计数器,当计数脉冲来自单片机内部机器周期时,我们习惯上称其为定时器,而当计数脉冲来自单片机外部的输入信号时,则称其为计数器。8051系列单片机在片内集成了两个可编程的定时/计数器,分别称其为定时/计数器0(T0)和定时/计数器1(T1),二者都具有定时和计数的功能,其逻辑结构图如图7-6所示。
图7-6 定时器/计数器的逻辑结构
7.2.1 定时/计数器的结构
定时/计数器0和定时/计数器1都具有以下两种工作模式:
(1)计数器模式:在计数器工作模式时,两个定时/计数器可以分别对外部输入脉冲进行计数,其中T0使用P3.4引脚,T1使用P3.5引脚作为计数脉冲的输入端,一旦在输入端出现有效的下降沿,计数器的计数值会加1。
(2)定时器模式:在定时器工作模式时,两个定时/计数器可以分别对来自单片机内部的机器周期进行计数,每经过1个机器周期的时间,计数器的值都会加1,依据计数器所计脉冲的数量和机器周期的长度,就可以计算出时间。
8051系列单片机的定时/计数器0内部使用两个8位的寄存器来保存计数值,高8位的寄存器称为TH0,低8位的寄存器称为TL0,其结构如图7-7所示。
图7-7 定时/计数器0的结构
两个8位寄存器都是用来保存计数值的,其使用方法非常灵活。按照工作方式的不同,两个寄存器既可以组合在一起组成一个16位的寄存器,也可以分成两个8位的寄存器单独使用,定时/计数器0的工作方式由寄存器TMOD控制。可以将TH0和TL0形象地看成两个水杯,如图7-8所示。当其工作在16位模式时,可以共同用于盛水,而当其工作在8位模式时,可以分别盛水。当盛水量超过其最大容量时,水会溢出。
图7-8 定时/计数器0的结构示意
定时/计数器1的结构和定时/计数器0非常类似,也是由两个8位的寄存器构成,用来保存计数值,这两个寄存器分别称为TH1和TL1,具体结构如图7-9所示。
图7-9 定时/计数器1的结构
7.2.2 定时/计数器的工作原理
以定时/计数器0为例来说明定时/计数器是如何工作的。软件将定时/计数器0设置成16位定时器,定时/计数器0中的两个计数器TH0和TL0组合在一起用于保存计数值,其初值为0,如图7-10所示。
图7-10 定时/计数器的计数值为0
定时/计数器启动后,每隔一个机器周期,计数器的值都会加1,即当单片机使用的晶振频率为12 MHz时,每隔1 µs计数器的值就会加1,经过65 535 µs后,计数器的值会被加满,如图7-11所示。这时计数器只是加满的状态,并没有溢出,也不会引发中断。
图7-11 定时/计数器的计数值已满
再经过一个机器周期的时间后,计数器又加1并产生溢出,计数器又回到原来的初始状态,如图7-12所示。计数器产生计数溢出后,单片机会硬件置位TF0,并向CPU申请中断,如果该中断得到允许,单片机则开始执行中断服务程序。
图7-12 溢出后定时/计数器的值为空
从上面的例子我们可以看出,从开始计时到计数溢出,总计用了65 535+1 µs,即65 536 µs的时间。有了这个例子作为理论基础,我们就不难设计出产生50 ms计数溢出的定时器应用(晶振为12 MHz),具体做法如下:
用定时器计数的最大时间值减去需要设定的时间值,得到的数字即为定时器的初值,在计数器开始计数之前,把初值预先写入到定时器中,让定时器在这个初值的基础上开始计时,这样计数器从开始计数到计数溢出时正好是50 ms。
初值=计数器的最大计数值(65 536 µs)-目标时间(50 000 µs)=15 536 µs
初值计算好后,一个棘手的问题出现了:初值如何在两个8位的计数器寄存器之间进行分配呢?方法也很简单,就是将初值对256求模后,装入高8位的TH0中,而将初值对256求余后,装入低8位的TL0中,具体计算方法如下:
TH0=15536/256
TL0=15536%256
7.2.3 定时/计数器的控制寄存器
1.定时器控制寄存器TCON(Timer Control Register)
前面已介绍,此处略。
2.定时/计数器工作方式控制寄存器TMOD(Timer Mode Control Register)
TMOD寄存器用于选择定时/计数器的工作方式,其中高四位控制定时/计数器1,低四位控制定时/计数器0,不可以位寻址。
(1)bit7(GATE):定时/计数器1的门控位,即定时/计数器1开启方式选择位,用于设置定时/计数器1的启动方式。
① 0:仅当TCON寄存器的TR1=1时启动定时/计数器1。
② 1:由TCON寄存器的TR1=1和INT1引脚的高电平共同来启动定时/计数器1。
(2)bit6(C/T位):定时/计数器1模式选择位。
① 0:设定为定时器模式。定时/计数器1对来自单片机片内的机器周期进行计数,每个机器周期计数器的值都会加1。
② 1:设定为计数器模式。定时/计数器1对来自单片机引脚T1(P3.5)的脉冲信号进行计数。
(3)bit5、bit4(M1:M0)位:定时/计数器1工作方式选择位,具体设置见表7-2。
(4)bit3(GATE):定时/计数器0的门控位,即定时/计数器0开启方式选择位,用于设置定时/计数器0的启动方式。
① 0:仅当TCON寄存器的TR0=1时启动定时/计数器0。
② 1:由TCON寄存器的TR0=1和INT0引脚的高电平共同来启动定时/计数器0。
(5)bit2(C/T位):定时/计数器0模式选择位。
① 0:设定为定时器模式。定时/计数器0对来自单片机片内的机器周期进行计数,每个机器周期计数器的值都会加1。
② 1:设定为计数器模式。定时/计数器1对来自单片机引脚T0(P3.4)的脉冲信号进行计数。
(6)bit1、bit0(M1:M0位):定时/计数器0工作方式选择位,具体设置见表7-2。
表7-2 定时/计数器的工作方式
7.2.4 定时/计数器的配置
按照TMOD寄存器上M1、M0位的设置不同,定时/计数器可以工作在四种工作方式下:
1.方式0:13位定时/计数器
当M1:M0位的值为00时,定时/计数器被设定为工作方式0。在方式0下,定时/计数器0被设定成为一个13位的计数器,由TL0的低5位和TH0的全部8位构成,其所能装入的最大数值为213 = 8192。定时/计数器0在方式0下的配置方法如图7-13所示。
图7-13 定时/计数器0的工作方式0
同样,定时/计数器1在方式0时也被设定成为一个13位的计数器,由TL1的低5位和TH1的全部8位构成,具体的配置方法如图7-14所示。(www.chuimin.cn)
图7-14 定时/计数器1的工作方式0
2.方式1:16位定时/计数器
当M1:M0的值为01时,定时/计数器被设置为工作方式1。定时/计数器0在被设定为方式1时,成为一个16位的计数器,由TL0的8位和TH0的8位构成,其能装入的最大数值为216=65536。定时/计数器0在方式1下的配置方法如图7-15所示。
图7-15 定时/计数器0的工作方式1
定时/计数器1在被设定为方式1时,也成为一个16位的计数器,如图7-16所示。
图7-16 定时/计数器1的工作方式1
3.方式2:8位初值自动重装定时/计数器
当定时/计数器工作在方式0和方式1时,计数溢出后计数器的值清零,如需再次定时或计数,需要用软件的方法给定时器装入初值,这样不仅会影响定时的精度,也会给程序设计带来不便,而方式2的初值自动重装定时/计数器可以很好地解决这个问题。
当M1:M0位的值为10时,定时/计数器被设置为工作方式2。定时/计数器0在被设定为方式2时,TL0用作计数,而TH0用作常数缓冲器,用来保存计数器的初值。当TL0产生计数溢出后,硬件会自动将TH0中的初值调出并且装入TL0中,为下一次计数做好准备。定时/计数器0在工作方式2下的结构如图7-17所示。
图7-17 定时/计数器0的工作方式2
工作方式2可以省去用户使用软件反复重装初值的麻烦,只要在初始化定时器时一次性把初值分别装入TL0和TH0中即可,既简化了操作,又能提高计数的精度。在工作方式2下,由于TH0用于保存初值,计数的只有8位的TL0,所以计数的最大值仅为255。
工作方式2非常适合用于那些需要重复计数的应用中,例如:可以通过此方式产生固定频率的脉冲信号,甚至是当作串行数据通信的波特率发送器使用。定时/计数器1在设定为方式2时,原理与定时/计数器0相同,如图7-18所示。
图7-18 定时/计数器1的工作方式2
4.方式3:两个8位定时器
当M1:M0的值为9时,定时/计数器0被设置为工作方式3。定时/计数器1不能工作在方式3下,如果把定时/计数器1设置为工作方式3,它会停止运行。在工作方式3下,定时/计数器0被拆分成两个独立的8位计数器TL0和TH0。
其中TL0既可以作为计数器使用,也可以作为定时器使用,原定时/计数器0的各控制位和引脚全部归TL0使用,其功能和操作方法与方式0或方式1类似。而TH0就没有那么多“资源”可利用了,只能作为简单的定时器使用,而且由于定时/计数器0的控制位已被TL0占用,因此只能借用定时/计数器1的控制位TR1和TF1,也就是TH0计数溢出时会置位TF1,TR1则用于控制TH0的启动和停止。定时/计数器0在工作方式3下的结构如图7-19所示。
图7-19 定时/计数器0的工作方式3
工作方式3下,TL0既能作为定时器也能作为计数器使用,而TH0由于没有了输入引脚只能作定时器使用,在该方式下定时/计数器0可以构成两个定时器或者一个定时器和一个计数器。当使用8051单片机的串行口通信时,定时/计数器1被用作波特率发生器的时基,这时能完成定时/计数任务的只剩下定时/计数器0。如果此时恰好需要两个定时器,就可以把定时/计数器0设定为方式3,将其拆分成TH0和TL0两个定时器。
编程向导:定时/计数器的初始化。
定时/计数器的初始化设置可分为以下5个步骤:
(1)编程TMOD寄存器,设置定时/计数器的工作方式。
(2)计算定时/计数器的初值,并将其写入TH0和TL0或TH1和TL1中。
(3)如果使用中断,还需设置IE寄存器,开启总中断EA和相应的定时器中断ET0或ET1。
(4)如果使用中断优先级,还需设置中断优先级寄存器IP。
(5)置位TCON寄存器的控制位TR0或TR1位,启动定时器。
7.2.5 定时/计数器的编程应用
定时/计数器是单片机的学习重点,必须要很好地理解和掌握。下面通过两个实训来进一步加深对定时/计数器的理解。
基于定时器的编程应用可以使用中断法或查询法两种,其中中断法可以减轻CPU的查询负担。
【实训7.2】编写基于中断法的秒计时器。程序要实现的目的是用四位数码管显示时间,高两位显示秒,低两位分别显示十分之一秒和百分之一秒。电路图如图7-20所示。
图7-20 中断法秒计时器电路图
分析:该实训和任务6.1的编程有相似之处,任务6.1中使用不精确延时方式下通过按键控制来让数码管显示数字,本实训要实现精确计时,并且在按键控制下实现不同功能。任务6.1的显示函数是有参函数,主要是通过全局变量“keynum”来传递需要显示的值,但本程序的四个显示数字是不同进制的,个位和十位是十进制,而百位和千位是六十进制,如果采用任务6.1的数据处理方法显然是不行的,对百位数显示的数字是0~9,但要带小数点,所以在程序中显示段码要和0x80进行或运算,即P1=seg[baiwei]|0x80,满10进1到千位,千位能显示的数字是0~5,所以要对“keynum”的范围进行限制,程序中要求“keynum>=6000”就行重新计数。在定时中断程序中,根据题意设定一次中断定时10 ms,即10000 µs,在晶振频率为12 MHz时,一个机器周期是1 µs,定时10000 µs的定时器初值就是65536-10000,TH0=(65536-10000)/256,TL0=(65536-10000)%256,工作在16位定时板式下。
秒计时器代码清单:
以上代码经正确编译后下载到系统板中,程序运行后数码管显示时间值为“00.00”,按K1键计时器启动,按K2键计时器停止,按K3键清零,按K4键计时器会暂停。具体的运行状态如图7-21所示。
图7-21 秒计时器(显示和按键部分)
在以上的程序中,是通过定时器的中断产生时基信号驱动数码管显示时间的。在某些应用中,也可以不使用中断,仅使用查询标志位的方法来达到定时或计数的目的。
【实训7.3】基于查询标志位的定时器应用。
在图7-22的基础上,使用查询法得到时基信号,让流水灯演示二进制的累加过程,具体程序见代码清单。
图7-22 流水灯演进电路图
分析:让流水灯每秒变化一次,从D1变化到D8,模拟二进制累加过程,从低位开始累加。用查询方式使用定时器,第50 ms计数一次,计满20次就是1 s。要点亮D1,则P0.0为低电平,但sec=1时,二进制代码为00000001,如果直接用P0=sec,则D1不亮,而D2~D8亮,没有达到我们的设计意图;如果用P0=256-sec,这里P0=11111110,则可以达到设计意图。
二进制数字累加器代码清单:
在Proteus环境下让程序运行,流水灯会每隔1 s变化一次,演示二进制的累加过程。具体状态如图7-23所示。
图7-23 二进制数字累加器Proteus模拟
有关单片机原理与应用 基于C语言的文章
表4-3 C51支持的数据类型续表注:数据类型中加底色的部分为C51语言扩展的数据类型。C51语言中使用的数据类型包括C语言中标准的数据类型和C51语言扩展的数据类型。C51语言扩展的数据类型有位类型、可位寻址的位类型、特殊功能寄存器和16位特殊功能寄存器型等。另外,C51语言还支持由基本数据类型组成的数组、结构体、联合体和枚举类型等结构类型数据。......
2023-11-17
A.8 KBB.16 KBC.32 KBD.64 KB三、判断题1.8位二进制无符号数的大小范围是0~256。()2.CPU的时钟周期为振荡器频率的倒数。()4.计算机中机器码就是由若干位二进制数构成的。()5.51系列单片机的产品8051与8031的区别是:8031片内无ROM。()9.8位二进制数原码的大小范围是-127~+127。为什么在计算机系统中广泛使用二进制数?......
2023-11-17
项目2:输入一行字符,分别统计出其中英文字母、空格、数字和其他字符的个数。图3.15兔子问题输出结果根据以上的分析可以知道,循环次数可以为0,因此该程序是一个条件型循环,可以利用while语句编写程序。熟悉了循环结构在程序设计中的运用,循环结构语句包含了while语句、do…......
2023-11-18
使用查询标志位的方法通过串行口发送C语言的经典语句“hello World!”,在PC上运行串口调试助手软件接收此消息并在屏幕上显示出来。单击“打开串口”按钮,这时会发现在串口调试助手的接收区有“hello World!”图9-29 串口调试助手向单片机发送数字单片机接收到来自PC发送的信息后,用LED灯显示该数字的状态,系统板的具体状态如图9-30所示。......
2023-11-17
ISP即在系统可编程,用几根下载线就可以对单片机进行程序下载,无需编程器,也不用将单片机取下,因此称之为在系统可编程。目前国内常用的下载软件可分为STC官方软件和开发板自己开发的软件。官方STC下载软件的下载过程如图2-26所示。图2-26 STC官方下载软件界面选择开发板上单片机的型号,这里选择STC90C516。......
2023-11-17
溢出和比较匹配中断源。比较匹配时清除定时器,WGM01:0=2,TCNT0=OCR0时计数器清零。3)与T/C0相关的8位寄存器8位控制寄存器。8位计数寄存器。8位中断屏蔽寄存器。8位中断标志寄存器。Bit1-OCF0:输出比较标志0。外部事件计数器。2)T/C2的工作模式普通模式。TCNT2=OCR2时计数器清零,波形发生器的频率:变量N表示预分频因子。......
2023-06-26
TC0单次定时时间与系统时钟频率、预分频比及TCNT0初值密切相关,需要仔细考虑和计算,但向导程序可以很轻松地为我们解决这些问题。向导程序将为我们计算出合适的预分频比及定时器初值,并打开TC0中断,同时还给出了单次定时的误差。计数器溢出后本应自动从0开始计数,但在TC0中断服务程序中计数初值被更改为0x64,而且应该一进入中断服务程序立即被更改。......
2023-11-26
涉及乐曲编程时,就必须了解定时器/计数器的设置。一般作为定时器选用16位计数器,这时最大定时时间就是机器周期时间×65536。T/C=0为定时器方式,T/C=1为计数器方式。M1 M0是选择定时器/计数器工作模式位:定时控制寄存器其各位标志如下:MSB表示最高有效位,LSB表示最低有效位。......
2023-11-07
相关推荐