C51编程16-中断篇(定时器中断3)

 使用定时器/计数器中断,需要将满足以下的条件。

    1)中断总允许打开 EA = 1;

    2)中断源允许打开  ET0 = 1或者 ET1= 1;

    3)设置定时器计/计数器的工作方式(设置TMOD)

    4)装载定时器,设置计数器的初始计算值。

    5)开启定时器(TCON中的TR0 = 1或者TR1 = 1)

    6)中断服务函数

     

    通过前面一些中断文章的学习,相信除了上面的第4点外,使用定时器/计数器已经没什么难度了。

    装载定时器,前面的定时器章节可以知道,定时器/计数器有4种方式。它们分别是13位手动装载(方式0)、16位手动装载(方式1)、8位自动重装(方式2)、8位手动装载(方式3)。根据定时器/计数器的位数需要TH0(1)与TL0(1)组成定时器/计数器的位数。

    输入的时钟脉冲是由晶体振荡器的输出12分频后得到的,所以定时器是对机器周期的计数器,每一个机器周期+1,也就是说TH0(1)与TL0(1)组成定时器/计数器的位数的值,在每个机器周期+1,当该值溢出时,产生定时器/计数器中断。

 

    下面以方式1与方式2,进行定时,点亮LED。 

   方式1

/****************************************
Header:
File Name: main.c
Author:  adam
Date:  2020年9月19日
******************************************/
​
#include "reg52.h"
#include "stdio.h"
​
typedef unsigned char uchar;
typedef unsigned int uint;
​
uint countms = 0;
void DelayMs(uint ms);
​
void main(){
​
   EA = 1;      //总中断允许
   ET0 = 1;     //定时器T0中断允许
   TMOD = 0x01; //设置为模式1,定时器模式:C/T=0;不启动外部INT0控制开始定时:GATE=0,
   //定时1ms,机器周期1us,1000个机器周期1ms
   //16位定时器溢出条件:满值65535(#FFFF)+1溢出,因此定时1ms需要(65535+1-1000);
   //将该值分给两个寄存器,每个可以装256个数。
   TH0 = (65536-1000)/256;   //装载初值TH     
   TL0 = (65536-1000)%256;   //装载初值TL
   TR0 =1;   //启动定时器TR0
​
   while(1)
   {
        DelayMs(1000);
        P0=~P0; 
   }
​
}
​
​
void DelayMs(uint ms)
{
        while(countms<ms);   //等待需要的ms;
        countms=0; 
}
​
void Timer0(void) interrupt  1
{
    //重新装初值
    TH0 = (65535-1000)/256;
    TL0 = (65535-1000)%256;  
    countms++;   //每ms,countms++
​
​
}

 

 

   方式2

/****************************************
Header:
File Name: main.c
Author:  adam
Date:  2020年9月19日
******************************************/
#include "reg52.h"
#include "stdio.h"
​
typedef unsigned char uchar;
typedef unsigned int uint;
​
uint countus = 0;
uint countms = 0;
​
void DelayMs(uint ms);
​
void main(){
   EA = 1;      //总中断允许
   ET0 = 1;     //定时器T0中断允许
   TMOD = 0x02; //设置为模式2,定时器模式:C/T=0;不启动外部INT0控制开始定时:GATE=0,
​
   //由于方式只有8位,最大定时只能到0.256us,因此先定时100us,然后通过100us定时ms。
   TH0 = 256-100;   //装载值TH,自动重装     
   TL0 = 256-100;   //装载值TL,溢出产生中断。
   TR0 =1;   //启动定时器TR0
​
   while(1)
   {
        DelayMs(100);
        P0=~P0;
   }
}
​
​
void DelayUs(uint us){  
      while(countus<us);
      countus=0;
}
​
void DelayMs(uint ms)
{
           while(countms<ms){
            DelayUs(10);   
            countms++;  
        }      
        countms=0;
}
​
​
void Timer0(void) interrupt  1
{  
    countus++;   //每ms,countms++   
}


 

    注:在上述的两个例子中,中断分别是1ms与100us。不建议使用定时器设置中断更小的时间。

    虽然定时器可以设置定1us就可以产生中断,但是1us仅仅为一个机器周期,当中断响应后,进入中断服务函数。仅仅一条简单的语句执行可能要四个机器周期,再加上保护现场与恢复现场,将会占用较长的机器周期,使得定时不准确。

      当GATE =1,定时器/计数器受到INT0/INT1电平的影响,INT0/INT1=1启动计数,INT0/INT1=0停止计数。当GATE =1,单片机上电后,P0~P3初值均为高电平,因此不需要外接高电平启动定时器/计数器。一般INT0/INT1采用以下的电路,按下按钮为低电平,定时器/计数器停止计数。

 

透析之眼 提了一个问题

阅读后有疑问,可以关注公众号,参与讨论哦

参与讨论

---------------------------------------------------------

如果觉得文章还不错,那就扫码关注吧!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

颖川初尘

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值