一个使用定时器的跑马灯
有了上片“一个简单的跑马灯”后,已经可以对IO口进行操作,但实际使用中经常要定时的去执行某一些动作,这就需要使用到定时器和中断,在一定的时间去触发执行要求的动作。
CH563 有4个定时器,功能挺多,这里只用最简单的定时功能;这里选用TIM0,TIM0相关寄存器如下:
都是资料中有详细注解,这里就不一一描述了。初始化在资料中介绍如下:
对应代码如下:
void Timer3_Init( UINT32 count_end)
{
R8_TMR3_CTRL_MOD = 0;
R32_TMR3_CNT_END = count_end; /* 捕获的最大超时时间 */
R8_TMR3_CTRL_MOD |= RB_TMR_COUNT_EN ; /* 允许计数,启动定时器 */
}
到这里就完成了TIM0 定时功能的初始化;
CH563 中断系统分为 IRQ ,FIQ 两大类, FIQ 优先级比IRQ 高,响应速度更快。
这里使用IRQ 模式;IRQ 中断初始化如下:
void IRQ_Init( void )
{
R8_TMR0_INT_FLAG = RB_TMR_IF_DATA_ACT|RB_TMR_IE_CYC_END|RB_TMR_IF_FIFO_HF|
RB_TMR_IF_DMA_END|RB_TMR_IF_FIFO_OV|RB_TMR_IF_DMA_ERR; /* 清除所有的中断标志 */
R8_TMR3_INTER_EN = RB_TMR_IE_CYC_END; /* 计数到达终值中断使能 */
R8_INT_EN_IRQ_0 = RB_IE_IRQ_TMR3; /* 允许定时器3相关中断产生 */
R8_INT_EN_IRQ_GLOB = RB_IE_IRQ_GLOB; /* 只开启IRQ全局中断 */
}
初始化了中断,还得要中断子程序来响应中断,中断子程序的代码参照上篇操作LED代码更改后如下:
__irq void IRQ_Handler( void )
{
UINT8 i;
PRINT( "irq# " );
if(R8_INT_FLAG_0&RB_IF_TMR3){
i= R8_TMR3_INT_FLAG;
if(i&RB_TMR_IF_CYC_END){ /* 捕获超时中断 */
if(ss == 1)
{ LED2_OUT_ACT( );
LED4_OUT_INACT( );
ss = 2;
}
else if(ss == 2)
{
LED2_OUT_INACT( );
LED3_OUT_ACT( );
ss = 3;
}
else
{
LED3_OUT_INACT( );
LED4_OUT_ACT( );
ss = 1;
}
R8_TMR3_INT_FLAG=0xff; /* 清除相应中断标志 */
R8_INT_FLAG_0 |= RB_IF_TMR3; /* 清除相应中断标志 */
R32_TMR3_FIFO;
}
}
}
完整代码参考附件