本帖最后由 观海 于 2019-12-31 15:26 编辑
set_ET1; //enable Timer1 interrupt #define set_ET1 ET1 = 1 set_EA; //enable interrupts
set_TR0; //Timer0 run
中断服务函数: void Timer0_ISR (void) interrupt 1 //interrupt address is 0x000B{ TH0 = TH0_INIT;
TL0 = TL0_INIT;
P12 = ~P12; // GPIO toggle when interrupt
}
模式1(16位定时器) 模式1与模式0 非常相似,只是模式1下定时器/计数器为16位的,就是说是用THx和TLx的全部16位用来计数。当
计数值由FFFFH向0000H翻转后,定时器相应的溢出标志TF0(TF1)置1,如果中断使能则将产生中断。
#include "N76E003.h" #include "Common.h" #include "Delay.h" #include "SFR_Macro.h" #include "Function_define.h"
//***************** The Following is in define in Fucntion_define.h *************************** //****** Always include Function_define.h call the define you want, detail see main(void) ******* //*********************************************************************************************** #if 0 //#define TIMER0_MODE0_ENABLE TMOD&=0x0F //#define TIMER0_MODE1_ENABLE TMOD&=0x0F;TMOD|=0x10 //#define TIMER0_MODE2_ENABLE TMOD&=0x0F;TMOD|=0x20 //#define TIMER0_MODE3_ENABLE TMOD&=0x0F;TMOD|=0x3F
//#define TIMER1_MODE0_ENABLE TMOD&=0xF0 //#define TIMER1_MODE1_ENABLE TMOD&=0xF0;TMOD|=0x01 //#define TIMER1_MODE2_ENABLE TMOD&=0xF0;TMOD|=0x02 //#define TIMER1_MODE3_ENABLE TMOD&=0xF0;TMOD|=0xF3 #endif
#define TH0_INIT 50000 #define TL0_INIT 50000 #define TH1_INIT 25000 #define TL1_INIT 25000
UINT8 u8TH0_Tmp,u8TL0_Tmp,u8TH1_Tmp,u8TL1_Tmp; /************************************************************************************************************ * TIMER 0 interrupt subroutine ************************************************************************************************************/ void Timer0_ISR (void) interrupt 1 //interrupt address is 0x000B { TH0 = u8TH0_Tmp; TL0 = u8TL0_Tmp;
P12 = ~P12; // GPIO1 toggle when interrupt }
/************************************************************************************************************ * TIMER 1 interrupt subroutine ************************************************************************************************************/ void Timer1_ISR (void) interrupt 3 //interrupt address is 0x001B { TH1 = u8TH1_Tmp; TL1 = u8TL1_Tmp;
P03 = ~P03; //P0.3 toggle when interrupt } /************************************************************************************************************ * Main function ************************************************************************************************************/ void main (void) {
Set_All_GPIO_Quasi_Mode; TIMER0_MODE1_ENABLE; TIMER1_MODE1_ENABLE;
clr_T1M; //set_T1M;
u8TH0_Tmp = (65536-TH0_INIT)/256; u8TL0_Tmp = (65536-TL0_INIT)%256; u8TH1_Tmp = (65536-TH1_INIT)/256; u8TL1_Tmp = (65536-TL1_INIT)%256;
TH0 = u8TH0_Tmp; TL0 = u8TL0_Tmp; TH1 = u8TH1_Tmp; TL1 = u8TL1_Tmp;
set_ET0; //enable Timer0 interrupt set_ET1; //enable Timer1 interrupt set_EA; //enable interrupts set_TR0; //Timer0 run set_TR1; //Timer1 run while(1); }u8TH0_Tmp = (65536-TH0_INIT)/256; u8TL0_Tmp = (65536-TL0_INIT)%256;
u8TH1_Tmp = (65536-TH1_INIT)/256; u8TL1_Tmp = (65536-TL1_INIT)%256; TH0 = u8TH0_Tmp; TL0 = u8TL0_Tmp; TH1 = u8TH1_Tmp; TL1 = u8TL1_Tmp;
只是模式1下定时器/计数器为16位的,就是说是用THx和TLx的全部16位用来计数。当
计数值由FFFFH向0000H翻转后,定时器相应的溢出标志TF0(TF1)置1,如果中断使能则将产生中断。
方式1为16位的定时器/计数器,对定时器T0来说是分成两个寄存器(可以形象地比作容器吧,网上有比我更形象的比喻,我就不多写了,请自行查阅):TH0为高八位,TL0为低八位,组成了16位的定时器,当低位TL0计满就向高位TH0移一个数,然后清零。 以16Mhz的内置晶振来说,机器周期是(1/16000000)s(1T 8051),当一次溢出也就是65536*1/16 us,约等于4.096ms,如果要定时50ms的话就要给他们装一个预装值(初值),总值-需要值=预装值, 也就是65536-65536=0,预装后,定时器从预装值(0)开始加值,定时器溢出中断后,会重新从预装值开始加值加到4(约为)ms就再产生中断,从而达到了定时的目的。如果要定时1s就可以让定时器中断1000ms/4ms=500次。 另外一点,TH0和TL0中应该装入的总数是0,然后把0对256求模:0/256=00装入TH0中,把0对256求余:0%256=0装入TL0中,因为这是两个八位2^8*2^8的容器。 所以就有了 TH0=(65535-65535)/256 TL0=(65535-65535)%256
|