定时器中断(16位模式)
该MCU内部共有6个定时器,其中time0和time1不能自重重装计数寄存器的值,timer2,timer3,time4,time5则都可以自动重装计数预装值。定时器的输入时钟在默认情况下是系统时钟的12分频输入,而系统时钟在默认情况下则是内部时钟24.5MHz的8分频。因此,定时器在默认情况下输入时钟为24.5MHz/8/12。其中,对于定时器的调试除了参考datasheet,也参考了石恒瑞同志的串口和定时器内容。
Timer0和Timer1
相关定时器:TCON THX TLX CKCON0 TMOD IE 其中TCON用来设置Timer0和Timer1的是能与否,THX和TLX是存储定时器重载计数预装值寄存器,CKCON0用来设置Timer0和Timer1的时钟即选择时钟源,TMOD用来设置是否是计数器模式,以及是8位,13位或者16位等。默认是16位。IE则是控制Timer0和Timer1的中断与否。由于这两个定时器不能重载计数预装值,因此,在中断函数里需要重载值。Timer0初始化函数和中断服务子函数如下,其中t_ms是在输入时钟为24.5MHz/8/12条件下中断溢出时间,单位是ms。
uint8_t TIME0_MS=0 ; //定时器0的初始化中断时间
uint8_t TIME1_MS=0 ; //定时器0的初始化中断时间
/**
* 定时0 初始化
* @param t_ms 每次中断的时间,时间单位为ms
* 默认频率为30625HZ,则定时器2的输入时钟为 其12分频
*/
void timer0_init(uint8_t t_ms)
{
uint8_t TCON_save;
TIME0_MS=t_ms; //定时器0的初始化中断时间
TCON_save = TCON;
SFRPAGE = 0x00;
TCON &= ~TCON_TR0__BMASK & ~TCON_TR1__BMASK;
TH0 = (uint16_t)(65536-0.001*t_ms*255208)/256;
TL0 = (uint16_t)(65536-0.001*t_ms*255208)%256;
TCON |= (TCON_save & TCON_TR0__BMASK) | (TCON_save & TCON_TR1__BMASK);
CKCON0=CKCON0|CKCON0_SCA__SYSCLK_DIV_12| CKCON0_T0M__PRESCALE; //系统时钟的12分频
TMOD=TMOD|TMOD_T0M__MODE1|TMOD_CT0__TIMER|TMOD_GATE0__DISABLED; //计数器模式,16bit
TCON |= TCON_TR0__RUN;
IE = IE|IE_ET0__ENABLED;
}
/**
* 定时器0中断
* 每中断一次加变量count_ms加1
*/
SI_INTERRUPT(TIMER0_ISR, TIMER0_IRQn)
{
count0_ms++;
TCON_TR0 = 0; // Stop Timer 0
TH0 = (uint16_t)(65536-0.001*TIME0_MS*255208)/256;
TL0 = (uint16_t)(65536-0.001*TIME0_MS*255208)%256;
TCON_TR0 = 1; // Start Timer 0
}
Timer2-----Timer5
Timer2--Timer5是自动重载定时器,也就是计数溢出后能够自动从TMRXRLH和TMRXRLL寄存器中将预装值加载到TMRXH和TMRXL中。相关的寄存器如下:TMRXCN0,TMRXH,TMRXL,TMRXRLH,TMRXRLL,IE,EIE1,EIE2,其中,TMRXCN0用来控制TIMRX的使能与否,TMRXH,TMRXL是存储计数预装值,TMRXRLH,TMRXRLL存储要自动重装到TMRXH,TMRXL的数据,IE是Timer2的中断控制寄存器,EIE1是Timer3的中断控制寄存器,EIE2是Timer4和Timer5的中断控制寄存器。其中TMR3CN0好像不能位操作,因此需要直接赋值。
定时器2初始化和中断服务子程序如下
/**
* 定时2 初始化
* @param t_ms 每次中断的时间,时间单位为ms
* 默认频率为30625HZ,则定时器2的输入时钟为 其12分频
*/
void timer2_init(uint8_t t_ms)
{
SFRPAGE = 0x00;
TMR2CN0 &= ~(TMR2CN0_TR2__BMASK);
TMR2H = (uint16_t)(65536-0.001*t_ms*255208)/256;
TMR2L = (uint16_t)(65536-0.001*t_ms*255208)%256;
TMR2RLH = (uint16_t)(65536-0.001*t_ms*255208)/256;
TMR2RLL = (uint16_t)(65536-0.001*t_ms*255208)%256;//溢出后自动装载TMR2RLH和TMR2RLL寄存器的值到TMR2H和TMR2L寄存器
TMR2CN0 |= TMR2CN0_TR2__RUN;
IE = IE | IE_ET2__ENABLED;
}
/**
* 定时器2中断
* 每中断一次加变量count_ms加1
*/
SI_INTERRUPT(TIMER2_ISR, TIMER2_IRQn)
{
count2_ms++;
TMR2CN0_TF2H = 0; // Clear the interrupt flag
}
定时器3初始化和中断服务子程序如下
/**
* 定时3 初始化
* @param t_ms 每次中断的时间,时间单位为ms
* 默认频率为30625HZ,则定时器2的输入时钟为 其12分频
*/
void timer3_init(uint8_t t_ms)
{
SFRPAGE = 0x00;
TMR3CN0 &= ~(TMR3CN0_TR3__BMASK);
TMR3H = (uint16_t)(65536-0.001*t_ms*255208)/256;
TMR3L = (uint16_t)(65536-0.001*t_ms*255208)%256;
TMR3RLH = (uint16_t)(65536-0.001*t_ms*255208)/256;
TMR3RLL = (uint16_t)(65536-0.001*t_ms*255208)%256;//溢出后自动装载TMR2RLH和TMR2RLL寄存器的值到TMR2H和TMR2L寄存器
TMR3CN0 |= TMR3CN0_TR3__RUN;
EIE1 = EIE1 | EIE1_ET3__ENABLED;
}
/**
* 定时器3中断
* 每中断一次加变量count_ms加1
*/
SI_INTERRUPT(TIMER3_ISR, TIMER3_IRQn)
{
count3_ms++;
TMR3CN0 &=0x7F; // Clear the interrupt flag
}