51定时/中断

51单片机中断号

外部中断0(INT0),对应中断号是0, 中断入口地址0003H
定时/计数器0(T1),对应中断号1 ,中断入口地址000BH
外部中断1(INT1),中断号2 入口地址0013H
定时/计数器1(T1)中断号3 入口地址001BH
串行口中(RI/TI)中断号4 入口地址0023H
这五个是AT89S51的,52还多了下面这个
定时/计数器2(T2)中断号5,入口地址002BH


定时器中断示示例代码,包含三个定时器在 90c516R+上测试通过

#include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义

sbit LED=P1^2;    //定义LED端口
sbit LED1=P1^3;    //定义LED端口
sbit LED2=P1^4;    //定义LED端口
/*------------------------------------------------
                    定时器初始化子程序
------------------------------------------------*/
//定时器0
void Init_Timer0(void)
{
 TMOD |= 0x01;	  //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响		     
 TH0=0x00;	      //给定初值,这里使用定时器最大值从0开始计数一直到65535溢出
 TL0=0x00;
 EA=1;            //总中断打开
 ET0=1;           //定时器中断打开
 TR0=1;           //定时器开关打开
}
//定时器1
void Init_Timer1(void)
{
 TMOD |= 0x10;	  //使用模式2,16位定时器,使用"|"符号可以在使用多个定时器时不受影响 
 TH1=0x00;	      //给定初值,这里使用定时器最大值从0开始计数一直到65535溢出
 TL1=0x00;
 EA=1;            //总中断打开
 ET1=1;           //定时器中断打开
 TR1=1;           //定时器开关打开
}

//定时器2
void TIM2Inital(void)
{
  RCAP2H = (65536-60000)/256;//晶振12M 60ms 16bit 自动重载
  RCAP2L = (65536-60000)%256;
  ET2=1;                     //打开定时器中断
  EA=1;                      //打开总中断
  TR2=1;                     //打开定时器开关
}
/*------------------------------------------------
                    主程序
------------------------------------------------*/
main()
{
 Init_Timer0();
 Init_Timer1();
 TIM2Inital();
 while(1);
}

/*------------------------------------------------
                 定时器中断子程序
------------------------------------------------*/
//中断号1  定时器0
void Timer0_isr(void) interrupt 1 using 1
{
 TH0=0x00;		  //重新赋值
 TL0=0x00;

 LED=~LED;        //指示灯反相,可以看到闪烁

}//中断号3  定时器1
void Timer1_isr(void) interrupt 3 using 1
{
 TH1=0x00;		  //重新赋值
 TL1=0x00;

 LED1=~LED1;        //指示灯反相,可以看到闪烁

}

//中断号3  定时器2

void TIM2(void) interrupt 5 using 1//定时器2中断
{

    TF2=0;
    LED2=~LED2;               //指示灯反相
   
}

下面是在网上搜索的一段定时器取时间的技巧:

确定定时器的初值是为了让定时器按照自己的意思(自己规定的秒数)去产生中断。由于定时器计数是用两个8位寄存器结合为一个16位去递加:  

2^16次方 = 65536(机器周期)

而定时器的默认中断方式是当16位寄存器递增至满(共计65536个机器周期)后,溢出便产生中断。
现在我想让定时器在50ms之后产生中断,则只需要让计数器从TH0TL0初值开始计数,刚刚好50ms之后就溢出,这样便可以控制定时器产生中断。
那么, TH0TL0这个初值是多少呢? 求这个初值只需要 65536 - (50ms内的机器周期数) 现在我们来看看,50ms内的机器周期有多少个:


假设晶振为 11.0592MHz
11.0592MHz => 11059200Hz / 12 = 921600个/秒 (也就是说1秒能运行921600个机器周期)

换算一下, 921600个/秒 = 921.6个/毫秒 = 46080个/50ms 
好了,现在我们计算出了50ms内能运行46080个机器周期,
那么按上述求初值的方法: 初值 = 65536 - 46080 = 19456个。 

最后,总结一下,我们想要让定时器经过50ms后产生中断,只需要给定时器设置一个初值,值为19456 = 0x4c00 即可。


赋值TH0 TL0时也有技巧,就是高位除 /,低位取余 %。
TH0 = 19456/256; // TH0是8位,2^8 = 256
TL0 = 19456%256; // TL0是8位,2^8 = 256

另外,对于精确计算,若想要1秒产生一次中断,只需要50ms中断的定时器产生20次即可得到1秒中断了。



转载于:https://my.oschina.net/ffs/blog/169722

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值