学习目标
定时器 | 通道 | 引脚 | AF | 极性 | LED序号 |
---|---|---|---|---|---|
T0 | ch0 | PA7 | AF1 | ON | LED1 |
PA8 | AF1 | OP | LED2 | ||
T7 | ch2 | PB15 | AF3 | ON | LED3 |
PC8 | AF3 | OP | LED4 | ||
ch1 | PB14 | AF3 | ON | LED5 | |
PC7 | AF3 | OP | LED6 | ||
ch0 | PA5 | AF3 | ON | LED7 | |
PC6 | AF3 | OP | LED8 |
高级定时器单通道互补功能
开发流程
- 添加Timer依赖
- 初始化PWM
- 配置通道的P极和N极
- PWM占空比控制
通道配置
////////// 配置输出通道
timer_oc_parameter_struct tops;
// ch0
timer_channel_output_struct_para_init(&tops);
// n config
tops.outputnstate = TIMER_CCXN_ENABLE;
// p config
tops.outputstate = TIMER_CCX_ENABLE;
timer_channel_output_config(timerx, TIMER_CH_0, &tops);
- ocnpolarity:N极性电平
- ocpolarity:P极性电平
完整代码
```cinclude “gd32f4xx.h”
include “systick.h”
include
include “main.h”
include “Usart0.h”
// T0 // ch0 PA7 ON // ch0 PA8 OP
// 分频计数 // 周期计数
define PRESCALER (10 - 1)
define PERIOD (SystemCoreClock / 100000 - 1)
void Usart0_recv(uint8_t *data, uint32_t len) {
}
static void PWM_config() { uint32_t timerx = TIMER0; uint32_t timerx_rcu = RCU_TIMER0; uint32_t timerx_psc = RCU_TIMER_PSC_MUL2;
uint32_t timerx_prescaler = PRESCALER; // 分频计数
uint32_t timerx_period = PERIOD; // 周期计数
uint32_t timerx_ch0_p_port = GPIOA;
uint32_t timerx_ch0_p_port_rcu = RCU_GPIOA;
uint32_t timerx_ch0_p_pin = GPIO_PIN_8;
uint32_t timerx_ch0_p_af = GPIO_AF_1;
uint32_t timerx_ch0_n_port = GPIOA;
uint32_t timerx_ch0_n_port_rcu = RCU_GPIOA;
uint32_t timerx_ch0_n_pin = GPIO_PIN_7;
uint32_t timerx_ch0_n_af = GPIO_AF_1;
/*************** GPIO config **************/
//// ch0 p
// 配置时钟
rcu_periph_clock_enable(timerx_ch0_p_port_rcu);
// 配置GPIO模式
gpio_mode_set(timerx_ch0_p_port, GPIO_MODE_AF, GPIO_PUPD_NONE, timerx_ch0_p_pin);
// 配置GPIO输出
gpio_output_options_set(timerx_ch0_p_port, GPIO_OTYPE_PP, GPIO_OSPEED_MAX, timerx_ch0_p_pin);
// 配置复用功能
gpio_af_set(timerx_ch0_p_port, timerx_ch0_p_af, timerx_ch0_p_pin);
//// ch0 n
// 配置时钟
rcu_periph_clock_enable(timerx_ch0_n_port_rcu);
// 配置GPIO模式
gpio_mode_set(timerx_ch0_n_port, GPIO_MODE_AF, GPIO_PUPD_NONE, timerx_ch0_n_pin);
// 配置GPIO输出
gpio_output_options_set(timerx_ch0_n_port, GPIO_OTYPE_PP, GPIO_OSPEED_MAX, timerx_ch0_n_pin);
// 配置复用功能
gpio_af_set(timerx_ch0_n_port, timerx_ch0_n_af, timerx_ch0_n_pin);
/*************** Timer config *************/
// 时钟配置
rcu_periph_clock_enable(timerx_rcu);
// 复位定时器
timer_deinit(timerx);
// 倍频配置
rcu_timer_clock_prescaler_config(timerx_psc);
// 初始化定时器
timer_parameter_struct tps;
timer_struct_para_init(&tps);
tps.prescaler = timerx_prescaler; // 分频计数
tps.period = timerx_period; // 周期计数
timer_init(timerx, &tps);
////////// 配置输出通道
timer_oc_parameter_struct tops;
// ch0
timer_channel_output_struct_para_init(&tops);
// n config
tops.outputnstate = TIMER_CCXN_ENABLE;
// p config
tops.outputstate = TIMER_CCX_ENABLE;
timer_channel_output_config(timerx, TIMER_CH_0, &tops);
////////// 输出模式配置
// ch0
timer_channel_output_mode_config(timerx, TIMER_CH_0, TIMER_OC_MODE_PWM0);
////////// Break配置
timer_break_parameter_struct tbps;
timer_break_struct_para_init(&tbps);
tbps.breakpolarity = TIMER_BREAK_POLARITY_HIGH;
tbps.outputautostate = TIMER_OUTAUTO_ENABLE;
tbps.breakstate = TIMER_BREAK_ENABLE;
timer_break_config(timerx, &tbps);
// 初始化
timer_enable(timerx);
}
static void PWM_update_ch0(float duty) { uint32_t timerx = TIMER0; uint32_t timerx_chn = TIMER_CH_0;
uint32_t pulse = duty * (PERIOD + 1) / 100;
/***************** pwm update *******************/
// 配置输出的占空比
timer_channel_output_pulse_value_config(timerx, timerx_chn, pulse);
}
static void GPIO_config() { // 配置时钟 rcu_periph_clock_enable(RCU_GPIOA); // 配置GPIO模式 gpio_mode_set(GPIOA, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_3); // 配置GPIO输出 gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_MAX, GPIO_PIN_3); }
int main(void) { systick_config(); nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2); Usart0_init(); GPIO_config(); PWM_config();
gpio_bit_reset(GPIOA, GPIO_PIN_3);
int8_t i;
while(1) {
for(i = 0; i < 25; i++) {
PWM_update_ch0(i);
delay_1ms(50);
}
for(i = 24; i >= 0; i--) {
PWM_update_ch0(i);
delay_1ms(50);
}
delay_1ms(1000);
}
}
<a name="q1l0U"></a>
### 高级定时器多通道互补功能
<a name="qXpuR"></a>
#### 开发流程
1. 添加Timer依赖
2. 初始化PWM
3. 配置通道的P极和N极
4. PWM占空比控制
<a name="sLxj0"></a>
#### 多通道配置
```c
timer_oc_parameter_struct tops;
timer_channel_output_struct_para_init(&tops);
// n config
tops.outputnstate = TIMER_CCXN_ENABLE;
tops.ocnpolarity = TIMER_OCN_POLARITY_LOW;
// p config
tops.outputstate = TIMER_CCX_ENABLE;
tops.ocpolarity = TIMER_OC_POLARITY_LOW;
///// ch0
timer_channel_output_config(timerx, TIMER_CH_0, &tops);
///// ch1
timer_channel_output_config(timerx, TIMER_CH_1, &tops);
///// ch2
timer_channel_output_config(timerx, TIMER_CH_2, &tops);
完整代码
#include "gd32f4xx.h"
#include "systick.h"
#include <stdio.h>
#include "main.h"
#include "Usart0.h"
// T7
// ch0
// N: PA5 ON
// P: PC6 OP
// ch1
// N: PB14 ON
// P: PC7 OP
// ch2
// N: PB15 ON
// P: PC8 OP
// 分频计数
// 周期计数
#define PRESCALER (10 - 1)
#define PERIOD (SystemCoreClock / 100000 - 1)
void Usart0_recv(uint8_t *data, uint32_t len) {
}
static void PWM_config() {
uint32_t timerx = TIMER7;
uint32_t timerx_rcu = RCU_TIMER7;
uint32_t timerx_psc = RCU_TIMER_PSC_MUL2;
uint32_t timerx_prescaler = PRESCALER; // 分频计数
uint32_t timerx_period = PERIOD; // 周期计数
// ch0
uint32_t timerx_ch0_n_port = GPIOA;
uint32_t timerx_ch0_n_port_rcu = RCU_GPIOA;
uint32_t timerx_ch0_n_pin = GPIO_PIN_5;
uint32_t timerx_ch0_n_af = GPIO_AF_3;
uint32_t timerx_ch0_p_port = GPIOC;
uint32_t timerx_ch0_p_port_rcu = RCU_GPIOC;
uint32_t timerx_ch0_p_pin = GPIO_PIN_6;
uint32_t timerx_ch0_p_af = GPIO_AF_3;
// ch1
uint32_t timerx_ch1_n_port = GPIOB;
uint32_t timerx_ch1_n_port_rcu = RCU_GPIOB;
uint32_t timerx_ch1_n_pin = GPIO_PIN_14;
uint32_t timerx_ch1_n_af = GPIO_AF_3;
uint32_t timerx_ch1_p_port = GPIOC;
uint32_t timerx_ch1_p_port_rcu = RCU_GPIOC;
uint32_t timerx_ch1_p_pin = GPIO_PIN_7;
uint32_t timerx_ch1_p_af = GPIO_AF_3;
// ch2
uint32_t timerx_ch2_n_port = GPIOB;
uint32_t timerx_ch2_n_port_rcu = RCU_GPIOB;
uint32_t timerx_ch2_n_pin = GPIO_PIN_15;
uint32_t timerx_ch2_n_af = GPIO_AF_3;
uint32_t timerx_ch2_p_port = GPIOC;
uint32_t timerx_ch2_p_port_rcu = RCU_GPIOC;
uint32_t timerx_ch2_p_pin = GPIO_PIN_8;
uint32_t timerx_ch2_p_af = GPIO_AF_3;
/*************** GPIO config **************/
//// ch0
//// p
// 配置时钟
rcu_periph_clock_enable(timerx_ch0_p_port_rcu);
// 配置GPIO模式
gpio_mode_set(timerx_ch0_p_port, GPIO_MODE_AF, GPIO_PUPD_NONE, timerx_ch0_p_pin);
// 配置GPIO输出
gpio_output_options_set(timerx_ch0_p_port, GPIO_OTYPE_PP, GPIO_OSPEED_MAX, timerx_ch0_p_pin);
// 配置复用功能
gpio_af_set(timerx_ch0_p_port, timerx_ch0_p_af, timerx_ch0_p_pin);
//// n
// 配置时钟
rcu_periph_clock_enable(timerx_ch0_n_port_rcu);
// 配置GPIO模式
gpio_mode_set(timerx_ch0_n_port, GPIO_MODE_AF, GPIO_PUPD_NONE, timerx_ch0_n_pin);
// 配置GPIO输出
gpio_output_options_set(timerx_ch0_n_port, GPIO_OTYPE_PP, GPIO_OSPEED_MAX, timerx_ch0_n_pin);
// 配置复用功能
gpio_af_set(timerx_ch0_n_port, timerx_ch0_n_af, timerx_ch0_n_pin);
//// ch1
//// p
// 配置时钟
rcu_periph_clock_enable(timerx_ch1_p_port_rcu);
// 配置GPIO模式
gpio_mode_set(timerx_ch1_p_port, GPIO_MODE_AF, GPIO_PUPD_NONE, timerx_ch1_p_pin);
// 配置GPIO输出
gpio_output_options_set(timerx_ch1_p_port, GPIO_OTYPE_PP, GPIO_OSPEED_MAX, timerx_ch1_p_pin);
// 配置复用功能
gpio_af_set(timerx_ch1_p_port, timerx_ch1_p_af, timerx_ch1_p_pin);
//// n
// 配置时钟
rcu_periph_clock_enable(timerx_ch1_n_port_rcu);
// 配置GPIO模式
gpio_mode_set(timerx_ch1_n_port, GPIO_MODE_AF, GPIO_PUPD_NONE, timerx_ch1_n_pin);
// 配置GPIO输出
gpio_output_options_set(timerx_ch1_n_port, GPIO_OTYPE_PP, GPIO_OSPEED_MAX, timerx_ch1_n_pin);
// 配置复用功能
gpio_af_set(timerx_ch1_n_port, timerx_ch1_n_af, timerx_ch1_n_pin);
//// ch2
//// p
// 配置时钟
rcu_periph_clock_enable(timerx_ch2_p_port_rcu);
// 配置GPIO模式
gpio_mode_set(timerx_ch2_p_port, GPIO_MODE_AF, GPIO_PUPD_NONE, timerx_ch2_p_pin);
// 配置GPIO输出
gpio_output_options_set(timerx_ch2_p_port, GPIO_OTYPE_PP, GPIO_OSPEED_MAX, timerx_ch2_p_pin);
// 配置复用功能
gpio_af_set(timerx_ch2_p_port, timerx_ch2_p_af, timerx_ch2_p_pin);
//// n
// 配置时钟
rcu_periph_clock_enable(timerx_ch2_n_port_rcu);
// 配置GPIO模式
gpio_mode_set(timerx_ch2_n_port, GPIO_MODE_AF, GPIO_PUPD_NONE, timerx_ch2_n_pin);
// 配置GPIO输出
gpio_output_options_set(timerx_ch2_n_port, GPIO_OTYPE_PP, GPIO_OSPEED_MAX, timerx_ch2_n_pin);
// 配置复用功能
gpio_af_set(timerx_ch2_n_port, timerx_ch2_n_af, timerx_ch2_n_pin);
/*************** Timer config *************/
// 时钟配置
rcu_periph_clock_enable(timerx_rcu);
// 复位定时器
timer_deinit(timerx);
// 倍频配置
rcu_timer_clock_prescaler_config(timerx_psc);
// 初始化定时器
timer_parameter_struct tps;
timer_struct_para_init(&tps);
tps.prescaler = timerx_prescaler; // 分频计数
tps.period = timerx_period; // 周期计数
timer_init(timerx, &tps);
////////// 配置输出通道
timer_oc_parameter_struct tops;
///// ch0
timer_channel_output_struct_para_init(&tops);
// n config
tops.outputnstate = TIMER_CCXN_ENABLE;
tops.ocpolarity = TIMER_OC_POLARITY_LOW;
// p config
tops.outputstate = TIMER_CCX_ENABLE;
tops.ocpolarity = TIMER_OC_POLARITY_LOW;
timer_channel_output_config(timerx, TIMER_CH_0, &tops);
///// ch1
timer_channel_output_struct_para_init(&tops);
// n config
tops.outputnstate = TIMER_CCXN_ENABLE;
// p config
tops.outputstate = TIMER_CCX_ENABLE;
tops.ocpolarity = TIMER_OC_POLARITY_LOW;
timer_channel_output_config(timerx, TIMER_CH_1, &tops);
///// ch2
timer_channel_output_struct_para_init(&tops);
// n config
tops.outputnstate = TIMER_CCXN_ENABLE;
// p config
tops.outputstate = TIMER_CCX_ENABLE;
tops.ocpolarity = TIMER_OC_POLARITY_LOW;
timer_channel_output_config(timerx, TIMER_CH_2, &tops);
////////// 输出模式配置
// ch0
timer_channel_output_mode_config(timerx, TIMER_CH_0, TIMER_OC_MODE_PWM0);
// ch1
timer_channel_output_mode_config(timerx, TIMER_CH_1, TIMER_OC_MODE_PWM0);
// ch2
timer_channel_output_mode_config(timerx, TIMER_CH_2, TIMER_OC_MODE_PWM0);
////////// Break配置
timer_break_parameter_struct tbps;
timer_break_struct_para_init(&tbps);
tbps.breakpolarity = TIMER_BREAK_POLARITY_HIGH;
tbps.outputautostate = TIMER_OUTAUTO_ENABLE;
tbps.breakstate = TIMER_BREAK_ENABLE;
timer_break_config(timerx, &tbps);
// 初始化
timer_enable(timerx);
}
static void PWM_update_ch0(float duty) {
uint32_t timerx = TIMER7;
uint32_t timerx_chn = TIMER_CH_0;
uint32_t pulse = duty * (PERIOD + 1) / 100;
/***************** pwm update *******************/
// 配置输出的占空比
timer_channel_output_pulse_value_config(timerx, timerx_chn, pulse);
}
static void PWM_update_ch1(float duty) {
uint32_t timerx = TIMER7;
uint32_t timerx_chn = TIMER_CH_1;
uint32_t pulse = duty * (PERIOD + 1) / 100;
/***************** pwm update *******************/
// 配置输出的占空比
timer_channel_output_pulse_value_config(timerx, timerx_chn, pulse);
}
static void PWM_update_ch2(float duty) {
uint32_t timerx = TIMER7;
uint32_t timerx_chn = TIMER_CH_2;
uint32_t pulse = duty * (PERIOD + 1) / 100;
/***************** pwm update *******************/
// 配置输出的占空比
timer_channel_output_pulse_value_config(timerx, timerx_chn, pulse);
}
static void GPIO_config() {
// 配置时钟
rcu_periph_clock_enable(RCU_GPIOA);
// 配置GPIO模式
gpio_mode_set(GPIOA, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_3);
// 配置GPIO输出
gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_MAX, GPIO_PIN_3);
}
int main(void)
{
systick_config();
nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2);
Usart0_init();
GPIO_config();
PWM_config();
gpio_bit_reset(GPIOA, GPIO_PIN_3);
int8_t i;
while(1) {
for(i = 0; i < 25; i++) {
PWM_update_ch0(i);
PWM_update_ch1(i);
PWM_update_ch2(i);
delay_1ms(50);
}
for(i = 24; i >= 0; i--) {
PWM_update_ch0(i);
PWM_update_ch1(i);
PWM_update_ch2(i);
delay_1ms(50);
}
delay_1ms(1000);
}
}
练习题
- 实现互补pwm