GD32定时器相关配置和问题

定时器种类

GD32E230C一共有7个定时器,可以分为六种类型:

高级定时器0
通用定时器(L0)2
通用定时器(L2)13
通用定时器(L3)14
通用定时器(L4)15/16
基本定时器5。

PWM配置

  1. 时钟使能与复位
rcu_periph_clock_enable(RCU_TIMER0);
timer_deinit(TIMER0);

RCU时钟使能:开启TIMER0的时钟,所有外设需先使能时钟才能使用。

定时器复位:将TIMER0寄存器恢复默认值,确保配置从初始状态开始

  1. 定时器基础配置
timer_initpara.prescaler = 719;
timer_initpara.alignedmode = TIMER_COUNTER_EDGE;
timer_initpara.counterdirection = TIMER_COUNTER_UP;
timer_initpara.period = 49999;
timer_initpara.clockdivision = TIMER_CKDIV_DIV1;
timer_initpara.repetitioncounter = 0;
timer_init(TIMER0, &timer_initpara);

预分频器(Prescaler):719表示将系统时钟分频为720分频(720 = 719+1)。假设系统时钟为72MHz,则定时器时钟为72MHz / 720 = 100kHz。

计数模式:边缘对齐(无特殊对齐),向上计数。

周期(Period):自动重装载值设为49999,定时器每计满50000(49999+1)个周期触发更新。结合100kHz时钟,周期为50000 / 100kHz = 0.5秒。

时钟分频(Clock Division):不分频(TIMER_CKDIV_DIV1),用于滤波器,不影响频率。

重复计数器:0表示不重复(高级定时器功能)。

  1. PWM输出通道配置
timer_ocintpara.ocpolarity = TIMER_OC_POLARITY_HIGH;
timer_ocintpara.outputstate = TIMER_CCX_ENABLE;
timer_channel_output_config(TIMER0, TIMER_CH_1, &timer_ocintpara);

输出极性:高电平有效(PWM信号高电平为有效状态)。
输出使能:启用TIMER0通道1的输出功能。

  1. PWM参数设置
timer_channel_output_pulse_value_config(TIMER0, TIMER_CH_1, 24999);
timer_channel_output_mode_config(TIMER0, TIMER_CH_1, TIMER_OC_MODE_PWM0);

占空比设置:比较寄存器值设为24999。在向上计数模式下,当计数值小于24999时输出有效电平(高电平),之后无效(低电平),占空比为24999 / 50000 = 50%。

PWM模式:选择PWM模式0,定义有效电平在计数值小于比较值时有效。

  1. 高级配置与启动定时器
timer_primary_output_config(TIMER0, ENABLE);
timer_auto_reload_shadow_enable(TIMER0);
timer_enable(TIMER0);

主输出使能:针对高级定时器需启用主输出(TIMER0可能被误配置,需确认是否支持该功能)。
自动重装载预装载:允许ARR寄存器缓冲,避免运行时修改值导致异常。
启动定时器:使能TIMER0开始计数并输出PWM。

关键参数计算

PWM频率:100kHz / 50000 = 2Hz(周期0.5秒)。
占空比:50%(24999/50000)。

需要的参数

  1. 引脚和定时器对应,即引脚能够复用成对应定时器的通道口
  2. 引脚功能复用对应的复用代码,是AF0还是AF1等
  3. 高级定时器需要增加一行 (主输出配置:timer_primary_output_config)
### 配置GD32定时器中断 #### 中断配置概述 在GD32微控制器中,定时器中断的配置涉及多个步骤,包括使能时钟、初始化定时器参数以及设置相应的中断服务程序。通过合理配置这些组件可以实现精确的时间控制事件响应[^1]。 #### 初始化定时器并启用中断 为了启动一个具有特定时间间隔触发功能的定时器,在完成基本设定之后还需要开启更新中断(Update Interrupt)。这通常是在完成了计数模式的选择、预分频系数(PSC)与自动重装载值(ARR)定义等工作后的一步操作。当定时器达到其上限值时会触发一次溢出事件从而激活该类型的IRQ请求[^4]。 #### 清除标志位防止误触 值得注意的是,在某些情况下可能会遇到定时器一被初始化就立刻跳转到对应的ISR (Interrupt Service Routine),这是因为未清除之前可能存在的状态标记所引起的异常行为;因此建议每次重新加载或改变工作方式前都调用`timer_interrupt_flag_clear()`函数来清理相关联的状态指示符以确保正常运作[^3]。 #### 示例代码展示如何创建每毫秒发生一次的定时器中断: ```c #include "gd32f30x.h" void timer_init(void){ rcu_periph_clock_enable(RCU_TIMER13); /* 使能TIMER13外围设备时钟 */ timer_deinit(TIMER13); // 设置定时器为向上计数模式, 自动重载, 不允许缓冲寄存器写入 timer_parameter_struct timer_initpara; timer_initpara.prescaler = 89; // APB1=60Mhz/90=666KHz timer_initpara.alignedmode = TIMER_COUNTER_EDGE; timer_initpara.counterdirection = TIMER_COUNTER_UP; timer_initpara.period = 665; // ARR=(期望延时us*PCLK1)/(Prescaler+1)-1 timer_initpara.clockdivision = TIMER_CKDIV_DIV1; timer_initpara.repetitioncounter = 0; timer_init(TIMER13,&timer_initpara); nvic_irq_enable(TIMER13_IRQn, 0, 0); // 开启NVIC中的TIM13中断通道 timer_interrupt_flag_clear(TIMER13,TIMER_INT_FLAG_UPDATE); // 清楚任何现存的更新中断标志 timer_interrupt_enable(TIMER13,TIMER_INT_UPDATE); // 启用更新中断源 } // 定义中断处理函数 void TIMER13_IRQHandler(void){ if(timer_interrupt_flag_get(TIMER13,TIMER_INT_FLAG_UPDATE)!= RESET){ // 如果确实是由于更新而产生的中断,则执行下面的操作 // 插入您的应用程序逻辑此处... timer_interrupt_flag_clear(TIMER13,TIMER_INT_FLAG_UPDATE);// 处理完毕后再次清零此标志位 } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值