这里利用定时器产生内部的时钟信号,不再使用延时的函数代码。用计数器判断时间差值,在main函数中做相应的操作。arduino里面常用的就是这种方法。
程序中的systick已经用作内部延时函数的代码了,所以这里使用定时器1作为内部计数器。
官网的例程给出一个定时器1产生1s周期的代码。这就修改一下定时器就行了
在at32f425_board.c定义一个初始化定时器1的代码,系统给出的是120Mhz的主频,用串口输出这个数据是96Mhz的,所以
这需要修改一下。
crm_clocks_freq_type crm_clocks_freq_struct = {0};
void at32_time1_init()
{
/* get system clock */
crm_clocks_freq_get(&crm_clocks_freq_struct);
printf("crm_clocks_freq is %d \rn",crm_clocks_freq_struct.ahb_freq);
/* enable tmr1 clock */
crm_periph_clock_enable(CRM_TMR1_PERIPH_CLOCK, TRUE);
/* tmr1 configuration */
/* time base configuration */
/* systemclock/96/1000 = 1khz */
tmr_base_init(TMR1, 1000-1, (crm_clocks_freq_struct.ahb_freq / 1000000) - 1);
tmr_cnt_dir_set(TMR1, TMR_COUNT_UP);
/* overflow interrupt enable */
tmr_interrupt_enable(TMR1, TMR_OVF_INT, TRUE);
/* tmr1 overflow interrupt nvic init */
nvic_priority_group_config(NVIC_PRIORITY_GROUP_4);
nvic_irq_enable(TMR1_BRK_OVF_TRG_HALL_IRQn, 0, 0);
/* enable tmr1 */
tmr_counter_enable(TMR1, TRUE);
}
在main.c中定义一个计数的变量
uint32_t sys_cnt=0;// 系统内部计时变量
uint32_t now(void)
{
return sys_cnt;
}
还需要在定时器中断中驱动这个变量自增加
void TMR1_BRK_OVF_TRG_HALL_IRQHandler(void)
{
if(tmr_flag_get(TMR1, TMR_OVF_FLAG) != RESET)
{
/* add user code... */
sys_cnt++;
tmr_flag_clear(TMR1, TMR_OVF_FLAG);
}
}
剩下的就是在代码中实现led显示了
if(now()-lst_t>1000)//每一秒钟执行一次
{
lst_t=now();
at32_led_toggle(LED2);
at32_led_toggle(LED3);
at32_led_toggle(LED4);
}
上电下载程序就能看到代码了,这里就不再上图演示了。
附上代码
AT32F425.rar
(3.12 MB)
|