欢迎光临散文网 会员登陆 & 注册

AT32学习笔记-TIMER1.md

2022-11-27 09:15 作者:繁花cloud  | 我要投稿

# 定时器基本使用

通过定时器来定期触发中断

## 定时器的初始化

```c

/* enable tmr1 clock */

// 开启外设时钟

crm_periph_clock_enable(CRM_TMR2_PERIPH_CLOCK, TRUE);

// 开启定时器2

tmr_32_bit_function_enable(TMR2, TRUE);

// 单次模式,执行完一次之后就会停止

// tmr_one_cycle_mode_enable(TMR2,TRUE);

// 设置参数,实际值=参数值+1

// 15999 计到这个数字就触发中断

// 19200 首先对systemclock进行预分频

tmr_base_init(TMR2, 19999, (19200) - 1);

// 设置计数方式(这里没有区别)

tmr_cnt_dir_set(TMR2, TMR_COUNT_UP);

```

## 预分频的概念

系统主频为192Mhz,也就是192000000hz,也就是说每次经过1/192000000秒定时器会把cnt+1,但是16位定时器最大cnt只能到65535,很快就满了。  

所以说需要对时钟进行分频。  

这里分频值为19200,也就是对主频/19200,也就是10khz,也就是说分频后经过1/10000秒后定时器会把cnt+1,然后设置tmr_pr为19999,实际值+参数值+1,也就是cnt到2w会触发中断,20000*1/10000刚好是2秒。  

需要注意的是,按照数据手册的要求,分频系数最大65535,超过这个值后就会溢出,最后效果就和预期效果不一样了。

## 开启32位cnt    

`tmr_32_bit_function_enable(TMR2, TRUE);`  

TIM2和TIM8支持32位计数,也就是说最大范围可以到0xffffffff,大大的提提升了范围。

## 定时器中断的设置

```c

// 开启定时器溢出中断

/* overflow interrupt enable */

tmr_interrupt_enable(TMR2, TMR_OVF_INT, TRUE);


/* tmr1 overflow interrupt nvic init */

// 设置抢占优先级和响应优先级

nvic_priority_group_config(NVIC_PRIORITY_GROUP_4);

// 在nvic中开启该中断,让nvic去管理这个中断

nvic_irq_enable(TMR2_GLOBAL_IRQn, 0, 0);

```

## 定义中断处理函数

`TMR2_GLOBAL_IRQHandler`在startup_at32xxxx.s文件中被定义,也就是常说的中断向量表中被定义

```c

void TMR2_GLOBAL_IRQHandler(void)

{

    // 中断处理函数可能被多个定时器公用,所以我们要检查定时器的flag

if(tmr_flag_get(TMR2, TMR_OVF_FLAG) != RESET)

  {

    /* add user code... */

    // 点灯,打印

i++;

    at32_led_toggle(LED3);

printf("tmr10 %d\r\n",i);

    // 按照寄存器要求,这个flag需要软件置0,要不然一直会触发中断

    tmr_flag_clear(TMR2, TMR_OVF_FLAG);

  }

}

```


AT32学习笔记-TIMER1.md的评论 (共 条)

分享到微博请遵守国家法律