定时器也可以做为计数器,其实他们本质上的原理是一样的,定时器是计数单片机内部的系统时钟,每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)
    {

        
    }
}

物联沃分享整理
物联沃-IOTWORD物联网 » STC8学习5 – 定时器

发表评论