- 学习目标
- 学习内容
- include “gd32f4xx.h”
- include “systick.h”
- include
- include “main.h”
- include “Usart0.h”
- define PRESCALER (10 - 1)
- define PERIOD (SystemCoreClock / 100000 - 1)
- include “gd32f4xx.h”
- include “systick.h”
- include
- include “main.h”
- include “Usart0.h”
- define PRESCALER (10 - 1)
- define PERIOD (SystemCoreClock / 100000 - 1)
学习目标
定时器 | 通道 | 引脚 | AF | LED序号 |
---|---|---|---|---|
T0 | ch0 | PA8 | AF1 | LED2 |
T1 | ch0 | PA5 | AF1 | LED7 |
T2 | ch0 | PC6 | AF2 | LED8 |
ch1 | PC7 | AF2 | LED6 | |
ch2 | PC8 | AF2 | LED4 | |
T7 | ch0_on | PA7 | AF3 | LED1 |
ch1_on | PB14 | AF3 | LED5 | |
ch2_on | PB15 | AF3 | LED3 |
实现LED4``LED6``LED8``LED1``LED3``LED5
呼吸灯效果
通用定时器多通道
开发流程
// ch0 timer_channel_output_struct_para_init(&tops); tops.outputstate = TIMER_CCX_ENABLE; timer_channel_output_config(timerx, TIMER_CH_0, &tops);
// ch1 timer_channel_output_struct_para_init(&tops); tops.outputstate = TIMER_CCX_ENABLE; timer_channel_output_config(timerx, TIMER_CH_1, &tops);
// ch2 timer_channel_output_struct_para_init(&tops); tops.outputstate = TIMER_CCX_ENABLE; timer_channel_output_config(timerx, TIMER_CH_1, &tops);
- TIMER_CH_0: 表示通道0
- TIMER_CH_1: 表示通道1
- TIMER_CH_2: 表示通道2
```c
// 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);
- TIMER_OC_MODE_PWM0: 高电平有效
-
占空比更新
// ch0
timer_channel_output_pulse_value_config(timerx, TIMER_CH_0, 0);
// ch1
timer_channel_output_pulse_value_config(timerx, TIMER_CH_1, 0);
// ch2
timer_channel_output_pulse_value_config(timerx, TIMER_CH_2, 0);
关心的内容
static void PWM_config() {
uint32_t timerx = TIMER2;
uint32_t timerx_rcu = RCU_TIMER2;
uint32_t timerx_psc = RCU_TIMER_PSC_MUL4;
uint32_t timerx_prescaler = PRESCALER; // 分频计数
uint32_t timerx_period = PERIOD; // 周期计数
uint32_t timerx_ch0_port = GPIOC;
uint32_t timerx_ch0_port_rcu = RCU_GPIOC;
uint32_t timerx_ch0_pin = GPIO_PIN_6;
uint32_t timerx_ch0_af = GPIO_AF_2;
uint32_t timerx_ch1_port = GPIOC;
uint32_t timerx_ch1_port_rcu = RCU_GPIOC;
uint32_t timerx_ch1_pin = GPIO_PIN_7;
uint32_t timerx_ch1_af = GPIO_AF_2;
uint32_t timerx_ch2_port = GPIOC;
uint32_t timerx_ch2_port_rcu = RCU_GPIOC;
uint32_t timerx_ch2_pin = GPIO_PIN_8;
uint32_t timerx_ch2_af = GPIO_AF_2;
/*************** GPIO config **************/
//// ch0
// 配置时钟
rcu_periph_clock_enable(timerx_ch0_port_rcu);
// 配置GPIO模式
gpio_mode_set(timerx_ch0_port, GPIO_MODE_AF, GPIO_PUPD_NONE, timerx_ch0_pin);
// 配置GPIO输出
gpio_output_options_set(timerx_ch0_port, GPIO_OTYPE_PP, GPIO_OSPEED_MAX, timerx_ch0_pin);
// 配置复用功能
gpio_af_set(timerx_ch0_port, timerx_ch0_af, timerx_ch0_pin);
//// ch1
// 配置时钟
rcu_periph_clock_enable(timerx_ch1_port_rcu);
// 配置GPIO模式
gpio_mode_set(timerx_ch1_port, GPIO_MODE_AF, GPIO_PUPD_NONE, timerx_ch1_pin);
// 配置GPIO输出
gpio_output_options_set(timerx_ch1_port, GPIO_OTYPE_PP, GPIO_OSPEED_MAX, timerx_ch1_pin);
// 配置复用功能
gpio_af_set(timerx_ch1_port, timerx_ch1_af, timerx_ch1_pin);
//// ch2
// 配置时钟
rcu_periph_clock_enable(timerx_ch2_port_rcu);
// 配置GPIO模式
gpio_mode_set(timerx_ch2_port, GPIO_MODE_AF, GPIO_PUPD_NONE, timerx_ch2_pin);
// 配置GPIO输出
gpio_output_options_set(timerx_ch2_port, GPIO_OTYPE_PP, GPIO_OSPEED_MAX, timerx_ch2_pin);
// 配置复用功能
gpio_af_set(timerx_ch2_port, timerx_ch2_af, timerx_ch2_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);
tops.outputstate = TIMER_CCX_ENABLE;
timer_channel_output_config(timerx, TIMER_CH_0, &tops);
// ch1
timer_channel_output_struct_para_init(&tops);
tops.outputstate = TIMER_CCX_ENABLE;
timer_channel_output_config(timerx, TIMER_CH_1, &tops);
// ch2
timer_channel_output_struct_para_init(&tops);
tops.outputstate = TIMER_CCX_ENABLE;
timer_channel_output_config(timerx, TIMER_CH_2, &tops);
#endif
////////// 输出模式配置
// 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);
// 初始化
timer_enable(timerx);
}
定时器是哪个
- 开启了几个通道
- 周期是多少
- 分频是多少
完整代码
```cinclude “gd32f4xx.h”
include “systick.h”
include
include “main.h”
include “Usart0.h”
// T2 // ch0 PC6 // ch1 PC7 // ch2 PC8
// 分频计数 // 周期计数
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 = TIMER2; uint32_t timerx_rcu = RCU_TIMER2; uint32_t timerx_psc = RCU_TIMER_PSC_MUL4;
uint32_t timerx_prescaler = PRESCALER; // 分频计数
uint32_t timerx_period = PERIOD; // 周期计数
uint32_t timerx_ch0_port = GPIOC;
uint32_t timerx_ch0_port_rcu = RCU_GPIOC;
uint32_t timerx_ch0_pin = GPIO_PIN_6;
uint32_t timerx_ch0_af = GPIO_AF_2;
uint32_t timerx_ch1_port = GPIOC;
uint32_t timerx_ch1_port_rcu = RCU_GPIOC;
uint32_t timerx_ch1_pin = GPIO_PIN_7;
uint32_t timerx_ch1_af = GPIO_AF_2;
uint32_t timerx_ch2_port = GPIOC;
uint32_t timerx_ch2_port_rcu = RCU_GPIOC;
uint32_t timerx_ch2_pin = GPIO_PIN_8;
uint32_t timerx_ch2_af = GPIO_AF_2;
/*************** GPIO config **************/
//// ch0
// 配置时钟
rcu_periph_clock_enable(timerx_ch0_port_rcu);
// 配置GPIO模式
gpio_mode_set(timerx_ch0_port, GPIO_MODE_AF, GPIO_PUPD_NONE, timerx_ch0_pin);
// 配置GPIO输出
gpio_output_options_set(timerx_ch0_port, GPIO_OTYPE_PP, GPIO_OSPEED_MAX, timerx_ch0_pin);
// 配置复用功能
gpio_af_set(timerx_ch0_port, timerx_ch0_af, timerx_ch0_pin);
//// ch1
// 配置时钟
rcu_periph_clock_enable(timerx_ch1_port_rcu);
// 配置GPIO模式
gpio_mode_set(timerx_ch1_port, GPIO_MODE_AF, GPIO_PUPD_NONE, timerx_ch1_pin);
// 配置GPIO输出
gpio_output_options_set(timerx_ch1_port, GPIO_OTYPE_PP, GPIO_OSPEED_MAX, timerx_ch1_pin);
// 配置复用功能
gpio_af_set(timerx_ch1_port, timerx_ch1_af, timerx_ch1_pin);
//// ch2
// 配置时钟
rcu_periph_clock_enable(timerx_ch2_port_rcu);
// 配置GPIO模式
gpio_mode_set(timerx_ch2_port, GPIO_MODE_AF, GPIO_PUPD_NONE, timerx_ch2_pin);
// 配置GPIO输出
gpio_output_options_set(timerx_ch2_port, GPIO_OTYPE_PP, GPIO_OSPEED_MAX, timerx_ch2_pin);
// 配置复用功能
gpio_af_set(timerx_ch2_port, timerx_ch2_af, timerx_ch2_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);
tops.outputstate = TIMER_CCX_ENABLE;
timer_channel_output_config(timerx, TIMER_CH_0, &tops);
// ch1
timer_channel_output_struct_para_init(&tops);
tops.outputstate = TIMER_CCX_ENABLE;
timer_channel_output_config(timerx, TIMER_CH_1, &tops);
// ch2
timer_channel_output_struct_para_init(&tops);
tops.outputstate = TIMER_CCX_ENABLE;
timer_channel_output_config(timerx, TIMER_CH_2, &tops);
////////// 输出模式配置
// ch0
timer_channel_output_mode_config(timerx, TIMER_CH_0, TIMER_OC_MODE_PWM1);
// ch1
timer_channel_output_mode_config(timerx, TIMER_CH_1, TIMER_OC_MODE_PWM1);
// ch2
timer_channel_output_mode_config(timerx, TIMER_CH_2, TIMER_OC_MODE_PWM1);
// 初始化
timer_enable(timerx);
}
static void PWM_update_ch0(float duty) { uint32_t timerx = TIMER2; 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 = TIMER2; 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 = TIMER2; 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);
}
}
<a name="jHb7L"></a>
### 高等级定时器多通道
<a name="H2UDK"></a>
#### 开发流程
1. 添加Timer依赖
2. 初始化PWM,包含多通道配置
3. Break配置
4. PWM占空比控制
<a name="uN2bU"></a>
#### 多通道配置
```c
timer_oc_parameter_struct tops;
// ch0
timer_channel_output_struct_para_init(&tops);
tops.outputnstate = TIMER_CCXN_ENABLE;
timer_channel_output_config(timerx, TIMER_CH_0, &tops);
// ch1
timer_channel_output_struct_para_init(&tops);
tops.outputnstate = TIMER_CCXN_ENABLE;
timer_channel_output_config(timerx, TIMER_CH_1, &tops);
// ch2
timer_channel_output_struct_para_init(&tops);
tops.outputnstate = TIMER_CCXN_ENABLE;
timer_channel_output_config(timerx, TIMER_CH_2, &tops);
特别强调,这里的引脚分为P和N类型,不同引脚要配置不同的输出状态
Break配置
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);
breakstate:break状态开启
- ouputostate:输出状态,自动开启
- breakpolarity:输出极性,高电平
占空比
// ch0
timer_channel_output_pulse_value_config(timerx, TIMER_CH_0, 0);
// ch1
timer_channel_output_pulse_value_config(timerx, TIMER_CH_1, 0);
// ch2
timer_channel_output_pulse_value_config(timerx, TIMER_CH_2, 0);
关心的内容
完整代码
```cinclude “gd32f4xx.h”
include “systick.h”
include
include “main.h”
include “Usart0.h”
// T7 // ch0 PA7 ON // ch1 PB14 ON // ch2 PB15 ON
// 分频计数 // 周期计数
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; // 周期计数
uint32_t timerx_ch0_port = GPIOA;
uint32_t timerx_ch0_port_rcu = RCU_GPIOA;
uint32_t timerx_ch0_pin = GPIO_PIN_7;
uint32_t timerx_ch0_af = GPIO_AF_3;
uint32_t timerx_ch1_port = GPIOB;
uint32_t timerx_ch1_port_rcu = RCU_GPIOB;
uint32_t timerx_ch1_pin = GPIO_PIN_14;
uint32_t timerx_ch1_af = GPIO_AF_3;
uint32_t timerx_ch2_port = GPIOB;
uint32_t timerx_ch2_port_rcu = RCU_GPIOB;
uint32_t timerx_ch2_pin = GPIO_PIN_15;
uint32_t timerx_ch2_af = GPIO_AF_3;
/*************** GPIO config **************/
//// ch0
// 配置时钟
rcu_periph_clock_enable(timerx_ch0_port_rcu);
// 配置GPIO模式
gpio_mode_set(timerx_ch0_port, GPIO_MODE_AF, GPIO_PUPD_NONE, timerx_ch0_pin);
// 配置GPIO输出
gpio_output_options_set(timerx_ch0_port, GPIO_OTYPE_PP, GPIO_OSPEED_MAX, timerx_ch0_pin);
// 配置复用功能
gpio_af_set(timerx_ch0_port, timerx_ch0_af, timerx_ch0_pin);
//// ch1
// 配置时钟
rcu_periph_clock_enable(timerx_ch1_port_rcu);
// 配置GPIO模式
gpio_mode_set(timerx_ch1_port, GPIO_MODE_AF, GPIO_PUPD_NONE, timerx_ch1_pin);
// 配置GPIO输出
gpio_output_options_set(timerx_ch1_port, GPIO_OTYPE_PP, GPIO_OSPEED_MAX, timerx_ch1_pin);
// 配置复用功能
gpio_af_set(timerx_ch1_port, timerx_ch1_af, timerx_ch1_pin);
//// ch2
// 配置时钟
rcu_periph_clock_enable(timerx_ch2_port_rcu);
// 配置GPIO模式
gpio_mode_set(timerx_ch2_port, GPIO_MODE_AF, GPIO_PUPD_NONE, timerx_ch2_pin);
// 配置GPIO输出
gpio_output_options_set(timerx_ch2_port, GPIO_OTYPE_PP, GPIO_OSPEED_MAX, timerx_ch2_pin);
// 配置复用功能
gpio_af_set(timerx_ch2_port, timerx_ch2_af, timerx_ch2_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);
tops.outputnstate = TIMER_CCXN_ENABLE;
timer_channel_output_config(timerx, TIMER_CH_0, &tops);
// ch1
timer_channel_output_struct_para_init(&tops);
tops.outputnstate = TIMER_CCXN_ENABLE;
timer_channel_output_config(timerx, TIMER_CH_1, &tops);
// ch2
timer_channel_output_struct_para_init(&tops);
tops.outputnstate = TIMER_CCXN_ENABLE;
timer_channel_output_config(timerx, TIMER_CH_2, &tops);
////////// 输出模式配置
// ch0
timer_channel_output_mode_config(timerx, TIMER_CH_0, TIMER_OC_MODE_PWM1);
// ch1
timer_channel_output_mode_config(timerx, TIMER_CH_1, TIMER_OC_MODE_PWM1);
// ch2
timer_channel_output_mode_config(timerx, TIMER_CH_2, TIMER_OC_MODE_PWM1);
////////// 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点灯
- 实现通用定时器pwm点灯
- 实现高级定时器pwm点灯