# AT32 定时器输出PWM
## GPIO初始化
```c
void user_gpio_init(void)
{
// 创建初始化结构体
gpio_init_type gpio_init_struct;
// 开启外设时钟
crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK,TRUE);
// 设置默认初始化参数
gpio_default_para_init(&gpio_init_struct);
// 驱动强度,强
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)
{
// 开启外设时钟
crm_periph_clock_enable(CRM_TMR2_PERIPH_CLOCK, TRUE);
// 重置外设
tmr_reset(TMR2);
// 开启32位计数,这里可开可不开
tmr_32_bit_function_enable(TMR2, TRUE);
// 设置定时器基础值,8分频(7+1),计数值(4799+1),频率应为5khz
tmr_base_init(TMR2, 4799, 7); // 5Khz
// 向上计数模式
tmr_cnt_dir_set(TMR2,TMR_COUNT_UP);
// 输出通道配置结构体
tmr_output_config_type tmr_output_struct;
// 设置默认参数
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;
// 闲置状态,FLASE(似乎输入的时候才有用)
tmr_output_struct.oc_idle_state=FALSE;
// 设置输出通道1参数
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);
// 设置输出通道2参数
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);
// 设置输出通道3参数
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);
// 定时器开始计数
tmr_counter_enable(TMR2,TRUE);
}
```
## OC_MODE在寄存器中的说明
000:断开。断开 C1ORAW 到 C1OUT 的输出;
001:设置 C1ORAW 为高:TMRx_CVAL=TMRx_C1DT时。
010:设置 C1ORAW 为低:TMRx_CVAL=TMRx_C1DT时。
011 : 切 换 C1ORAW 的电平 : 当TMRx_CVAL=TMRx_C1DT 时。
100:固定 C1ORAW 为低。
101:固定 C1ORAW 为高。
110:PWM 模式 A
-OWCDIR=0,若 TMRx_C1DT>TMRx_CVAL 时设置C1ORAW 为高,否则为低;
-OWCDIR=1,若 TMRx_ C1DT <TMRx_CVAL 时设置C1ORAW 为低,否则为高。
111:PWM 模式 B
-OWCDIR=0,若 TMRx_ C1DT >TMRx_CVAL 时设置C1ORAW 为低,否则为高;
-OWCDIR=1,若 TMRx_ C1DT <TMRx_CVAL 时设置C1ORAW 为高,否则为低。
## 通道的缓冲使能说明
通道 1 输出缓存使能(Channel 1 output buffer enable)
0:关闭 TMRx_C1DT 的缓存功能,写入 TMRx_C1DT 的内容会立即生效。
1:启用 TMRx_C1DT 的缓存功能,写入 TMRx_C1DT 的内容将保存到缓存寄存器中,当发生溢出事件时再更新到TMRx_C1DT 中。
也就是说,开启和关闭的区别在于TMRx_C1DT会不会立即生效,也就是说开启之后发送溢出事件后比较值才会更新。
日常使用中开启和关闭没有较大的区别。
## 定时器的缓冲使能说明
周期缓冲使能(Period buffer enable)
0:缓冲关闭;
1:缓冲开启。
和上方通道缓冲较为相近,主要是更新的时间
!(images/Snipaste_2022-11-26_12-31-45.png)
## PWM模式
110:PWM 模式 A
111:PWM 模式 B
A和B主要在占空比上存在区别。
模式A,到达比较值之前都为有效电平,到达比较值后变为无效电平。
模式A,到达比较值之前都为无效电平,到达比较值后变为有效电平。
同时,有效电平和无效电平最后输出和配置中的oc_polarity有关,两者作为互补。