定时器也可以做为计数器,其实他们本质上的原理是一样的,定时器是计数单片机内部的系统时钟,每1个或者12个时钟脉冲,就加一。计数器则是记录外部输入脉冲。
1. 定时器0有四种工作模式,这里使用的是定时器0的16位可重新装载模式,16位(0x0000~0xFFFF)即可以从0数到65535共计65536个,区别8位(0x00~0xFF)的256个,可重装载指的是初始化设置的起始数,在溢出中断后会重新装载。
TMOD = 0x00;//配置工作模式
2.配置定时器0的工作频率,手上的设备是工作在35MHz,设置1T模式,定时器0也工作35MHz,计数间隔就是1/35 us, 如果设置12T模式,那么定时器0就会工作在35/12 MHz,计数间隔就是12/35 us。
AUXR |= 0x80; //工作时钟不分频
3. 计算初始置,以定时1ms为例,1ms = 1000us 计数间隔是1/35 us,那么需要1000/(1/35) = 35000个间隔 ,就是说经过35000个计数后,时间间隔为1ms,那么就设置初始置为65536 - 35000 = 30536,转换16进制就是 0x7748 ,按高低为分给TL0,TH0.
TL0 = 0x48;
TH0 = 0x77;
4.使能定时中断,还有总中断
ET0 = 1; //使能定时器0中断
EA = 1; //打开总中断
5.开始计数
TR0 = 1; //启动定时器0计数
void T0_Lsr(void) interrupt 1
{
static unsigned int val;
val ++;
if(val == 1000)
{
LED_RED = ! LED_RED;
val = 0;
}
}
void Timer0_Init(void)
{
TMOD = 0x00;//配置工作模式
AUXR |= 0x80; //工作时钟不分频
TL0 = 0x48;
TH0 = 0x77;
TR0 = 1; //启动定时器0计数
ET0 = 1; //使能定时器0中断
EA = 1; //打开总中断
}
void main(void)
{
P0M0 = 0x00;
P0M1 = 0x00;
Timer0_Init();
while(1)
{
6,定时器0和1是在一起,配置起来非常相似。要注意下不同定时器的区别
TMOD = 0x00是同时配置的定时器0和1的工作模式,都是16位重装模式
AUXR |= 0x40; 给第七位赋值1,工作时钟不分频 (配置定时器1的时钟位)
TL1 = 0x48; 一样的1ms配置 (配置定时器1的初始值,刚开始配置错成定时器0了)
TH1 = 0x77;
TR1 = 1; //启动定时器1计数 (配置定时器1)
ET1 = 1; //使能定时器1中断
EA = 1; //打开总中断
再改一下中断序号3
void T1_Lsr(void) interrupt 3
{
static unsigned int val;
val ++;
if(val == 1000)
{
LED_RED = ! LED_RED;
val = 0;
}
}
void Timer1_Init(void)
{
TMOD = 0x00;//配置工作模式
AUXR |= 0x40; //工作时钟不分频
TL1 = 0x48;
TH1 = 0x77;
TR1 = 1; //启动定时器0计数
ET1 = 1; //使能定时器0中断
EA = 1; //打开总中断
}
7.和定时器0、1相比,定时器2的区别就非常大了。 定时器2,只有16位可重装模式,不用配置模式。但是需要将设备设置为定时器。
AUXR &= ~0X08 ; //设置为定时器
同样要设置工作频率
AUXR |= 0x04; //工作时钟不分频
注意下面有点恶心的区别就是初始值的格式不一样 ,数字2在中间
T2L = 0x48;
T2H = 0x77;
还有就是,使能溢出中断和启动中断都不能直接对T2R和IE2进行设置,需要对整个寄存器进行设置
AUXR |= 0X10; //启动定时器2计数
IE2 |= 0X04; //使能定时器2中断
void T2_Lsr(void) interrupt 12
{
static unsigned int val;
val ++;
if(val == 1000)
{
LED_RED = ! LED_RED;
val = 0;
}
}
void Timer2_Init(void)
{
AUXR &= ~0X08 ; //设置为定时器
AUXR |= 0x04; //工作时钟不分频
T2L = 0x48;
T2H = 0x77;
AUXR |= 0X10; //启动定时器2计数
IE2 |= 0X04; //使能定时器2中断
EA = 1; //打开总中断
}
void main(void)
{
P0M0 = 0x00;
P0M1 = 0x00;
Timer2_Init();
while(1)
{
8.定时器3、4和定时器2类似,只是运用的寄存器不一样。因为不能直接按位设置数值,所以配置的时候要很仔细,设置3的时候,就有可能设置到4的位上。(找bug找了快十分钟)
这里开始配置错了,配置的是T4H,T4L
T3L = 0x48;
T3H = 0x77;
这里开始写错了,写的是T3T4M |= 0X80.把T4给启动了
T4T3M |= 0X08; //启动定时器3计数 T3T4M |= 0X08
没有语法错误,编译都不会报错,但是现象不对。
void T3_Lsr(void) interrupt 19
{
static unsigned int val;
val ++;
if(val == 1000)
{
LED_RED = ! LED_RED;
val = 0;
}
}
void Timer3_Init(void)
{
T4T3M |= 0x02; //工作时钟不分频,T3是定时器
T4T3M &= ~0X04;
T3L = 0x48;
T3H = 0x77;
T4T3M |= 0X08; //启动定时器3计数 T3T4M |= 0X08
IE2 |= 0X20; //使能定时器3中断 IE2 |= 0X20
EA = 1; //打开总中断
}
void main(void)
{
P0M0 = 0x00;
P0M1 = 0x00;
Timer3_Init();
while(1)
{文章来源:https://www.toymoban.com/news/detail-736812.html
}
}文章来源地址https://www.toymoban.com/news/detail-736812.html
到了这里,关于STC8学习5 - 定时器的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!