以TIMER7为例,对定时器函数进行封装
注意事项:GD32中TIMER7是高级定时器,相关详细请参考上一篇文章。
//main.c
#include "gd32f4xx.h"
#include "systick.h"
#include
#include "main.h"
#include "Usart0.h"
#include "Timer.h"
float duty0 = 0;
float duty1 = 0;
float duty2 = 0;
void Usart0_on_recv(uint8_t* data, uint32_t len) {
printf("recv: %s\r\n", data);
if(data[0] == 0x00) {
// T2 ch0 +
Timer7_ch0_update(duty0++);
} else if(data[0] == 0x01) {
// T2 ch0 -
Timer7_ch0_update(duty0--);
} else if(data[0] == 0x02) {
// T2 ch1 +
Timer7_ch1_update(duty1++);
} else if(data[0] == 0x03) {
// T2 ch1 -
Timer7_ch1_update(duty1--);
} else if(data[0] == 0x04) {
// T2 ch2 +
Timer7_ch2_update(duty2++);
} else if(data[0] == 0x05) {
// T2 ch2 -
Timer7_ch2_update(duty2--);
}
}
int main(void)
{
systick_config();
Usart0_init();
Timer_init();
while(1) {
}
}
关心的内容
该代码中,data[0] == 0x00
等等是用来检查通过 USART0 (串口0) 接收到的数据的第一个字节是否为0x00
。这个data
数组是通过Usart0_on_recv
函数的参数传入的,而这个函数看起来是一个串口接收回调函数。
//Timer7.c
#include "Timer7.h"
#if USE_TIMER_7
void Timer7_init() {
// T7 ch0 ch1 ch2 ch3
// PC6 PC7 PC8
//哪个定时器
uint32_t timer_rcu = RCU_TIMER7;
uint32_t timer = TIMER7;
// uint32_t timer_rcu_psc = RCU_TIMER_PSC_MUL4;// 倍频
//定时器周期和分频
uint32_t timer_param_psc = TIMER7_PSC;
uint32_t timer_param_period = TIMER7_PERIOD;
/******************** GPIO *********************************/
// // PC6 PC7 PC8
//////////// ch0
#if TIMER7_CH0_ENABLE
// P和N
#if TIMER7_CH0_P_ENABLE
// gpio初始化 ch0
rcu_periph_clock_enable(TIMER7_CH0_P_PORT_RCU);
gpio_mode_set(TIMER7_CH0_P_PORT, GPIO_MODE_AF, GPIO_PUPD_NONE, TIMER7_CH0_P_PIN);
gpio_output_options_set(TIMER7_CH0_P_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_MAX, TIMER7_CH0_P_PIN);
gpio_af_set(TIMER7_CH0_P_PORT, TIMER7_CH0_P_AF, TIMER7_CH0_P_PIN);
#endif
#if TIMER7_CH0_N_ENABLE
// gpio初始化 ch0
rcu_periph_clock_enable(TIMER7_CH0_N_PORT_RCU);
gpio_mode_set(TIMER7_CH0_N_PORT, GPIO_MODE_AF, GPIO_PUPD_NONE, TIMER7_CH0_N_PIN);
gpio_output_options_set(TIMER7_CH0_N_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_MAX, TIMER7_CH0_N_PIN);
gpio_af_set(TIMER7_CH0_N_PORT, TIMER7_CH0_N_AF, TIMER7_CH0_N_PIN);
#endif
#endif
//////////// ch1
#if TIMER7_CH1_ENABLE
// P和N
#if TIMER7_CH1_P_ENABLE
// gpio初始化 ch0
rcu_periph_clock_enable(TIMER7_CH1_P_PORT_RCU);
gpio_mode_set(TIMER7_CH1_P_PORT, GPIO_MODE_AF, GPIO_PUPD_NONE, TIMER7_CH1_P_PIN);
gpio_output_options_set(TIMER7_CH1_P_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_MAX, TIMER7_CH1_P_PIN);
gpio_af_set(TIMER7_CH1_P_PORT, TIMER7_CH1_P_AF, TIMER7_CH1_P_PIN);
#endif
#if TIMER7_CH1_N_ENABLE
// gpio初始化 ch0
rcu_periph_clock_enable(TIMER7_CH1_N_PORT_RCU);
gpio_mode_set(TIMER7_CH1_N_PORT, GPIO_MODE_AF, GPIO_PUPD_NONE, TIMER7_CH1_N_PIN);
gpio_output_options_set(TIMER7_CH1_N_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_MAX, TIMER7_CH1_N_PIN);
gpio_af_set(TIMER7_CH1_N_PORT, TIMER7_CH1_N_AF, TIMER7_CH1_N_PIN);
#endif
#endif
//////////// ch2
#if TIMER7_CH2_ENABLE
// P和N
#if TIMER7_CH2_P_ENABLE
// gpio初始化 ch0
rcu_periph_clock_enable(TIMER7_CH2_P_PORT_RCU);
gpio_mode_set(TIMER7_CH2_P_PORT, GPIO_MODE_AF, GPIO_PUPD_NONE, TIMER7_CH2_P_PIN);
gpio_output_options_set(TIMER7_CH2_P_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_MAX, TIMER7_CH2_P_PIN);
gpio_af_set(TIMER7_CH2_P_PORT, TIMER7_CH2_P_AF, TIMER7_CH2_P_PIN);
#endif
#if TIMER7_CH2_N_ENABLE
// gpio初始化 ch0
rcu_periph_clock_enable(TIMER7_CH2_N_PORT_RCU);
gpio_mode_set(TIMER7_CH2_N_PORT, GPIO_MODE_AF, GPIO_PUPD_NONE, TIMER7_CH2_N_PIN);
gpio_output_options_set(TIMER7_CH2_N_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_MAX, TIMER7_CH2_N_PIN);
gpio_af_set(TIMER7_CH2_N_PORT, TIMER7_CH2_N_AF, TIMER7_CH2_N_PIN);
#endif
#endif
//////////// ch3
#if TIMER7_CH3_ENABLE
// P和N
#if TIMER7_CH3_P_ENABLE
// gpio初始化 ch0
rcu_periph_clock_enable(TIMER7_CH3_P_PORT_RCU);
gpio_mode_set(TIMER7_CH3_P_PORT, GPIO_MODE_AF, GPIO_PUPD_NONE, TIMER7_CH3_P_PIN);
gpio_output_options_set(TIMER7_CH3_P_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_MAX, TIMER7_CH3_P_PIN);
gpio_af_set(TIMER7_CH3_P_PORT, TIMER7_CH3_P_AF, TIMER7_CH3_P_PIN);
#endif
#if TIMER7_CH3_N_ENABLE
// gpio初始化 ch0
rcu_periph_clock_enable(TIMER7_CH3_N_PORT_RCU);
gpio_mode_set(TIMER7_CH3_N_PORT, GPIO_MODE_AF, GPIO_PUPD_NONE, TIMER7_CH3_N_PIN);
gpio_output_options_set(TIMER7_CH3_N_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_MAX, TIMER7_CH3_N_PIN);
gpio_af_set(TIMER7_CH3_N_PORT, TIMER7_CH3_N_AF, TIMER7_CH3_N_PIN);
#endif
#endif
/************************ timer ************************/
// 初始化定时器相关配置
rcu_periph_clock_enable(timer_rcu);
timer_deinit(timer);
timer_parameter_struct tps;
timer_struct_para_init(&tps);//配置默认值
// 根据实际需求去修改值
tps.prescaler = timer_param_psc;
tps.period = timer_param_period; // 周期计数(从0开始计数)
timer_init(timer, &tps);
/*************** timer CH 配置 **********************/
timer_oc_parameter_struct tops;
// 定时器通道配置 CH0
//////////////// ch0
#if TIMER7_CH0_ENABLE
timer_channel_output_struct_para_init(&tops);
// N和P
#if TIMER7_CH0_P_ENABLE
tops.outputstate = TIMER_CCX_ENABLE;
tops.ocpolarity = TIMER_OC_POLARITY_HIGH;
#endif
#if TIMER7_CH0_N_ENABLE
tops.outputnstate = TIMER_CCXN_ENABLE;
tops.ocnpolarity = TIMER_OCN_POLARITY_HIGH;
#endif
timer_channel_output_config(timer, TIMER_CH_0 , &tops);
timer_channel_output_mode_config(timer, TIMER_CH_0, TIMER_OC_MODE_PWM0);
timer_channel_output_pulse_value_config(timer, TIMER_CH_0, 0);//pwm值
#endif
//////////////////////////////////////////
#if TIMER7_CH1_ENABLE
// 定时器通道配置 CH1
timer_channel_output_struct_para_init(&tops);
// N和P
#if TIMER7_CH1_P_ENABLE
tops.outputstate = TIMER_CCX_ENABLE;
#endif
#if TIMER7_CH1_N_ENABLE
tops.outputnstate = TIMER_CCXN_ENABLE;
#endif
timer_channel_output_config(timer, TIMER_CH_1 , &tops);
timer_channel_output_mode_config(timer, TIMER_CH_1, TIMER_OC_MODE_PWM0);
timer_channel_output_pulse_value_config(timer, TIMER_CH_1, 0);//pwm值
#endif
#if TIMER7_CH2_ENABLE
// 定时器通道配置 CH2
timer_channel_output_struct_para_init(&tops);
// N和P
#if TIMER7_CH2_P_ENABLE
tops.outputstate = TIMER_CCX_ENABLE;
#endif
#if TIMER7_CH2_N_ENABLE
tops.outputnstate = TIMER_CCXN_ENABLE;
#endif
timer_channel_output_config(timer, TIMER_CH_2 , &tops);
timer_channel_output_mode_config(timer, TIMER_CH_2, TIMER_OC_MODE_PWM0);
timer_channel_output_pulse_value_config(timer, TIMER_CH_2, 0);//pwm值
#endif
#if TIMER7_CH3_ENABLE
timer_channel_output_struct_para_init(&tops);
#if TIMER7_CH3_P_ENABLE
tops.outputstate = TIMER_CCX_ENABLE;
#endif
#if TIMER7_CH3_N_ENABLE
tops.outputnstate = TIMER_CCXN_ENABLE;
#endif
timer_channel_output_config(timer, TIMER_CH_3 , &tops);
timer_channel_output_mode_config(timer, TIMER_CH_3, TIMER_OC_MODE_PWM0);
timer_channel_output_pulse_value_config(timer, TIMER_CH_3, 0);//pwm值
#endif
//只针对高级定时器,break,保护电路,打开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(timer, &tbps);
timer_break_enable(timer);
timer_enable(timer);
}
#if TIMER7_CH0_ENABLE
void Timer7_ch0_update(float duty){
uint32_t timer = TIMER7;
if(duty > 100) duty = 100;
if(duty < 0) duty = 0;
uint32_t count = TIMER7_PERIOD + 1;
uint32_t pulse = count * duty / 100 - 1;
//计数值
timer_channel_output_pulse_value_config(timer, TIMER_CH_0, pulse);//pwm值
}
#endif
#if TIMER7_CH1_ENABLE
void Timer7_ch1_update(float duty){
uint32_t timer = TIMER7;
if(duty > 100) duty = 100;
if(duty < 0) duty = 0;
uint32_t count = TIMER7_PERIOD + 1;
uint32_t pulse = count * duty / 100 - 1;
//计数值
timer_channel_output_pulse_value_config(timer, TIMER_CH_1, pulse);//pwm值
}
#endif
#if TIMER7_CH2_ENABLE
void Timer7_ch2_update(float duty){
uint32_t timer = TIMER7;
if(duty > 100) duty = 100;
if(duty < 0) duty = 0;
uint32_t count = TIMER7_PERIOD + 1;
uint32_t pulse = count * duty / 100 - 1;
//计数值
timer_channel_output_pulse_value_config(timer, TIMER_CH_2, pulse);//pwm值
}
#endif
#if TIMER7_CH3_ENABLE
void Timer7_ch3_update(float duty){
uint32_t timer = TIMER7;
if(duty > 100) duty = 100;
if(duty < 0) duty = 0;
uint32_t count = TIMER7_PERIOD + 1;
uint32_t pulse = count * duty / 100 - 1;
//计数值
timer_channel_output_pulse_value_config(timer, TIMER_CH_3, pulse);//pwm值
}
#endif
#endif
关心的内容
TIMER7高级定时器,四通道
这里的引脚分为P和N类型,不同引脚要配置不同的输出状态
所以封装过程中需要分类
P、N配置
//Timer7.h
#ifndef __TIMER_7_H__
#define __TIMER_7_H__
#include "Timer_config.h"
#if USE_TIMER_7
// 1. 基本timer,有中断函数
// 2. timer, 控制多个通道的duty变化
// 3. timer, 控制周期频率动态变化
// 4. ARM中有很多timer
void Timer7_init();
#if TIMER7_CH0_ENABLE
void Timer7_ch0_update(float duty);
#endif
#if TIMER7_CH1_ENABLE
void Timer7_ch1_update(float duty);
#endif
#if TIMER7_CH2_ENABLE
void Timer7_ch2_update(float duty);
#endif
#if TIMER7_CH3_ENABLE
void Timer7_ch3_update(float duty);
#endif
#endif
#endif
//Timer_config.h
#ifndef __TIMER_CONFIG_H__
#define __TIMER_CONFIG_H__
#include "gd32f4xx.h"
#include "systick.h"
#define USE_TIMER_0 0
#define USE_TIMER_1 0
#define USE_TIMER_2 0
#define USE_TIMER_3 0
#define USE_TIMER_4 0
#define USE_TIMER_5 0
#define USE_TIMER_6 0
#define USE_TIMER_7 1
#define USE_TIMER_8 0
#define USE_TIMER_9 0
#define USE_TIMER_10 0
#define USE_TIMER_11 0
#define USE_TIMER_12 0
#define USE_TIMER_13 0
/*************** Timer 0 *************/
/*************** Timer 1 *************/
/*************** Timer 2 *************/
#if USE_TIMER_2
// 0: output 1: base timer 2: input
#define TIMER2_FUNC 0
#if TIMER2_FUNC == 0
#define TIMER2_CH0_ENABLE 1
#define TIMER2_CH1_ENABLE 1
#define TIMER2_CH2_ENABLE 1
#define TIMER2_CH3_ENABLE 0
#endif
/**
* TIMER2_PSC (10 - 1)
* TIMER2_PERIOD (SystemCoreClock / 10000 - 1)
* 表示10秒执行10000次
*/
#define TIMER2_PSC (1 - 1)
#define TIMER2_PERIOD (SystemCoreClock / 10000 - 1)
#if TIMER2_CH0_ENABLE
// PA6(AF2),PB4(AF2),PC6(AF2)
#define TIMER2_CH0_PORT_RCU RCU_GPIOC
#define TIMER2_CH0_PORT GPIOC
#define TIMER2_CH0_PIN GPIO_PIN_6
#define TIMER2_CH0_AF GPIO_AF_2
#endif
#if TIMER2_CH1_ENABLE
//PA7,PB5,PC7
#define TIMER2_CH1_PORT_RCU RCU_GPIOC
#define TIMER2_CH1_PORT GPIOC
#define TIMER2_CH1_PIN GPIO_PIN_7
#define TIMER2_CH1_AF GPIO_AF_2
#endif
#if TIMER2_CH2_ENABLE
//PB0,PC8
#define TIMER2_CH2_PORT_RCU RCU_GPIOC
#define TIMER2_CH2_PORT GPIOC
#define TIMER2_CH2_PIN GPIO_PIN_8
#define TIMER2_CH2_AF GPIO_AF_2
#endif
#if TIMER2_CH3_ENABLE
//PB1,PC9
#define TIMER2_CH3_PORT_RCU RCU_GPIOC
#define TIMER2_CH3_PORT GPIOC
#define TIMER2_CH3_PIN GPIO_PIN_6
#define TIMER2_CH3_AF GPIO_AF_2
#endif
#endif
/***************************************/
/*************** Timer 7 **************/
/**************************************/
#if USE_TIMER_7
// 0: output 1: base timer 2: input
#define TIMER7_FUNC 0
#if TIMER7_FUNC == 0
#define TIMER7_CH0_ENABLE 1
#define TIMER7_CH1_ENABLE 1
#define TIMER7_CH2_ENABLE 1
#define TIMER7_CH3_ENABLE 0
#endif
#if TIMER7_CH0_ENABLE
#define TIMER7_CH0_P_ENABLE 1
#define TIMER7_CH0_N_ENABLE 1
#endif
#if TIMER7_CH1_ENABLE
#define TIMER7_CH1_P_ENABLE 0
#define TIMER7_CH1_N_ENABLE 1
#endif
#if TIMER7_CH2_ENABLE
#define TIMER7_CH2_P_ENABLE 0
#define TIMER7_CH2_N_ENABLE 1
#endif
#if TIMER7_CH3_ENABLE
#define TIMER7_CH3_P_ENABLE 0
#define TIMER7_CH3_N_ENABLE 1
#endif
/**
* TIMER2_PSC (10 - 1)
* TIMER2_PERIOD (SystemCoreClock / 10000 - 1)
* 表示10秒执行10000次
*/
#define TIMER7_PSC (1 - 1)
#define TIMER7_PERIOD (SystemCoreClock / 10000 - 1)
//////////////// ch0
#if TIMER7_CH0_P_ENABLE
// PA7(AF3),PB4(AF2),PC6(AF2)
#define TIMER7_CH0_P_PORT_RCU RCU_GPIOC
#define TIMER7_CH0_P_PORT GPIOC
#define TIMER7_CH0_P_PIN GPIO_PIN_6
#define TIMER7_CH0_P_AF GPIO_AF_3
#endif
#if TIMER7_CH0_N_ENABLE
// PA7(AF3),PB4(AF2),PC6(AF2)
#define TIMER7_CH0_N_PORT_RCU RCU_GPIOA
#define TIMER7_CH0_N_PORT GPIOA
#define TIMER7_CH0_N_PIN GPIO_PIN_5
#define TIMER7_CH0_N_AF GPIO_AF_3
#endif
//////////////////////////////////////////
//////////////// ch1
#if TIMER7_CH1_P_ENABLE
// PA7(AF3),PB4(AF2),PC6(AF2)
#define TIMER7_CH1_P_PORT_RCU RCU_GPIOC
#define TIMER7_CH1_P_PORT GPIOC
#define TIMER7_CH1_P_PIN GPIO_PIN_6
#define TIMER7_CH1_P_AF GPIO_AF_3
#endif
#if TIMER7_CH1_N_ENABLE
// PA7(AF3),PB4(AF2),PC6(AF2)
#define TIMER7_CH1_N_PORT_RCU RCU_GPIOA
#define TIMER7_CH1_N_PORT GPIOA
#define TIMER7_CH1_N_PIN GPIO_PIN_7
#define TIMER7_CH1_N_AF GPIO_AF_3
#endif
//////////////////////////////////////////
//////////////// ch2
#if TIMER7_CH2_P_ENABLE
// PA7(AF3),PB4(AF2),PC6(AF2)
#define TIMER7_CH2_P_PORT_RCU RCU_GPIOC
#define TIMER7_CH2_P_PORT GPIOC
#define TIMER7_CH2_P_PIN GPIO_PIN_6
#define TIMER7_CH2_P_AF GPIO_AF_3
#endif
#if TIMER7_CH2_N_ENABLE
// PA7(AF3),PB4(AF2),PC6(AF2)
#define TIMER7_CH2_N_PORT_RCU RCU_GPIOA
#define TIMER7_CH2_N_PORT GPIOA
#define TIMER7_CH2_N_PIN GPIO_PIN_7
#define TIMER7_CH2_N_AF GPIO_AF_3
#endif
//////////////////////////////////////////
//////////////// ch3
#if TIMER7_CH3_P_ENABLE
// PA7(AF3),PB4(AF2),PC6(AF2)
#define TIMER7_CH3_P_PORT_RCU RCU_GPIOC
#define TIMER7_CH3_P_PORT GPIOC
#define TIMER7_CH3_P_PIN GPIO_PIN_6
#define TIMER7_CH3_P_AF GPIO_AF_3
#endif
#if TIMER7_CH3_N_ENABLE
// PA7(AF3),PB4(AF2),PC6(AF2)
#define TIMER7_CH3_N_PORT_RCU RCU_GPIOA
#define TIMER7_CH3_N_PORT GPIOA
#define TIMER7_CH3_N_PIN GPIO_PIN_7
#define TIMER7_CH3_N_AF GPIO_AF_3
#endif
//////////////////////////////////////////
#endif
/*********************************************************/
#endif
以上是以高级定时器TIMER7和通用定时器TIMER2为例封装配置,可参考此流程封装配置GD32F4其余剩下的12个定时器。