利用定时器T1写延时函数,实现动态数码管的扫描——基于正点原子A7开发板
总共有两个例子:
① 数码管动态扫描在主函数main()中进行;
② 数码管动态扫描在中断函数Timer1()中进行;
##:感觉这里的延时时间总是有一些暗含的bug,但是现在还未深究
对应的代码如下:
①对应的代码:
*利用T1中断实动态数码管控制,每隔1S切换一个数码管*/
/***************定时器T1的应用版本1***************/
/************要完成的任务放在中断程序中***********/
# include <reg52.h>
# include <math.h>
# include <intrins.h>
# include <string.h>
int LEDCtr[]={0x00,0x10,0x20,0x30,0x40,0x50,0x60,0x70}; //38译码器对应的8个通道,输出低电平
int LEDDisp[]={0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F}; //共阴极LED组成的数码管的引脚设置
int NumberLEDCtr = 0;
int NumberLEDDisp = 0;
void main()
{
P3 = LEDCtr[NumberLEDCtr];
P1 = LEDDisp[NumberLEDDisp];
TMOD = 0x10; //通过TMOD,设置定时器1为工作方式1
TH1 = (65536-50000) / 256; //定时器1对应的数据寄存器的高8位,定时时间为50000个机器周期
TL1 = (65536-50000) % 256; //定时器1对应的数据寄存器的低8位
EA = 1; //打开总中断开关
ET1 = 1; //打开T1中断开关
TF0 = 0; //清除TF0标志位
TR1 = 1; //启动定时器T1
//启动定时器后,定时器的数值开始增加,当数值溢出时就中断了,数值溢出后进入中断函数
//并不是TR=1之后就进入中断函数,TR=1是打开定时器了,开始计数直至数值溢出然后进入中断
while(1) //执行完TR1=1的指令后,程序就进入了while(1)中进行死循环
{
}
}
//数值每溢出一次,就进一次中断函数,每进一次中断函数就进行一次判断看LED是否要移位;
//static的理解:不重复赋值变量,在20次进入中断程序的过程中,static int NumberInterrupt = 0只进行了一次.
void Timer1() interrupt 3
{
static int NumberInterrupt = 0; //static声明可以保证变量在每次调用之后保持调用完时候的值
TH1 = (65536-50000) / 256;
TL1 = (65536-50000) % 256;
NumberInterrupt++;
if(NumberInterrupt==20) //判断是否已经进行了20次中断也就是中断时间总共1S
{
NumberInterrupt = 0;
NumberLEDCtr++;
NumberLEDDisp++;
if(NumberLEDCtr>7) //当LED的序号或者LED引脚设置超出范围,使其从头开始
NumberLEDCtr = 0;
if(NumberLEDDisp>7)
NumberLEDDisp = 0;
P3 = LEDCtr[NumberLEDCtr];
P1 = LEDDisp[NumberLEDDisp];
}
}
②对应的代码:
/***************定时器T1的应用版本2***************/
/*********要完成的任务放在主程序main()中*********/
# include <reg52.h>
# include <math.h>
# include <intrins.h>
# include <string.h>
int LEDCtr[]={0x00,0x10,0x20,0x30,0x40,0x50,0x60,0x70}; //38译码器对应的8个通道,输出低电平
int LEDDisp[]={0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F}; //共阴极LED组成的数码管的引脚设置
int NumberLEDCtr = 0;
int NumberLEDDisp = 0;
int NumberInterrupt = 0;
void main()
{
P3 = LEDCtr[NumberLEDCtr];
P1 = LEDDisp[NumberLEDDisp];
TMOD = 0x10; //通过TMOD,设置定时器1为工作方式1
TH1 = (65536-50000) / 256; //定时器1对应的数据寄存器的高8位,定时时间为50000个机器周期
TL1 = (65536-50000) % 256; //定时器1对应的数据寄存器的低8位
EA = 1; //打开总中断开关
ET1 = 1; //打开T1中断开关
TF0 = 0; //清除TF0标志位
TR1 = 1; //启动定时器T1
//启动定时器后,定时器的数值开始增加,当数值溢出时就中断了,数值溢出后进入中断函数
//并不是TR=1之后就进入中断函数,TR=1是打开定时器了,开始计数直至数值溢出然后进入中断
while(1) //执行完TR1=1的指令后,程序就进入了while(1)中进行死循环
{
if(NumberInterrupt==20) //判断是否已经进行了20次中断也就是中断时间总共1S
{
NumberInterrupt = 0;
NumberLEDCtr++;
NumberLEDDisp++;
if(NumberLEDCtr>7) //当LED的序号或者LED引脚设置超出范围,使其从头开始
NumberLEDCtr = 0;
if(NumberLEDDisp>7)
NumberLEDDisp = 0;
P3 = LEDCtr[NumberLEDCtr];
P1 = LEDDisp[NumberLEDDisp];
}
}
}
//数值每溢出一次,就进一次中断函数,每进一次中断函数就进行一次判断看LED是否要移位;
void Timer1() interrupt 3
{
TH1 = (65536-50000) / 256;
TL1 = (65536-50000) % 256;
NumberInterrupt++;
}