【AT-START-F425测评】 五、定时器中断代码简析及呼吸灯实现
[复制链接]
雅特力AT32提供了较完整的Demo例程,其中tmr例程还是非常丰富的,其中有个7_pwm_output的例程,7个管脚分别输出PWM。Readme文件中有英文说明
- tmr1_ch1 ---> pa8
- tmr1_ch1c ---> pb13
- tmr1_ch2 ---> pa9
- tmr1_ch2c ---> pb14
- tmr1_ch3 ---> pa10
- tmr1_ch3c ---> pb15
- tmr1_ch4 ---> pa11
查询手册,可以看到定时器各管脚的复用情况
可以看到,复用使用MUX2。
具体的代码部分为
int main(void)
{
uint8_t dir = 0;
system_clock_config();
at32_board_init();
/* get system clock */
crm_clocks_freq_get(&crm_clocks_freq_struct);
/* turn led2/led3/led4 on */
at32_led_on(LED2);
at32_led_on(LED3);
at32_led_on(LED4);
/* enable tmr1/gpioa/gpiob clock */
crm_periph_clock_enable(CRM_TMR1_PERIPH_CLOCK, TRUE);
crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE);
// crm_periph_clock_enable(CRM_GPIOB_PERIPH_CLOCK, TRUE);
/* timer1 output pin Configuration */
gpio_init_struct.gpio_pins = GPIO_PINS_8 | GPIO_PINS_9 | GPIO_PINS_10 |GPIO_PINS_11;
gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
gpio_init(GPIOA, &gpio_init_struct);
// gpio_init_struct.gpio_pins = GPIO_PINS_13 | GPIO_PINS_14 | GPIO_PINS_15;
// gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
// gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
// gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
// gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
// gpio_init(GPIOB, &gpio_init_struct);
gpio_pin_mux_config(GPIOA, GPIO_PINS_SOURCE8, GPIO_MUX_2);
gpio_pin_mux_config(GPIOA, GPIO_PINS_SOURCE9, GPIO_MUX_2);
gpio_pin_mux_config(GPIOA, GPIO_PINS_SOURCE10, GPIO_MUX_2);
gpio_pin_mux_config(GPIOA, GPIO_PINS_SOURCE11, GPIO_MUX_2);
// gpio_pin_mux_config(GPIOB, GPIO_PINS_SOURCE13, GPIO_MUX_2);
// gpio_pin_mux_config(GPIOB, GPIO_PINS_SOURCE14, GPIO_MUX_2);
// gpio_pin_mux_config(GPIOB, GPIO_PINS_SOURCE15, GPIO_MUX_2);
/* tmr1 configuration generate 7 pwm signals with 4 different duty cycles:
prescaler = 0, tmr1 counter clock = system_core_clock
the objective is to generate 7 pwm signal at 17.57 khz:
- tim1_period = (system_core_clock / 17570) - 1
the channel 1 and channel 1c duty cycle is set to 50%
the channel 2 and channel 2c duty cycle is set to 37.5%
the channel 3 and channel 3c duty cycle is set to 25%
the channel 4 duty cycle is set to 12.5%
the timer pulse is calculated as follows:
- channelxpulse = duty_cycle * (tim1_period - 1) / 100 */
//类似stm32的ARR,自动重新装载寄存器
/* compute the value to be set in arr regiter to generate signal frequency at 17.57 khz */
//timer_period = (crm_clocks_freq_struct.sclk_freq / 17570 ) - 1;
//一下分别根据周期计算占空比
/* compute c1dt value to generate a duty cycle at 50% for channel 1 and 1c */
// channel1_pulse = (uint16_t)(((uint32_t) 5 * (timer_period - 1)) / 10);
/* compute c2dt value to generate a duty cycle at 37.5% for channel 2 and 2c */
//channel2_pulse = (uint16_t)(((uint32_t) 375 * (timer_period - 1)) / 1000);
/* compute c3dt value to generate a duty cycle at 25% for channel 3 and 3c */
//channel3_pulse = (uint16_t)(((uint32_t) 2 * (timer_period - 1)) / 100);
/* compute c4dt value to generate a duty cycle at 12.5% for channel 4 */
//channel4_pulse = (uint16_t)(((uint32_t) 125 * (timer_period- 1)) / 1000);
//原代码直接用系统主频进行计数,不分频
//tmr_base_init(TMR1, timer_period, 0);
//更改为分频96,及定时器主频为 96Mhz / (95 +1) = 1Mhz
//更改Arr 为 500, 实际计数为501个
tmr_base_init(TMR1, 500, 95);
tmr_cnt_dir_set(TMR1, TMR_COUNT_UP); //向上计数方式
tmr_clock_source_div_set(TMR1, TMR_CLOCK_DIV1); //采用预分频的频率
/* channel 1, 2, 3 and 4 configuration in output mode */
tmr_output_default_para_init(&tmr_output_struct);
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_LOW;
tmr_output_struct.oc_idle_state = TRUE;
tmr_output_struct.occ_output_state = TRUE;
tmr_output_struct.occ_polarity = TMR_OUTPUT_ACTIVE_HIGH;
tmr_output_struct.occ_idle_state = FALSE;
// channel 1 通道1配置,以及设置占空比
tmr_output_channel_config(TMR1, TMR_SELECT_CHANNEL_1, &tmr_output_struct);
tmr_channel_value_set(TMR1, TMR_SELECT_CHANNEL_1, channel1_pulse);
// channel 2 通道2配置,以及设置占空比
tmr_output_channel_config(TMR1, TMR_SELECT_CHANNEL_2, &tmr_output_struct);
tmr_channel_value_set(TMR1, TMR_SELECT_CHANNEL_2, channel2_pulse);
// channel 3 通道3配置,以及设置占空比
tmr_output_channel_config(TMR1, TMR_SELECT_CHANNEL_3, &tmr_output_struct);
tmr_channel_value_set(TMR1, TMR_SELECT_CHANNEL_3, channel3_pulse);
// channel 4 通道4配置,以及设置占空比
tmr_output_channel_config(TMR1, TMR_SELECT_CHANNEL_4, &tmr_output_struct);
tmr_channel_value_set(TMR1, TMR_SELECT_CHANNEL_4, channel4_pulse);
/* output enable */
tmr_output_enable(TMR1, TRUE);
/* enable tmr1 */
tmr_counter_enable(TMR1, TRUE);
channel3_pulse = 100;
while(1)
{
//设置呼吸方式,最大值时递减,最小值时递增
if(dir)channel3_pulse++;
else channel3_pulse--;
if(channel3_pulse>=500)dir=0;
if(channel3_pulse==0)dir=1;
//赋值占空比
TMR1->c3dt = channel3_pulse;
delay_ms(2);
}
}
用的是高级定时器TMR1实现的。
评测的时候发现PA11没有占空比信号,通过万用表检测,发现排针(PA11)和MCU的管脚之间断开了,不知道是什么原因,个人在使用过程中对开发板的保护还是蛮好的,由此推断应该是出厂没有完全检测管脚,也给厂家提个醒。
|