1、实验六 使用单片机定时器的数码管动态显示驱动实验 一、 实验目的 l 掌握数码管动态驱动方式的工作原理; l 掌握单片机定时器中断服务程序的编写方法; l 掌握基于单片机定时器中断调度方式的数码管动态显示驱动程序的编写方法。 二、 实验要求 l 单片机通过P1 端口连接数码管组的字型码(段码)控制端; l 单片机通过P0 端口连接数码管组的位置码(位码)控制端; l 根据电路连接方式和数码管驱动方式,设计显示0~9,A~F 的字型码; l 设置8 个字节的显示缓冲区,通过数码管动态显示驱动的方法,将显示缓冲区内容显示在8 位数码管上。 三、 实验设备 l 硬件:PC
2、机,nKDE-51 单片机实验教学系统; l 软件:Keil C51 集成开发环境,FlashMagic 单片机程序烧写软件。 四、 实验原理 1. MCS-51 定时器/计数器的结构及功能 MCS-51 单片机内部提供两个16 位定时器/计数器,分别是定时器/计数器0(T0)和定时器/计数器1(T1)。虽然它们被称为定时器/计数器,但本质上它们都计数器。当选择单片机的机器周期作为计数对象时,由于机器周期出现的频率和晶振频率之间的关系是固定的,对固定频率的信号进行计数实际上就是定时器;当对通过T0 引脚(P3.4)或T1 引脚(P3.5)引入的外部脉冲作为计数对象时,它们是计数器。
3、 图6-1 MCS-51 单片机定时器/计数器0、1 结构框图 定时器/计数器的基本结构如图6-1 所示。它是由6 个特殊功能寄存器组成的。其中,定时器T0 由TH0 和TL0 两个8 位计数器组成;定时器T1 由TH1 和TL1 两个8 位计数器组成。 当它们用做定时器时,其计数脉冲来源于晶振时钟输出信号的12 分频,即每个机器周期使计数器加1,所以说定时器本质上是针对机器周期的计数器,一旦单片机的晶振频率选定,机器周期也就随之确定,从而使对机器周期的计数转换为对确定时间的计数。例如,当单片机晶振频率选择为12MHz 时,一个机器周期就是1μs,即计数器对机器周期每计数一次,就是1μ
4、s,具体的定时时长可通过简单的换算变换成相应的计数值。 当它们用做计数器时,只要T0 或T1 的引脚上有一个从1 到0 的负跳变,相应的计数器就加1。由于单片机在每个机器周期的S5P2 状态对T0 及T1 引脚的电平进行一次采样,因此单片机需要用两个机器周期来识别一次负跳变,所以单片机计数器的最高计数频率为晶振频率的1/24。 不管是用作定时器还是计数器,T0 和T1 的计数器都只能递增计数,当16 位计数器的计数值增加到0FFFFH 时,下一次计数脉冲的到达将会使计数器的值回到0000H,计数器产生溢出信号,置位相应的标志位,并向主机申请中断。由于递增计数的特性,当设定计数次数时,必须以
5、计数器的计数量程减去计数次数作为初值赋给计数器作为计数初值,才能在设定的计数次数后置位相应的标志位,向CPU 申请中断。 2. 定时器/计数器的控制与状态寄存器 T0 和T1 的16 位加1 计数器由两个8 位特殊功能寄存器THx 和TLx(x=0 或1)组成,它们可被软件编程设置为不同的组合状态(13 位、16 位或两个独立的8 位计数器),从而形成定时器/计数器的4 种工作方式,这些工作方式的选择及控制都由两个特殊功能寄存器TMOD 和TCON 中的内容来决定。 (1) 工作方式控制寄存器TMOD TMOD 寄存器用于定义定时器/计数器0 和1 的操作模式及选择工作方式,其格式为:
6、 位宽8 位的TMOD 寄存器分成高低两部分,各4 位,分别用于定义T1 和T0 的工作模式及选择工作方式,对应位的功能相同。各位的定义及功能说明如下。 l M1M0:工作模式选择位 M1M0 两位共有四种组合,可定义四种定时器/计数器的工作方式,分别为13 位、16 位定时器/计数器、具有自动重装的8 位定时器/计数器和将T0 分成两个8 位计数器四种。具体工作方式选择如表6-1 所示。 表6-1 M1、M0 和定时器/计数器工作方式的对应关系 l 功能选择位C/T 当C/=0 时为选择定时(Timer)功能,即定时器/计数器的内部计数器对单片机的机器周期进行计数,从而
7、实现定时功能。 当C/=1 时为选择计数(Counter)功能,即定时器/计数器的内部计数器对单片机的T0 或T1引脚引入的外部脉冲进行计数。 l GATE:门控位 当GATE=0 时,TCON 寄存器中的TR0 或TR1(定时器/计数器运行控制位)为1 则可立即启动定时器/计数器0 或1; 当GATE=1 时,不但TR0 或TR1 要为1,而且单片机的或引脚的输入也为高电平时,才能启动定时器/计数器0 或1。 (2) 定时器控制寄存器TCON TCON 寄存器用于控制定时器/计数器0 和1 的启动和停止,还包括溢出标志及中断控制标志等。它的字节地址为88H,可以位寻址。TCON
8、的高4 位存放定时器/计数器的运行控制位和溢出标志位,其余4 位为外部中断的触发方式控制位和中断请求标志,在上一个实验中已做过介绍,此处不再赘述。 TCON 寄存器的地址及各功能位分布如下: TF1:定时器/计数器1(T1)的溢出标志。当T1 计数溢出时,由硬件将此位置1。TF1 可供程序查询,同时也是定时器/计数器1 的中断请求标志。如果中断系统被设置允许该中断,则当CPU响应中断,进入中断服务程序后,由硬件将TF1 自动清0,不需要软件处理。 TF0:定时器/计数器0(T0)的溢出标志。其功能和操作方式同TF1。 TR1:定时器/计数器1(T1)的运行控制位。通过软件置1 或清0
9、来启动或停止T1 内部计数器的计数。 TR0:定时器/计数器0(T0)的运行控制位。其功能和操作方式同TR0。 单片机复位后,TCON 寄存器的所有位均为0。 3. MCS-51 定时器/计数器的工作方式 MCS-51 的定时器/计数器0(T0)有方式0~方式3 共4 种工作方式,定时器/计数器1(T1)则只有方式0~方式2 共3 种工作方式。因为方式3 很少使用,因此本节仅介绍工作方式0~2。 (1) 定时器/计数器工作方式0 当TMOD 中的M1M0 为00 时,定时器/计数器被选为工作方式0,13 位计数器,其逻辑结构如图6-2 所示。 图6-2 MCS-51 定时器/
10、计数器工作方式0 逻辑结构 在工作方式0 下,16 位计数器THx 和TLx 一共只使用了13 位,由THx 的8 位和TLx 的低5位组成,即TLx 的5 位计数溢出后,THx 的计数加1,直到全部的13 位计数值为全1 后,下一个计数脉冲的到达将使TFx 置位为1,并向CPU 申请中断。程序可以通过查询TFx 是否为1 来判断定时器/计数器的计数是否溢出,也可以通过开放相应的中断来处理定时器/计数器计数溢出事件。 当C/=0 时,为定时工作方式,计数源选择开关连接到振荡器的12 分频输出,计数器对机器周期脉冲计数。其定时时间为: (213-初值)×机器周期时长 从上式可以看出,初值
11、越大,计数器离溢出越近,定时时间越短,当计数器初值为0 时定时时间最长。如果系统晶振频率为12MHz,则每个机器周期时长为1μs,则在定时器方式0 下最长的定时时间为(213-0)×1μs=8.192ms。 当C/=1 时,为计数工作方式,计数源选择开关连接到单片机的T0 引脚(P3.4)或者T1 引脚(P3.5),计数器对T0 引脚或T1 引脚引入的脉冲信号进行计数,每当外部信号发生一次负跳变(即从高电平到低电平的下降边沿),计数器加1。 不论定时器/计数器工作在定时方式还是计数方式,GATE(门控位)都控制着定时器/计数器的运行条件: 当GATE=0 时,图6-2中的或门输出始终为1
12、在这种情况下,与门的输出(计数控制信号)由TRx 决定,定时器/计数器不受输入电平的影响,只要TRx=1,对应的定时器/计数器就允许计数,TRx=0 则停止计数。 当GATE=1 时,图6-2 中与门的输出(计数控制信号)由的输入电平和TRx 共同决定,只有当为高电平且TRx=1 这两个条件都满足时,定时器/计数器才开始计数,否则定时器/计数器停止计数。 (2) 定时器/计数器工作方式1 当TMOD 中的M1M0 为01 时,定时器/计数器被选为工作方式1,16 位计数器,其逻辑结构如图6-2 所示。 图6-2 MCS-51 定时器/计数器工作方式1 逻辑结构 定时器/计数器方
13、式1 和方式0 的工作原理完全相同,此处不再赘述。它们的差别仅在于计数器的位数不同:方式0 为13 位计数器,而方式1 则将THx 和TLx 合为一个16 位的计数器。因此,在作为定时器使用时,方式1 的最大定时时间为: (216-初值)×机器周期时长 当晶振频率为12MHz,则定时方式1 最长的定时时间为(216-0)×1μs=65.536ms。 (3) 定时器/计数器工作方式2 当TMOD 中的M1M0 为10 时,定时器/计数器被选为工作方式2,具有自动重装功能的8 位计数器,其逻辑结构如图6-3 所示。 图6-3 MCS-51 定时器/计数器工作方式2 逻辑结构 在方式
14、2 中,TLx 作为8 位内部计数器,根据C/的值选择对机器周期或外部脉冲进行计数,THx 则作为重装初值寄存器,在TLx 计数溢出置位TFx 标志的同时,由硬件控制直接将重装初值装入TLx,开始新一轮的计数,如此不断循环。当用作定时器时,这种方式下一次定时时间为: (28-初值)×机器周期时长 方式2 和方式0、1 最大的差别就是计数器的初值是由硬件控制自动装入的。在方式0、1 下一旦计数器溢出,就表示计数器已回0,如果要按照原先的初值重新计数,就需要通过软件重装计数器初值,由于重装操作需要执行一定数量的代码,因此影响了定时时间的精度。方式2 则采用硬件控制重装初值,完全避免了重装操作对
15、定时精度的影响,适用于需要产生高精度定时间隔的场合,常用作单片机串行口的波特率发生器。 数码管的动态显示是通过程序在运行过程中对每一位数码管轮流驱动,交替点亮实现的。动态显示的方法利用了人眼视觉暂留的原理,只要各数码管轮流点亮的间隔小于人眼视觉暂留的时间(约40ms),人们就会觉得数码管是一直点亮的。 综上所述,实验系统的数码管共有8 个(电路连接情况如图3-8 所示),为了满足每个数码管两次点亮间隔不超过40ms 的条件,每个数码管的点亮时间应不大于5ms。本实验设置每个数码管点亮时间为5ms。 五、 实验过程 1. 电路连接 将基本IO 板上的J1 和CPU 板上单片机的P0(J
16、1 或J5)相连、基本IO 板上的J2 和CPU 板上单片机的P1(J2 或J6)相连即可。注意连接时的顺序,单片机端口的低位和A 段相连。
2. 程序设计
#include
17、0x82,0xF8, 0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E }; // 定义字型码,并指定存放在程序存储器中 void T0ISR(void) interrupt 1 // 定时器0 的中断服务程序(中断号为1) { TH0 = (65536-(OSC/12/FPS))/256; TL0 = (65536-(OSC/12/FPS))%256; // 重置定时常数 P1 = 0xff; // 先关闭显示,消隐处理 P0 = pos; // 输出位置码,进行位驱动。此时该位置数码管显示字符 P1 = CharCode[D
18、isplayBuf[i]]; // 根据显示缓冲区中的数据查找字型码,并进行段驱动 pos >>= 1; // 右移1 位,得到下次显示的位置码 i ++; // 位置编号+1 if(i == 8) // 如果8 位数据都显示完,则复位各变量 { // 准备进行下一次8 位显示的循环 i = 0; pos = 0x80; } } void main(void) { for(i=0;i<8;i++) DisplayBuf[i] = i;// 初始化显示缓冲区 P0 = 0; P1 = 0xff; // 先关闭显示 i = 0; pos =
19、 0x80; // 位置控制变量初始化 TMOD = 0x01; // GATE=0,C/#T=0,Mode=1,T0 选择定时器模式1 TH0 = (65536-(OSC/12/FPS))/256; TL0 = (65536-(OSC/12/FPS))%256; // 设置定时常数 ET0 = 1; // 允许T0 中断 EA = 1; // 总中断允许 TR0 = 1; // T0 开始运行 while(1); // 在此处循环。显示过程完全由T0 的ISR 处理 } 根据实验要求,设计代码如下: 程序中在设置定时器初值时,为了增强可读性,定义了宏FPS,即每秒中断次数,此时应特别注意,要确保在当前晶振频率下,OSC/12/FPS 能够得到整数,否则将会引起定时误差。例如在本例中,晶振频率为11.0592MHz,FPS 定义为200 时,可整除得到定时常数为4608。 3. 验证结果 在Keil 中建立新工程,将上述程序代码加入工程,编译链接后,将生成的HEX 文件烧写到单片机中,验证运行结果和设计要求是否相符。