文章目录
- 一、定时器介绍
- 二、定时器的应用
- 2.1 定时功能
- ❗注意事项!
- ❗什么是1T和12T
- 2.2 计数功能
- ❗注意点
- 三、利用定时器计数功能实现555频率测量
一、定时器介绍
在没有钟表的时候,定时的方式通过有一注香的时间,或者一桶水的时间。前者烧香不断减少是减法,后者滴水不断增加是加法。
定时/计数器,是一种能够对内部时钟信号或外部输入信号进行计数,当计数值达到设定要求时,向CPU提 出中断处理请求,从而实现定时或者计数功能的外设。定时/计数器的最基本工作原理是进行计数。作为定时器时,计数信号的来源选择周期性的内部时钟脉冲;用作计数器时,计数信号的来源选择非周期性的外部输入信号。
不管是定时器还是计数器,本质上都是计数器。
二、定时器的应用
定时器有两个功能,分别是定时和计数功能,定时是对内部时钟而计数是对外部时钟。
2.1 定时功能
举个例子,比如我想每隔2ms实现做某一件事,那么我们就在初始化的时候设置定时时长为2ms就可以。比赛的时候不推荐大家自己算TLx和THx的值,直接用STC烧录工具就可以直接实现,顺带着帮你把中断服务函数格式都写了。
1.系统时钟频率为12Mhz,看板子最左侧的晶振。
2.设置时间单位为ms
3.定时器输入时钟12分频(12T)
4.使能定时器中断
❗注意事项!
用STC软件生成的初始化代码中只开启了定时器中断,并没有开启总中断,所以需要我们在调用Timer0_Init()后添加一行代码(EA=1;),或者直接在Timer0_Init()中添加EA=1也行。
此外AUXR寄存器在reg52.h中没有定义,所以需要自己定义一下,或者将reg52.h改为stc15f2k60s2.h虽然比较长,但是多写几遍就记住了。
❗什么是1T和12T
在51中,1T模式是指每一个系统基本时钟执行1个动作,12T指每12个系统基本时钟执行1个动作。IAP12f2k60s2是工作在1T模式,所以它的运行速度比stc89c51\52快12倍。我们在定时器初始化中设置AUXR为12T并不会改变系统指令的运行速度,它只是改变了定时器输入信号,将输入信号进行12分频。
为什么选择12T,因为这样定时器就可以计数更长的时间,比1T模式下多12倍呢!
#include <stc15f2k60s2.h> // AUXR寄存器需要用到这个头文件void Timer0_Isr(void) interrupt 1
{
}void Timer0_Init(void) //2ms@12.000MHz
{AUXR &= 0x7F; //Timer clock is 12T mode,不会改变系统运行速度TMOD &= 0xF0; //Set timer work modeTL0 = 0x30; //Initial timer valueTH0 = 0xF8; //Initial timer valueTF0 = 0; //Clear TF0 flagTR0 = 1; //Timer0 start runET0 = 1; //Enable timer0 interruptEA=1; // 开启总中断
}
2.2 计数功能
一样的我们利用软件生成初始化代码,在此基础上做一些修改就可以了。
❗注意点
1.开发板上只将定时器0的时钟输入引脚拉了出来,所以只能使用定时器0来实现外部时钟计数。
2.要使定时器的输入信号不分频,也就是设置为1T模式
3.切记不能设置成为自动重转载模式!!!
4.修改TMOD让定时器输入信号为外部信号
前面三点在烧录软件中操作,第四点在keil中改写。
根据寄存器说明,将生成代码中的
TMOD |= 0x01;
改为TMOD |= 0x05;
三、利用定时器计数功能实现555频率测量
可以直接复制到main.c中直接用。
#include <stc15f2k60s2.h>
#include <intrins.h>
unsigned char count_t=0;
unsigned int count_f=0;
unsigned int last_f=0;
unsigned char code dat[]={0xc0, 0xf9, 0xa4, 0xb0, 0x99,0x92, 0x82, 0xf8, 0x80, 0x90,0x88,0x80,0xc6,0xc0,0x86,0x8e,0xbf,0x7f};void Delay()
{unsigned char i, j;_nop_();_nop_();i = 22;j = 128;do{while (--j);} while (--i);
}void selectHC573(unsigned char num)
{switch(num){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;case 0:P2=(P2 & 0x1f) | 0x00;break;}
}void system_Init()
{selectHC573(5);P0=0x00;selectHC573(0);
}void display_SMG_Bit(unsigned char dat, unsigned pos)
{/*消影法2*/P0=0xff;selectHC573(7);selectHC573(0);P0=0x01<<(pos-1);selectHC573(6);selectHC573(0);P0=dat;selectHC573(7);selectHC573(0);
}void display_D_SMG(unsigned int dat1)
{ display_SMG_Bit(dat[15],1);Delay();display_SMG_Bit(0xff,2);Delay();display_SMG_Bit(0xff,3);Delay();if(dat1>9999){display_SMG_Bit(dat[dat1/10000],4);Delay();}if(dat1>999){display_SMG_Bit(dat[dat1/1000%10],5);Delay();}if(dat1>99){display_SMG_Bit(dat[dat1/100%10],6);Delay();}if(dat1>9){display_SMG_Bit(dat[dat1 / 10 % 10],7);Delay();}display_SMG_Bit(dat[dat1 % 10],8);Delay();
}void Timer1_Isr(void) interrupt 3
{count_t++;if(count_t==99){count_t=0;count_f=TH0;count_f=(count_f<<8)|TL0;last_f=count_f;TL0=0;TH0=0;}
}void Timer0_Init(void) //1ms@12.000MHz
{AUXR |= 0x80; //imer clock is 1T modeTMOD &= 0xF0; //Set timer work modeTMOD |= 0x05; //Set timer work modeTL0 = 0x00; //Initial timer valueTH0 = 0x00; //Initial timer valueTF0 = 0; //Clear TF0 flagTR0 = 1; //Timer0 start run
}void Timer1_Init(void) //10ms@12.000MHz
{AUXR &= 0xBF; //Timer clock is 12T modeTMOD &= 0x0F; //Set timer work modeTL1 = 0xF0; //Initial timer valueTH1 = 0xD8; //Initial timer valueTF1 = 0; //Clear TF1 flagTR1 = 1; //Timer1 start runET1 = 1; //Enable timer1 interruptEA=1;
}void main()
{system_Init();Timer0_Init();Timer1_Init();//开启总中断while(1){display_D_SMG(last_f);}
}