当前位置: 首页 > news >正文

掌握定时器基于GD32F407VE的天空星的配置

Timer定时器详解:从基础到高级应用

一、概述

定时器是现代微控制器中不可或缺的重要外设,它可以产生精确的时间间隔、延时、定时等功能,广泛应用于**定时、计数、脉冲宽度调制(PWM)**等领域。

  • 基本定时器:提供精确的时间基准和周期性中断
  • 通用定时器:支持PWM输出、输入捕获等高级功能
  • 高级定时器:满足复杂的控制需求,如电机驱动

定时器应用示意图

定时器的主要功能和应用场景

定时器功能应用场景描述实例
定时器定时LED闪烁定时器每隔一段时间触发中断,切换LED状态,实现定时闪烁效果。指示灯每秒闪烁一次,显示设备运行状态。
实时时钟(RTC)定时器每秒触发一次中断,用于更新时间信息。时钟更新显示时间,每分钟增加1。
定时器计数测量转速定时器计数旋转编码器的脉冲,计算出电机的转速。电机控制系统中实时测量转速,反馈调速信息。
事件计数计数生产线上通过的物品数量或其他事件次数。生产线计数器,记录产品通过的数量。
脉冲宽度调制(PWM)LED亮度调节通过改变PWM信号的占空比,实现从暗到亮的平滑过渡。调节台灯亮度,根据需求设置亮暗。
电机速度控制改变PWM信号的占空比控制电机的转速。控制小车电机转速,实现速度精准控制。
音频信号生成利用PWM生成特定频率音频信号。蜂鸣器报警,根据信号产生不同频率的警报音。

定时器工作原理

定时器本质上是一个电子计数器,通过计数系统时钟周期来实现定时功能。核心计算公式为:

计数值 = 系统主频 / 目标频率

例如:

  • 系统主频:168 MHz
  • 目标频率:10,000 Hz
  • 计数值 = 168,000,000 / 10,000 = 16,800

这意味着定时器需要计数16,800个系统时钟周期才能产生10kHz的定时事件。

GD32F4定时器分类

  • 基本定时器:用于简单的定时和计数
  • 通用定时器:功能丰富,适合信号测量、PWM生成
  • 高级定时器:专为高要求控制场景设计,如电机控制
    在这里插入图片描述

二、基本定时器

2.1 初始化配置

基本定时器的初始化步骤:

/*** @brief Timer定时器初始化配置* @param rcu   TIMER的RCU* @param timer_periph  TIMERx(x=0,1,2,3,4,5,6,7,8,9,10,11,12,13)* @param t_perscaler   分频系数* @param t_period      周期*/
static void timer_init_config(rcu_periph_enum rcu, uint32_t timer_periph,uint16_t t_perscaler, uint32_t t_period) {// 时钟使能rcu_periph_clock_enable(rcu);// 重置timer_deinit(timer_periph);// 定义结构体变量timer_parameter_struct initpara;// 给结构体成员配置默认值timer_struct_para_init(&initpara);// 修改关键成员// SystemCoreClock/用户指定的频率      用户指定的频率 >= 2564initpara.period = t_period - 1; // 周期initpara.prescaler = t_perscaler - 1;  // 分频  // 初始化定时器timer_init(timer_periph, &initpara);// 启动定时器timer_enable(timer_periph);
}
/*** @brief 输出通道配置* * @param timer_periph  TIMERx(x=0,1,2,3,4,5,6,7,8,9,10,11,12,13)* @param channel   	TIMER_CH_0, TIMER_CH_1, TIMER_CH_2, TIMER_CH_3* @param flag   		1 正极, 2 负极, 3 正负极*/
static void timer_channel_config(uint32_t timer_periph, uint16_t channel, uint8_t flag) {// ====================== PWM相关timer_oc_parameter_struct ocpara;// 初始化结构体默认参数timer_channel_output_struct_para_init(&ocpara);// 修改关键成员if (flag == 1) {ocpara.outputstate  = TIMER_CCX_ENABLE; // 正极} else if (flag == 2) { // 负极ocpara.outputnstate = TIMER_CCXN_ENABLE; // 负极} else { // 正负极ocpara.outputstate  = TIMER_CCX_ENABLE; // 正极ocpara.outputnstate = TIMER_CCXN_ENABLE; // 负极}// 输出通道配置timer_channel_output_config(timer_periph, channel, &ocpara);// 配置模式  TIMER_OC_MODE_PWM0 和  TIMER_OC_MODE_PWM1 相反timer_channel_output_mode_config(timer_periph, channel, TIMER_OC_MODE_PWM0);
}
/*** @brief 更新指定Timer的channel的占空比** @param timer_periph  TIMERx(x=0,1,2,3,4,5,6,7,8,9,10,11,12,13)* @param channel   TIMER_CH_0, TIMER_CH_1, TIMER_CH_2, TIMER_CH_3* @param t_period      周期 [1, 65536]* @param duty  		占空比 [0.0, 100.0]*/
void TIMER_channel_duty_update(uint32_t timer_periph, uint16_t channel, uint32_t t_period, float duty) {// 占空比timer_channel_output_pulse_value_config(timer_periph, channel,  (duty / 100.0) * (t_period - 1));
}

2.2 中断处理

定时器中断服务函数:
写在TIMER.c文件下面

// 定时器5中断函数
void TIMER5_DAC_IRQHandler() { if (SET == timer_interrupt_flag_get(TIMER5, TIMER_INT_FLAG_UP)) {timer_interrupt_flag_clear(TIMER5, TIMER_INT_FLAG_UP);TIMER5_irq_callback(); // 中断函数回调函数}
}

2.3 倍频和分频技术

在GD32中,定时器时钟可能经过倍频处理:

// 4倍频配置
//rcu_timer_clock_prescaler_config(RCU_TIMER_PSC_MUL4);
// 分频配置
//timer_initpara.prescaler = 10 - 1;  // 10分频/*** @brief 更新指定Timer的周期和分频** @param timer_periph  TIMERx(x=0,1,2,3,4,5,6,7,8,9,10,11,12,13)* @param period        周期 [1, 65536] * @param prescaler     分频系数 [1, 65536]*/
static void TIMER_period_prescaler_update(uint32_t timer_periph, uint32_t period, uint16_t prescaler) {timer_autoreload_value_config(timer_periph,  period-1); // 周期,自动重载值timer_prescaler_config(timer_periph, prescaler-1, TIMER_PSC_RELOAD_NOW); // 分频
}

分频系数的计算公式:

  • 真实频率 = 系统频率 / 分频系数
  • 实际周期值 = (系统频率 / 分频系数) / 目标频率 - 1

三、PWM与通用定时器

3.1 PWM原理

PWM(脉宽调制)通过调节信号的占空比来控制输出的平均电压:

PWM原理图

3.2 PWM输出配置

// 初始化
void Buzzer_init() {// PB9  复用推挽输出  AF1   IOGPIO_output_af(RCU_GPIOB, GPIOB, GPIO_PIN_9, GPIO_OTYPE_PP, GPIO_AF_1);timer_init_config(TIMER_RCU, TIMER_PERIPH, PRESCALER, SystemCoreClock/10000);// 定时器初始化  初始化1次timer_channel_config(TIMER_PERIPH, TIMER_CH); // 通道配置,配置1次
}
static void	PWM_config(u16 hz) {// 定时器1配置u16 period_t  = (SystemCoreClock / PRESCALER / hz);  // 时钟使能rcu_periph_clock_enable(TIMER_RCU);// 4倍频,最大值为168Mrcu_timer_clock_prescaler_config(RCU_TIMER_PSC_MUL4);// 重置timer_deinit(TIMER_PERIPH);// 定义结构体变量timer_parameter_struct initpara;// 给结构体成员配置默认值timer_struct_para_init(&initpara);// 修改关键成员// SystemCoreClock/用户指定的频率      用户指定的频率 >= 2564initpara.period = period_t - 1; // 周期initpara.prescaler = PRESCALER - 1;  // 分频  // 初始化定时器timer_init(TIMER_PERIPH, &initpara);// 启动定时器timer_enable(TIMER_PERIPH);// ====================== PWM相关timer_oc_parameter_struct ocpara;// 初始化结构体默认参数timer_channel_output_struct_para_init(&ocpara);// 修改关键成员ocpara.outputstate  = TIMER_CCX_ENABLE; // PWM和引脚关联了,后续可以输出方波// 输出通道配置timer_channel_output_config(TIMER_PERIPH, TIMER_CH, &ocpara);// 配置模式  TIMER_OC_MODE_PWM0 和  TIMER_OC_MODE_PWM1 相反timer_channel_output_mode_config(TIMER_PERIPH, TIMER_CH, TIMER_OC_MODE_PWM0);// 占空比timer_channel_output_pulse_value_config(TIMER_PERIPH, TIMER_CH,  0.5 * (period_t - 1));
}

3.3 动态调整占空比

/*** @brief 更新指定Timer的channel的占空比** @param timer_periph  TIMERx(x=0,1,2,3,4,5,6,7,8,9,10,11,12,13)* @param channel   TIMER_CH_0, TIMER_CH_1, TIMER_CH_2, TIMER_CH_3* @param t_period      周期 [1, 65536]* @param duty  		占空比 [0.0, 100.0]*/
static void TIMER_channel_duty_update(uint32_t timer_periph, uint16_t channel, uint32_t t_period, float duty) {// 占空比timer_channel_output_pulse_value_config(timer_periph, channel,  (duty / 100.0) * (t_period - 1));
}

3.4 蜂鸣器应用

利用PWM生成音频信号:


四、高级定时器

高级定时器(TIMER0和TIMER7)支持更复杂的功能,如互补PWM输出和死区控制。

4.1 互补PWM输出

	// 保护电路也是公共的// break 只针对高级定时器TIMER0 & TIMER7,需要打开互补保护电路/* TIMER通道互补保护电路 */timer_break_parameter_struct breakpara;/* 初始化TIMER break参数结构体 */timer_break_struct_para_init(&breakpara);/* break输入的极性 HIGH */breakpara.breakpolarity   = TIMER_BREAK_POLARITY_HIGH;/* 输出自动的启用 */breakpara.outputautostate = TIMER_OUTAUTO_ENABLE;/* bread输入的启用*/breakpara.breakstate     = TIMER_BREAK_ENABLE;/* 死区时间 [0, 255] */// breakpara.deadtime  = 128;/* 配置TIMER break */timer_break_config(TIMER0, &breakpara);/* 启用TIMER break */timer_break_enable(TIMER0);

4.2 死区时.间配置

防止互补输出同时导通:

breakpara.deadtime = 100;  // 设置死区时间

五、定时器库封装

为了提高代码复用性和可维护性,可以封装定时器驱动库:

5.1 配置文件

TIMER_config.h

#ifndef __TIMER_CONFIG_H__
#define __TIMER_CONFIG_H__#include "gd32f4xx.h"#define USE_TIMER_0     0  // 高级
#define USE_TIMER_1     0
#define USE_TIMER_2     0
#define USE_TIMER_3     1  // LED5 ~ 8
#define USE_TIMER_4     0
#define USE_TIMER_5     0  //基本
#define USE_TIMER_6     0  //基本
#define USE_TIMER_7     0 // 高级
#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#if USE_TIMER_0
// 启用TIMER0的情况下,才需要配置如下参数
#define TM0_PRESCALER   10
#define TM0_FREQ        1000
#define TM0_PERIOD      (SystemCoreClock / TM0_PRESCALER / TM0_FREQ)// TIMER0CHx对应的引脚所有参数
// TIMER0_CH0 ON  PE8
#define TM0_CH0_ON     RCU_GPIOE, GPIOE, GPIO_PIN_8, GPIO_OTYPE_PP, GPIO_AF_1
// TIMER0_CH0 OP  PE9
#define TM0_CH0_OP     RCU_GPIOE, GPIOE, GPIO_PIN_9, GPIO_OTYPE_PP, GPIO_AF_1//// TIMER0_CH1 ON  PE10
//#define TM0_CH1_ON     RCU_GPIOE, GPIOE, GPIO_PIN_10, GPIO_OTYPE_PP, GPIO_AF_1
//// TIMER0_CH1 OP  PE11
//#define TM0_CH1_OP     RCU_GPIOE, GPIOE, GPIO_PIN_11, GPIO_OTYPE_PP, GPIO_AF_1#endif#if USE_TIMER_1
// 启用TIMER1的情况下,才需要配置如下参数
#define TM1_PRESCALER   10
#define TM1_FREQ        1000
#define TM1_PERIOD      (SystemCoreClock / TM1_PRESCALER / TM1_FREQ)// TIMER1CHx对应的引脚所有参数
// #define TM1_CH0        RCU_GPIOA, GPIOA, GPIO_PIN_8, GPIO_AF_2
#define TM1_CH1        RCU_GPIOB, GPIOB, GPIO_PIN_9, GPIO_AF_1#endif#if USE_TIMER_3
// 启用TIMER3的情况下,才需要配置如下参数
#define TM3_PRESCALER   10
#define TM3_FREQ        1000
#define TM3_PERIOD      (SystemCoreClock / TM3_PRESCALER / TM3_FREQ)// TIMER3CHx对应的引脚所有参数
#define TM3_CH0        RCU_GPIOD, GPIOD, GPIO_PIN_12, GPIO_OTYPE_PP, GPIO_AF_2
#define TM3_CH1        RCU_GPIOD, GPIOD, GPIO_PIN_13, GPIO_OTYPE_PP, GPIO_AF_2
#define TM3_CH2        RCU_GPIOD, GPIOD, GPIO_PIN_14, GPIO_OTYPE_PP, GPIO_AF_2
#define TM3_CH3        RCU_GPIOD, GPIOD, GPIO_PIN_15, GPIO_OTYPE_PP, GPIO_AF_2
#endif#endif

5.2 统一接口函数

TIMER.h文件

#ifndef __TIMER_H__
#define __TIMER_H__#include "gd32f4xx.h"
#include "TIMER_config.h"// 初始化
void TIMER_init();/*** @brief 更新指定Timer的channel的占空比** @param timer_periph  TIMERx(x=0,1,2,3,4,5,6,7,8,9,10,11,12,13)* @param channel   	TIMER_CH_0, TIMER_CH_1, TIMER_CH_2, TIMER_CH_3* @param t_period      周期 [1, 65536]* @param duty  		占空比 [0.0, 100.0]*/
void TIMER_channel_duty_update(uint32_t timer_periph, uint16_t channel, uint32_t t_period, float duty);#endif

TIMER.c文件

#include "TIMER.h"
#include "gpio_cfg.h"/*** @brief Timer定时器初始化配置** @param rcu   TIMER的RCU* @param timer_periph  TIMERx(x=0,1,2,3,4,5,6,7,8,9,10,11,12,13)* @param t_perscaler   分频系数* @param t_period      周期*/
static void timer_init_config(rcu_periph_enum rcu, uint32_t timer_periph,uint16_t t_perscaler, uint32_t t_period) {// 时钟使能rcu_periph_clock_enable(rcu);// 重置timer_deinit(timer_periph);// 定义结构体变量timer_parameter_struct initpara;// 给结构体成员配置默认值timer_struct_para_init(&initpara);// 修改关键成员// SystemCoreClock/用户指定的频率      用户指定的频率 >= 2564initpara.period = t_period - 1; // 周期initpara.prescaler = t_perscaler - 1;  // 分频  // 初始化定时器timer_init(timer_periph, &initpara);// 启动定时器timer_enable(timer_periph);
}/*** @brief 输出通道配置* * @param timer_periph  TIMERx(x=0,1,2,3,4,5,6,7,8,9,10,11,12,13)* @param channel   	TIMER_CH_0, TIMER_CH_1, TIMER_CH_2, TIMER_CH_3* @param flag   		1 正极, 2 负极, 3 正负极*/
static void timer_channel_config(uint32_t timer_periph, uint16_t channel, uint8_t flag) {// ====================== PWM相关timer_oc_parameter_struct ocpara;// 初始化结构体默认参数timer_channel_output_struct_para_init(&ocpara);// 修改关键成员if (flag == 1) {ocpara.outputstate  = TIMER_CCX_ENABLE; // 正极} else if (flag == 2) { // 负极ocpara.outputnstate = TIMER_CCXN_ENABLE; // 负极} else { // 正负极ocpara.outputstate  = TIMER_CCX_ENABLE; // 正极ocpara.outputnstate = TIMER_CCXN_ENABLE; // 负极}// 输出通道配置timer_channel_output_config(timer_periph, channel, &ocpara);// 配置模式  TIMER_OC_MODE_PWM0 和  TIMER_OC_MODE_PWM1 相反timer_channel_output_mode_config(timer_periph, channel, TIMER_OC_MODE_PWM0);
}/*** @brief 更新指定Timer的channel的占空比** @param timer_periph  TIMERx(x=0,1,2,3,4,5,6,7,8,9,10,11,12,13)* @param channel   TIMER_CH_0, TIMER_CH_1, TIMER_CH_2, TIMER_CH_3* @param t_period      周期 [1, 65536]* @param duty  		占空比 [0.0, 100.0]*/
void TIMER_channel_duty_update(uint32_t timer_periph, uint16_t channel, uint32_t t_period, float duty) {// 占空比timer_channel_output_pulse_value_config(timer_periph, channel,  (duty / 100.0) * (t_period - 1));
}// 初始化
void TIMER_init() {// 4倍频,最大值为168Mrcu_timer_clock_prescaler_config(RCU_TIMER_PSC_MUL4);#if USE_TIMER_0   // ====== 定时器0// 公共的// 定时器初始化配置timer_init_config(RCU_TIMER0, TIMER0, TM0_PRESCALER, TM0_PERIOD); // ====== 通道0 ==========// 如果有定义TM0_CH0_ON 和 TM0_CH0_OP 两个宏,不关心定义#if defined (TM0_CH0_ON) &&  defined (TM0_CH0_OP)// 引脚IOGPIO_output_af(TM0_CH0_ON);GPIO_output_af(TM0_CH0_OP);// 通道配置timer_channel_config(TIMER0, TIMER_CH_0, 3); // 3为正负极#endif// ====== 通道1 ==========#if defined (TM0_CH1_ON) &&  defined (TM0_CH1_OP)// 引脚IOGPIO_output_af(TM0_CH1_ON);GPIO_output_af(TM0_CH1_OP);// 通道配置timer_channel_config(TIMER0, TIMER_CH_1, 3); // 3为正负极#endif// 保护电路也是公共的// break 只针对高级定时器TIMER0 & TIMER7,需要打开互补保护电路/* TIMER通道互补保护电路 */timer_break_parameter_struct breakpara;/* 初始化TIMER break参数结构体 */timer_break_struct_para_init(&breakpara);/* break输入的极性 HIGH */breakpara.breakpolarity   = TIMER_BREAK_POLARITY_HIGH;/* 输出自动的启用 */breakpara.outputautostate = TIMER_OUTAUTO_ENABLE;/* bread输入的启用*/breakpara.breakstate     = TIMER_BREAK_ENABLE;/* 死区时间 [0, 255] */// breakpara.deadtime  = 128;/* 配置TIMER break */timer_break_config(TIMER0, &breakpara);/* 启用TIMER break */timer_break_enable(TIMER0);#endif#if USE_TIMER_3   // ====== 定时器3// 公共的 定时器初始化配置timer_init_config(RCU_TIMER3, TIMER3, TM3_PRESCALER, TM3_PERIOD); // ============ 通道#if defined (TM3_CH0)GPIO_output_af(TM3_CH0);timer_channel_config(TIMER3, TIMER_CH_0, 1); // 1为正极#endif#if defined (TM3_CH1)GPIO_output_af(TM3_CH1);timer_channel_config(TIMER3, TIMER_CH_1, 1); // 1为正极#endif#if defined (TM3_CH2)GPIO_output_af(TM3_CH2);timer_channel_config(TIMER3, TIMER_CH_2, 1); // 1为正极#endif#if defined (TM3_CH3)GPIO_output_af(TM3_CH3);timer_channel_config(TIMER3, TIMER_CH_3, 1); // 1为正极#endif#endif}
http://www.dtcms.com/a/466957.html

相关文章:

  • 补充:计算点到原点的距离。(new)
  • 北京网站建设 专业10年郑州艾特网站建设公司
  • 陕西做网站的公司在哪江苏建设行业证书编号查询网站
  • 元服务发布准备工作
  • 【2025-系统规划与管理师】第七章:网络环境规划
  • 固态硬盘保护器Romex Software
  • 如室设计网站东莞房价多少
  • 创建网站超市百度找不到 网站
  • 超参数优化利器:GridSearchCV 详解与实战指南
  • 网站建设合同需要注意什么创意赣州网站建设
  • 从 Wonderware 到 TDengine:大理卷烟厂的国产化转型之路
  • Redis-Bitmaps、HyperLogLog、GEO类型
  • 一级a做爰片i网站商城网站前期推广
  • Golang的结构体和反射
  • 网站点击量软件古腾堡布局的网站
  • 网站title优化手机网页页面设计模板
  • 湛江正规网站制作方案网站建设五项基本原则
  • 【Vue】——路由
  • 160 国际英文网站app开发公司哪里好
  • 企业网站优化哪家好陕西住房与城乡建设部网站
  • 小模型大智慧:新一代轻量化语言模型全解析
  • 网站首页背景代码wordpress幻灯片不显示
  • 37.2多点电容触摸屏实验(详细代码)_csdn
  • 了解学习MySQL数据库基础
  • 做网站怎么选服务器服务器网站怎么做
  • 长沙微信网站开发学习网页制作学什么
  • 超越RTL的系统设计:ESL设计的新范式与CIRCT的桥梁作用
  • JVM的即时编译JIT的介绍
  • 网站建设心得8000字网站域名设计推荐
  • 十堰哪里有做网站的搜索引擎营销的案例有哪些