AT32學(xué)習(xí)筆記-TIMER1.md
# 定時(shí)器基本使用
通過(guò)定時(shí)器來(lái)定期觸發(fā)中斷
## 定時(shí)器的初始化
```c
/* enable tmr1 clock */
// 開(kāi)啟外設(shè)時(shí)鐘
crm_periph_clock_enable(CRM_TMR2_PERIPH_CLOCK, TRUE);
// 開(kāi)啟定時(shí)器2
tmr_32_bit_function_enable(TMR2, TRUE);
// 單次模式,執(zhí)行完一次之后就會(huì)停止
// tmr_one_cycle_mode_enable(TMR2,TRUE);
// 設(shè)置參數(shù),實(shí)際值=參數(shù)值+1
// 15999 計(jì)到這個(gè)數(shù)字就觸發(fā)中斷
// 19200 首先對(duì)systemclock進(jìn)行預(yù)分頻
tmr_base_init(TMR2, 19999, (19200) - 1);
// 設(shè)置計(jì)數(shù)方式(這里沒(méi)有區(qū)別)
tmr_cnt_dir_set(TMR2, TMR_COUNT_UP);
```
## 預(yù)分頻的概念
系統(tǒng)主頻為192Mhz,也就是192000000hz,也就是說(shuō)每次經(jīng)過(guò)1/192000000秒定時(shí)器會(huì)把cnt+1,但是16位定時(shí)器最大cnt只能到65535,很快就滿(mǎn)了。??
所以說(shuō)需要對(duì)時(shí)鐘進(jìn)行分頻。??
這里分頻值為19200,也就是對(duì)主頻/19200,也就是10khz,也就是說(shuō)分頻后經(jīng)過(guò)1/10000秒后定時(shí)器會(huì)把cnt+1,然后設(shè)置tmr_pr為19999,實(shí)際值+參數(shù)值+1,也就是cnt到2w會(huì)觸發(fā)中斷,20000*1/10000剛好是2秒。??
需要注意的是,按照數(shù)據(jù)手冊(cè)的要求,分頻系數(shù)最大65535,超過(guò)這個(gè)值后就會(huì)溢出,最后效果就和預(yù)期效果不一樣了。
## 開(kāi)啟32位cnt? ??
`tmr_32_bit_function_enable(TMR2, TRUE);`??
TIM2和TIM8支持32位計(jì)數(shù),也就是說(shuō)最大范圍可以到0xffffffff,大大的提提升了范圍。
## 定時(shí)器中斷的設(shè)置
```c
// 開(kāi)啟定時(shí)器溢出中斷
/* overflow interrupt enable */
tmr_interrupt_enable(TMR2, TMR_OVF_INT, TRUE);
/* tmr1 overflow interrupt nvic init */
// 設(shè)置搶占優(yōu)先級(jí)和響應(yīng)優(yōu)先級(jí)
nvic_priority_group_config(NVIC_PRIORITY_GROUP_4);
// 在nvic中開(kāi)啟該中斷,讓nvic去管理這個(gè)中斷
nvic_irq_enable(TMR2_GLOBAL_IRQn, 0, 0);
```
## 定義中斷處理函數(shù)
`TMR2_GLOBAL_IRQHandler`在startup_at32xxxx.s文件中被定義,也就是常說(shuō)的中斷向量表中被定義
```c
void TMR2_GLOBAL_IRQHandler(void)
{
? ? // 中斷處理函數(shù)可能被多個(gè)定時(shí)器公用,所以我們要檢查定時(shí)器的flag
if(tmr_flag_get(TMR2, TMR_OVF_FLAG) != RESET)
? {
? ? /* add user code... */
? ? // 點(diǎn)燈,打印
i++;
? ? at32_led_toggle(LED3);
printf("tmr10 %d\r\n",i);
? ? // 按照寄存器要求,這個(gè)flag需要軟件置0,要不然一直會(huì)觸發(fā)中斷
? ? tmr_flag_clear(TMR2, TMR_OVF_FLAG);
? }
}
```