SYD8821 TIMER模块使用说明
这里除了timer0被协议栈占用外,剩下的timer1-timer4都可以被用户代码使用
注意:SYD8821的计数器是递增计数器,也就是说这里设置的初值是定时器的溢出值(最大值),读回来的计数值是从0到溢出值之间。
注意:timer0~timer3是16bit的计数器,也就是说timer0~timer3最多能够计数2s,而timer4位24bit的计数器,也就是说timer4最多能够记1024秒。
这里硬件连接图如下:
这里打开工程:“\SYD8821_SDK\Source Code\SYD8821\TIMER\Keil”可看到主函数如下:
int main()
{
uint8_t *buff;
uint16_t buff_size=0;
__disable_irq();
// Select External XO
sys_32k_clock_set(SYSTEM_32K_CLOCK_XO);
// Set MCU Clock 64M
sys_mcu_clock_set(MCU_CLOCK_64_MHZ);
// RC bumping
sys_mcu_rc_calibration();
LED_KEY_Module_Init();
UART_Module_Init();
Timer_Module_Init(); //timer初始化
__enable_irq();
while(1)
{
gpo_toggle(LED4);
if(timer1s_inting)
{
timer1s_inting = 0;
gpo_toggle(LED7);
uart_write(1,"SYD8821 TIMER1 1s TEST\r\n", 26);
}
。。。。。。。。。。。。。。。。。。
}
}
注意:这里选择SYSTEM_32K_CLOCK_XO(外部32.768KHz晶振)作为时钟源,这样定时器的周期才能够准确,当然,这里也可以用内部32.768KHz RC晶振做为时钟源,但是内部RC振荡器必须以一定的周期(3分钟左右)进行校准
其中初始化函数Timer_Module_Init源码如下:
void Timer_Module_Init(void)
{
timer_disable(TIMER_1); //使能定时器之前先失能定时器
timer_enable(TIMER_1, timer1_callback, 32768, 1);//32768 = 1S 16384 = 500ms
NVIC_EnableIRQ(TIMER1_IRQn);
}
注意:这里在使能定时器之前先失能定时器,否则在仿真的时候中断没能够上报上来
这里设置的定时器计数初值为32768,时钟源是32.768KHz,也就是说这里将产生1S的中断
逻辑分析仪看到的波形如下:
这里上传本博客源码:https://download.csdn.net/download/chengdong1314/10337404
TIMER4测试
这里用timer1和timer4同时设置相同的参数
void Timer_Module_Init(void)
{
timer_disable(TIMER_1);
timer_enable(TIMER_1, timer1_callback, 32768*2, 1);//32768 = 1S 16384 = 500ms
NVIC_EnableIRQ(TIMER1_IRQn);
timer_disable(TIMER_4);
timer_enable(TIMER_4, timer4_callback, 32768*2, 1);//32768 = 1S 16384 = 500ms
NVIC_EnableIRQ(TIMER4_IRQn);
}
可以看到timer1的波形和timer4的波形是不一样的,timer1的明显不对,timer4的波形是正确的两秒:
为了规范代码这里修改timer的驱动和相关头文件:
TIMER_CTRL_TYPE修改如下:
/* ============================ timer =========================== */
typedef struct {
/* 0x00~ 0x03*/
__IO uint32_t TIMER_ENABLE:1;
__IO uint32_t RSVD00:31;
union{
struct{
/* 0x04~ 0x07*/
__IO uint32_t TIMER_RELOAD_VAL:16;
__IO uint32_t RSVD01:16;
/* 0x08~ 0x0B*/
__IO uint32_t TIMER_COUNTER:16;
__IO uint32_t RSVD02:16;
};
struct{
/* 0x04~ 0x07*/
__IO uint32_t TIMER4_RELOAD_VAL:24;
__IO uint32_t RSVD011:8;
/* 0x08~ 0x0B*/
__IO uint32_t TIMER4_COUNTER:24;
__IO uint32_t RSVD021:8;
};
};
/* 0x0C~ 0x17*/
__IO uint32_t RSVD03[3];
/* 0x18~ 0x1B*/
__IO uint32_t INTERRUPT_OUT:1;
__IO uint32_t RSVD04:31;
/* 0x1C~ 0x1F*/
__IO uint32_t TIMER_INTERRUPT_ENABLE:1;
__IO uint32_t RSVD05:31;
/* 0x20~ 0x23*/
__IO uint32_t TIMER_INTERRUPT_DISABLE:1;
__IO uint32_t RSVD06:31;
}TIMER_CTRL_TYPE;
timer_enable修改如下:
uint8_t timer_enable(TIMER_ID id, TIMER_IRQ_CALLBACK_TYPE callback, int interval, int int_enable)
{
if (is_timer_enabled(id) || id >= TIMER_NUM)
return 0;
cb[id] = callback;
if(id==TIMER_4)ctrl[id]->TIMER4_RELOAD_VAL = interval;
else ctrl[id]->TIMER_RELOAD_VAL = interval;
if (int_enable)
ctrl[id]->TIMER_INTERRUPT_ENABLE = 1;
else
ctrl[id]->TIMER_INTERRUPT_DISABLE = 1;
ctrl[id]->TIMER_ENABLE = 1;
return 1;
}