AT32學(xué)習(xí)筆記
# AT32 定時器輸出PWM
## GPIO初始化
```c
void user_gpio_init(void)
{
? ? // 創(chuàng)建初始化結(jié)構(gòu)體
gpio_init_type gpio_init_struct;
? ? // 開啟外設(shè)時鐘
crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK,TRUE);
? ? // 設(shè)置默認(rèn)初始化參數(shù)
gpio_default_para_init(&gpio_init_struct);
? ? // 驅(qū)動強(qiáng)度,強(qiáng)
gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
? ? // 輸出模式,推挽
gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
? ? // GPIO模式,IOMUX
gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
? ? // 引腳 IO1 IO2 IO3
gpio_init_struct.gpio_pins = GPIO_PINS_1 | GPIO_PINS_2 | GPIO_PINS_3;
? ? // 上拉,無上拉
gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
gpio_init(GPIOA,&gpio_init_struct);
}
```
## 定時器初始化
```c
// 定時器初始化
void user_tmr_init(void)
{
? ? // 開啟外設(shè)時鐘
crm_periph_clock_enable(CRM_TMR2_PERIPH_CLOCK, TRUE);
? ? // 重置外設(shè)
tmr_reset(TMR2);
? ? // 開啟32位計數(shù),這里可開可不開
tmr_32_bit_function_enable(TMR2, TRUE);
? ? // 設(shè)置定時器基礎(chǔ)值,8分頻(7+1),計數(shù)值(4799+1),頻率應(yīng)為5khz
tmr_base_init(TMR2, 4799, 7); // 5Khz
? ? // 向上計數(shù)模式
tmr_cnt_dir_set(TMR2,TMR_COUNT_UP);
// 輸出通道配置結(jié)構(gòu)體
tmr_output_config_type tmr_output_struct;
? ? // 設(shè)置默認(rèn)參數(shù)
tmr_output_default_para_init(&tmr_output_struct);
? ? // PWM模式A,B
tmr_output_struct.oc_mode = TMR_OUTPUT_CONTROL_PWM_MODE_B;
? ? // 輸出模式,開啟
tmr_output_struct.oc_output_state = TRUE;
? ? // 輸出極性,有效時輸出高電平
tmr_output_struct.oc_polarity = TMR_OUTPUT_ACTIVE_HIGH;
? ? // 閑置狀態(tài),FLASE(似乎輸入的時候才有用)
tmr_output_struct.oc_idle_state = FALSE;
? ? // 設(shè)置輸出通道1參數(shù)
? ? tmr_output_channel_config(TMR2, TMR_SELECT_CHANNEL_2, &tmr_output_struct);
? ? // 比較值
? ? tmr_channel_value_set(TMR2, TMR_SELECT_CHANNEL_2, 4800);
? ? // 開啟BUFFER
? ? tmr_output_channel_buffer_enable(TMR2, TMR_SELECT_CHANNEL_2, TRUE);
? ? // 設(shè)置輸出通道2參數(shù)
tmr_output_channel_config(TMR2, TMR_SELECT_CHANNEL_3, &tmr_output_struct);
? ? tmr_channel_value_set(TMR2, TMR_SELECT_CHANNEL_3, 4800);
? ? tmr_output_channel_buffer_enable(TMR2, TMR_SELECT_CHANNEL_3, TRUE);
? ? // 設(shè)置輸出通道3參數(shù)
tmr_output_channel_config(TMR2, TMR_SELECT_CHANNEL_4, &tmr_output_struct);
? ? tmr_channel_value_set(TMR2, TMR_SELECT_CHANNEL_4, 4800);
? ? tmr_output_channel_buffer_enable(TMR2, TMR_SELECT_CHANNEL_4, TRUE);
? ? // 開啟BUFFER
tmr_period_buffer_enable(TMR2,TRUE);
? ? // 定時器開始計數(shù)
tmr_counter_enable(TMR2,TRUE);
}
```
## OC_MODE在寄存器中的說明
000:斷開。斷開 C1ORAW 到 C1OUT 的輸出;??
001:設(shè)置 C1ORAW 為高:TMRx_CVAL=TMRx_C1DT時。??
010:設(shè)置 C1ORAW 為低:TMRx_CVAL=TMRx_C1DT時。??
011 : 切 換 C1ORAW 的電平 : 當(dāng)TMRx_CVAL=TMRx_C1DT 時。??
100:固定 C1ORAW 為低。??
101:固定 C1ORAW 為高。??
110:PWM 模式 A??
-OWCDIR=0,若 TMRx_C1DT>TMRx_CVAL 時設(shè)置C1ORAW 為高,否則為低;??
-OWCDIR=1,若 TMRx_ C1DT <TMRx_CVAL 時設(shè)置C1ORAW 為低,否則為高。??
111:PWM 模式 B??
-OWCDIR=0,若 TMRx_ C1DT >TMRx_CVAL 時設(shè)置C1ORAW 為低,否則為高;??
-OWCDIR=1,若 TMRx_ C1DT <TMRx_CVAL 時設(shè)置C1ORAW 為高,否則為低。??
## 通道的緩沖使能說明
通道 1 輸出緩存使能(Channel 1 output buffer enable)??
0:關(guān)閉 TMRx_C1DT 的緩存功能,寫入 TMRx_C1DT 的內(nèi)容會立即生效。??
1:啟用 TMRx_C1DT 的緩存功能,寫入 TMRx_C1DT 的內(nèi)容將保存到緩存寄存器中,當(dāng)發(fā)生溢出事件時再更新到TMRx_C1DT 中。??
也就是說,開啟和關(guān)閉的區(qū)別在于TMRx_C1DT會不會立即生效,也就是說開啟之后發(fā)送溢出事件后比較值才會更新。??
日常使用中開啟和關(guān)閉沒有較大的區(qū)別。
## 定時器的緩沖使能說明
周期緩沖使能(Period buffer enable)??
0:緩沖關(guān)閉;??
1:緩沖開啟。??
和上方通道緩沖較為相近,主要是更新的時間

## PWM模式
110:PWM 模式 A??
-OWCDIR=0,若 TMRx_C1DT>TMRx_CVAL 時設(shè)置C1ORAW 為高,否則為低;??
-OWCDIR=1,若 TMRx_ C1DT <TMRx_CVAL 時設(shè)置C1ORAW 為低,否則為高。??
111:PWM 模式 B??
-OWCDIR=0,若 TMRx_ C1DT >TMRx_CVAL 時設(shè)置C1ORAW 為低,否則為高;??
-OWCDIR=1,若 TMRx_ C1DT <TMRx_CVAL 時設(shè)置C1ORAW 為高,否則為低。??
A和B主要在占空比上存在區(qū)別。??
模式A,到達(dá)比較值之前都為有效電平,到達(dá)比較值后變?yōu)闊o效電平。??
模式A,到達(dá)比較值之前都為無效電平,到達(dá)比較值后變?yōu)橛行щ娖健??
同時,有效電平和無效電平最后輸出和配置中的oc_polarity有關(guān),兩者作為互補(bǔ)。??