13.2.5 定时器/计数器仿真
51系列单片机具有两个定时器/计数器T0和T1,对于52系列单片机还包含额外的定时器/计数器T2。这里以定时器/计数器T0、T1和T2为例,介绍定时器/计数器的仿真操作。
1.定时器/计数器T0和T1的仿真界面
这里以AT89S52单片机为例进行介绍,其他兼容单片机均类似。在KeilµVision3集成开发环境中,定时器/计数器T0和T1的仿真界面,分别如图13.30和图13.31所示。由于T0和T1的结构和功能类似,因此定时器/计数器T0和T1具有相同的仿真界面。
图 13.30 定时器/计数器T0的仿真界面
图 13.31 定时器/计数器T1的仿真界面
在定时器/计数器的仿真界面上,实时显示了该定时器/计数器的工作模式、寄存器值等。下面分别进行介绍。
在仿真界面中,第一个下拉列表框中用于选择定时器/计数器的工作模式,包括如下4个选项。
❑“0:13 Bit Timer/Counter”:定时器/计数器T0或T1的工作模式0,为13位计数器。
❑“1:16 Bit Timer/Counter”:定时器/计数器T0或T1的工作模式1,为16位计数器。
❑“2:8 Bit auto-reload”:定时器/计数器T0或T1的工作模式2,为自动重新装入的8位计数器。
❑“3:Two 8 Bit Timer/Cnt”:定时器/计数器T0的工作模式3,为两个相互独立的8位计数器。而对于定时器/计数器T1,则没有该选项,只有一项为“3:Disabled”,表示该工作模式无效。
在仿真界面中,第二个下拉列表框,用于选择定时方式还是计数方式,包括如下两个选项。
❑“Timer”:表示定时器/计数器T0或T1工作于定时方式。
❑“Counter”:表示该定时器/计数器T0或T1工作于计数方式。
在仿真界面中,同样显示了定时器/计数器相关的寄存器区,包括如下几项。
❑“TCON”:定时器/计数器的中断控制寄存器TCON的值。
❑“TMOD”:定时器/计数器的方式控制寄存器TMOD的值。
❑“TH0”或“TH1”:定时器/计数器T0的TH0值,或者定时器/计数器T1的TH1的值。
❑“TL0”或“TL1”:定时器/计数器T0的TL0值,或者定时器/计数器T1的TL1的值。
❑“T0 Pin”或“T1 Pin”:在定时器/计数器的计数方式中,用作计数脉冲的外部输入引脚。其中,P3.4引脚对应T0,P3.5引脚对应T1。
在仿真界面中,同样显示了定时器/计数器相关的控制标志位,包括如下几项。
❑“TF0”或“TF1”:定时器/计数器T0或T1的溢出标志位。
❑“TR0”或“TR1”:定时器/计数器T0或T1的启/停控制位。
❑“GATE”:定时器/计数器的门控制位。
❑“INT 0#”或“INT 1#”:定时器/计数器T0相关的引脚,或T1相关的
引脚。
另外,“Status”显示了定时器/计数器T0或T1的运行状态。如果显示为“Run”,表示正在运行;如果显示为“Stop”,表示没有运行。
在程序仿真执行的时候,定时器/计数器的寄存器状态等均显示在仿真界面上。同时,用户也可以根据需要手工更改仿真界面上的各个值,来测试程序的运行情况。
2.定时器/计数器T0的仿真
这里以定时器/计数器T1的工作模式1为例,介绍定时器/计数器的仿真操作。假设采用AT89S52单片机,外接12MHz晶振,需要在P1.2端口输出频率为50Hz的方波,即周期为20ms。此时可以采用定时器T1工作于模式1,即16位定时器模式。使定时器产生10ms的定时,通过定时中断来产生P1.2端口的方波信号输出。
(1)在KeilµVision3集成开发环境中,新建一个工程并选择Atmel公司的AT89S52单片机。同时,在设置单片机外接振荡器的频率为12MHz。
(2)选择“File”→“New”命令,新建一个程序文件,并保存为*.C文件,在其中输入如下程序源代码。
include<reg51.h>//头文件
sbit Wave=P1^2;//位定义
void T1ISR(void)interrupt 3//定时器T1中断响应
{
Wave=~Wave;//反向
TL1=0x0F0;//重置计数初值
TH1=0x0D8;
}
void main(void)//主函数
{
Wave=0;//初始化P1^2=0
TMOD=0x10;//设置定时器T1为模式1
TL1=0x0F0;//初始化
TH1=0x0D8;
TR1=1;
ET1=1;
EA=1;//开中断
while(1)//主循环
{
}
}
在该程序中,将P1.2引脚定义为位变量Wave。在main主函数中首先将P1.2引脚赋为0,并初始化定时器T1,接着打开相应的中断。在while主循环中不进行任何操作,而是等待定时器的中断。当定时器溢出时将触发中断,程序进入中断服务例程T1ISR,此时首先取反P1.2引脚,然后重置计数初值进入下一次定时。
(3)选择“Debug”→“Start/Stop Debug Session”命令,进入程序仿真调试环境。
(4)选择“Peripherals”→“Timer”→“Timer 1”命令,打开定时器/计数器T1的仿真界面。
(5)选择“Peripherals”→“I/O-Ports”→“Port 1”命令,打开并行I/O端口P1的仿真界面。
(6)选择“Debug”→“Run”命令,程序便开始仿真执行。此时,定时器/计数器T1的仿真
运行如图13.32所示,其中显示了T1为16位定时器模式,状态为正在运行,各个寄存器的值随程序的运行而更新。P1端口的仿真运行,如图13.33所示,从中可以看到P1.2引脚的电平循环改变。
图 13.32 定时器/计数器T1的仿真界面
图 13.33 P1端口的仿真界面
(7)选择“View”→“Logic Analyzer Window”命令,打开“Logic Analyzer”窗口。
(8)在“Logic Analyzer”窗口,单击“Setup……”按钮,打开“Setup Logic Analyzer”对话框,如图13.34所示。在“Current Logic Analyzer Signals:”中输入变量Wave。
(9)单击“Close”按钮,关闭“Setup Logic Analyzer”对话框。此时,在“Logic Analyzer”窗口便可以看到Wave变量,即P1.2引脚上的波形输出,如图13.35所示。从中可以看出,通过定时器/计数器T1使该程序实现了P1.2引脚的波形输出。
图 13.34 “Setup Logic Analyzer”对话框
图 13.35 P1.2引脚的仿真波形
(10)当仿真完毕后,选择“Debug”→“Stop Running”命令,便可以结束程序的仿真运行。
(11)选择“Debug”→“Start/Stop Debug Session”命令,可以退出程序仿真调试模式。
3.定时器/计数器T2的仿真界面
AT89S52单片机属于52子系列单片机,除了包含定时器/计数器T0和T1外,该系列单片机还包含一个定时器/计数器T2。在KeilµVision3集成开发
环境中同样提供了T2的仿真支持,定时器/计数器T2的仿真界面,如图13.36所示。
在定时器/计数器T2的仿真界面上,“Mode”用来实时显示定时器/计数器T2的工作方式,显示内容随寄存器的设置而不同。其他部分则显示了相关寄存器的值,包括如下所示的几项。
图 13.36 定时器/计数器T2的仿真界面
❑“Mode”:用来实时显示定时器/计数器T2的工作方式,显示内容随寄存器的设置而不同。
❑“T2CON”:定时器/计数器T2的控制寄存器。
❑“T2MOD”:定时器/计数器T2的启动及加/减计数控制器。
❑“T2”:定时器/计数器T2的值。
❑“RCAP2”:捕获模式下的定时器/计数器值。
❑“TR2”:定时器/计数器T2的溢出中断请求标志位。
❑“C/T2#”:定时器/计数器T2的定时或计数功能选择标志位。
❑“CP/RL2#”:定时器/计数器T2的捕获或重新再装入选择标志位。
❑“EXEN2”:定时器/计数器T2的外部触发允许标志位。
❑“TCLK”:定时器/计数器T2的串行口发送时钟标志位。
❑“RCLK”:定时器/计数器T2的串行口接收时钟标志位。
❑“T2OE”:定时器/计数器T2的输出控制位。
❑“DCEN”:定时器/计数器T2的加1计数/减1计数标志位。
另外,在定时器/计数器T2的仿真界面上,“I/O”区域用于设置并实时显示定时器/计数器T2相关的I/O引脚,包括如下所示的几项。
❑“T2EX”:对应P1.1引脚,不同模式下有不同的含义。
❑“T2 Pin”:对应P1.0引脚,不同模式下有不同的含义。
在定时器/计数器T2的仿真界面上,“IRQ”区域用于设置并实时显示定时器/计数器T2的中断,包括如下几项。
❑“TF2”:定时器/计数器T2的溢出中断请求标志位。
❑“EXF2”:定时器/计数器2的外部中断请求标志位。
在程序仿真执行时,定时器/计数器T2的仿真界面上除了显示工作状态以及各个寄存器的值以外,用户还可以根据需要手工更改这些值来测试程序的运行情况。
4.定时器/计数器T2的仿真
这里以定时器/计数器T2的重新再装入模式为例,介绍T2的仿真。假设使用AT89S52单片机,外接12MHz晶振,使用定时器T2使P1.0引脚每个1秒改变一下输出电平,即输出0.5Hz的方波脉冲。下面具体介绍C51程序及其仿真操作。
(1)在KeilµVision3集成开发环境中,新建一个工程并选择Atmel公司的AT89S52单片机。同时,在设置单片机外接振荡器的频率为12MHz。
(2)选择“File”→“New”命令,新建一个程序文件,并保存为*.C文件,在其中输入如下的程序源代码。
include“reg52.h”//头文件
define uint unsigned int
define uchar unsigned char
sbit P1_0=P1^0;//定义位变量
void Timer2_Server(void)interrupt 5
{
static uint Timer2_Server_Count;//定义静态变量,计数T2定时器的溢出次数
TF2=0;//T2定时器发生溢出中断时清除溢出标记
Timer2_Server_Count++;
if(Timer2_Server_Count==16)//T2定时器的预装载值为0x0BDC,溢出16次就是1秒
{
Timer2_Server_Count=0;
P1_0=~P1_0;//P1_0反向
}
}
void main(void)//主函数
{
P1_0=1;//P1_0置为低电平
TH2=0x0B;//T2定时器赋预装载值,溢出16次就是1秒
TL2=0xDC;
RCAP2H=0x0B;//重载值
RCAP2L=0xDC;
ET2=1;//允许T2定时器中断
EA=1;//打开总中断
TR2=1;//启动T2定时器
while(1)//主循环
{
}
}
由于T2定时器是一个16位定时器,最长的溢出时间也就几十毫秒。因此在该程序中,为T2赋初值,使T2溢出16次的时间为1秒。程序中设置定时器T2,并打开相应的中断,在中断服务例程中实现P1.0端口的方波输出。
(3)选择“Debug”→“Start/Stop Debug Session”命令,进入程序仿真调试环境。
(4)选择“Peripherals”→“Timer”→“Timer 2”命令,打开定时器/计数器T2的仿真界面。
(5)选择“Peripherals”→“I/O-Ports”→“Port 1”命令,打开并行I/O端口P1的仿真界面。
(6)选择“Debug”→“Run”命令,程序便开始仿真执行。此时,定时器/计数器T2的仿真运行如图13.37所示,其中显示了T2为16位定时器模式,状态为正在运行,各个寄存器的值随程序的运行而更新。P1端口的仿真运行,如图13.38所示,从中可以看到P1.0引脚的电平循环改变。
图 13.37 定时器/计数器T2的仿真界面
图 13.38 P1端口的仿真界面
(7)选择“View”→“Logic Analyzer Window”命令,打开“Logic Analyzer”窗口。
(8)在“Logic Analyzer”窗口,单击“Setup……”按钮,打开“Setup Logic Analyzer”对话框,如图13.39所示。在“Current Logic Analyzer Signals:”文本框中输入变量P1_0。
(9)单击“Close”按钮,关闭“Setup Logic Analyzer”对话框。此时,在“Logic Analyzer”窗口便可以看到P1_0变量,即P1.0引脚上的波形输出,如图13.40所示。从中可以看出,通过定时器/计数器T2使该程序实现了P1.0引脚的波形输出。
图 13.39 “Setup Logic Analyzer”对话框
图 13.40 P1.0引脚的仿真波形
(10)当仿真完毕后,选择“Debug”→“Stop Running”命令,便可以结束程序的仿真运行。
(11)选择“Debug”→“Start/Stop Debug Session”命令,可以退出程序仿真调试模式。