GD32篇 二、GD32TIMER输出PWM

2 篇文章 1 订阅
2 篇文章 0 订阅

GD32篇 记录

一、GD32开发版程序设置读保护,防止程序被读取

二、GD32TIMER输出PWM


前言

一、GD32F103 的TIMER特点

可以在中文手册里面找到相关的资料
在这里插入图片描述
在这里插入图片描述

二、通用定时器 L0(TIMERx, x=1,2,3,4)

简介

通用定时器L0(定时器1/2/3/4)是4通道定时器,支持输入捕获,输出比较,产生PWM信号控
制电机和电源管理。通用定时器L0计数器是16位无符号计数器。
通用定时器L0是可编程的,可以被用来计数,其外部事件可以驱动其他定时器。
定时器和定时器之间是相互独立,但是他们可以被同步在一起形成一个更大的定时器,这些定
时器的计数器一致地增加。

2.主要特征

 总通道数:4;  计数器宽度:16位;
 时钟源可选:内部时钟,内部触发,外部输入,外部触发;
 多种计数模式:向上计数,向下计数和中央对齐计数;
 正交编码器接口:被用来追踪运动和分辨旋转方向和位置;
 霍尔传感器接口:用来做三相电机控制;
 可编程的预分频器:16位,运行时可以被改变;
 每个通道可配置:输入捕获模式,输出比较模式,可编程的PWM模式,单脉冲模式;
 自动重装载功能;
 中断输出和DMA请求:更新事件,触发事件,比较/捕获事件;
 多个定时器的菊型链接使得一个定时器可以同时启动多个定时器;
 定时器的同步允许被选择的定时器在同一个时钟周期开始计数;
 定时器主/从模式控制器。


三、输出比较模式

在输出比较模式,TIMERx可以产生时控脉冲,其位置,极性,持续时间和频率都是可编程的。
当一个输出通道的CxCV寄存器与计数器的值匹配时,根据CHxCOMCTL的配置,这个通道的
输出可以被置高电平,被置低电平或者反转。当计数器的值与CxCV寄存器的值匹配时,CHxIF
位被置1,如果CHxIE = 1则会产生中断,如果CxCDE=1则会产生DMA请求。

配置步骤如下:

第一步:时钟配置:
配置定时器时钟源,预分频器等。

第二步:比较模式配置:
设置CHxCOMSEN位来配置输出比较影子寄存器;
设置CHxCOMCTL位来配置输出模式(置高电平/置低电平/反转);
设置CHxP/CHxNP位来选择有效电平的极性;
设置CHxEN使能输出。

第三步:通过CHxIE/CxCDE位配置中断/DMA请求使能。

第四步:通过TIMERx_CAR寄存器和TIMERx_CHxCV寄存器配置输出比较时基:
CxCV可以在运行时根据你所期望的波形而改变。

第五步:设置CEN位使能定时器。

代码如下:

void timer_config(void)
{
    rcu_periph_clock_enable(RCU_GPIOA);
    rcu_periph_clock_enable(RCU_AF);

    /*Configure PA1 PA2 PA3(TIMER1 CH1 CH2 CH3) as alternate function*/
    gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_1);
   
    timer_oc_parameter_struct timer_ocintpara;
    timer_parameter_struct timer_initpara;

    rcu_periph_clock_enable(RCU_TIMER1);

    timer_deinit(TIMER1);

    /* TIMER1 configuration */
    timer_initpara.prescaler         = 107;	//预分频 108M / 107 + 1 = 1M 
    timer_initpara.alignedmode       = TIMER_COUNTER_EDGE;	//无中央对齐计数模式(边沿对齐模式),DIR位指定了计数方向
    timer_initpara.counterdirection  = TIMER_COUNTER_UP;	//向上计数
    timer_initpara.period            = 1000;	// 1M / 1000 = 1000Hz
    timer_initpara.clockdivision     = TIMER_CKDIV_DIV1;	
    timer_initpara.repetitioncounter = 0;
    timer_init(TIMER1,&timer_initpara);

    /* CH1,CH2 and CH3 configuration in PWM mode1 */
    timer_ocintpara.ocpolarity   = TIMER_OC_POLARITY_HIGH;	
    timer_ocintpara.outputstate  = TIMER_CCX_ENABLE;
    timer_ocintpara.ocnpolarity  = TIMER_OCN_POLARITY_HIGH;
    timer_ocintpara.outputnstate = TIMER_CCXN_DISABLE;
    timer_ocintpara.ocidlestate  = TIMER_OC_IDLE_STATE_LOW;
    timer_ocintpara.ocnidlestate = TIMER_OCN_IDLE_STATE_LOW;

    timer_channel_output_config(TIMER1,TIMER_CH_1,&timer_ocintpara);//选择通道1	

    /* CH1 configuration in PWM mode1,duty cycle 25% */
    timer_channel_output_pulse_value_config(TIMER1,TIMER_CH_1,500 );// 设置占空比50%
    timer_channel_output_mode_config(TIMER1,TIMER_CH_1,TIMER_OC_MODE_PWM0);
    timer_channel_output_shadow_config(TIMER1,TIMER_CH_1,TIMER_OC_SHADOW_DISABLE);



    /* auto-reload preload enable */
    timer_auto_reload_shadow_enable(TIMER1);
    /* auto-reload preload enable */
    timer_enable(TIMER1);
}

int main(void)
{
    timer_config();

    while (1);

}

几个用到的函数说明

timer_enable(TIMER1);

在这里插入图片描述

timer_auto_reload_shadow_enable(TIMER1);

在这里插入图片描述

timer_channel_output_config(TIMER1,TIMER_CH_1,&timer_ocintpara);//选择通道1

在这里插入图片描述

timer_channel_output_pulse_value_config(TIMER1,TIMER_CH_1,500 );// 设置占空比50%

在这里插入图片描述

timer_channel_output_mode_config(TIMER1,TIMER_CH_1,TIMER_OC_MODE_PWM0);

在这里插入图片描述

timer_channel_output_shadow_config(TIMER1,TIMER_CH_1,TIMER_OC_SHADOW_DISABLE);

在这里插入图片描述

四、总结

总之就是,
一,先确定使用哪一个定时器,哪一个通道
二、去找到定时器对应的GPIO
三、设置定时器的参数,预分频系数,周期,向上向下计数等等
四、选择通道输出
五、选择输出比较值,即占空比
六、使能定时器
七、在主函数调用定时器初始化函数

  • 4
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
首先,你需要将Timer1的CH0配置为PWM输出模式,并设置PWM的频率和占空比。然后,你需要使用DMA将PWM数据传输到Timer1的CCR寄存器中。 下面是一个简单的示例代码来实现这个功能: ```c // 定义PWM输出的频率和占空比 #define PWM_FREQ 10000 #define PWM_DUTY_CYCLE 50 // 初始化Timer1 CH0为PWM输出模式 void TIM1_CH0_PWM_Init(void) { // 使能Timer1时钟 rcu_periph_clock_enable(RCU_TIMER1); // 配置Timer1 CH0为PWM输出模式 timer_oc_parameter_struct timer_ocinitpara; timer_ocinitpara.oc_mode = TIMER_OC_MODE_PWM0; timer_ocinitpara.output_state = TIMER_CCX_ENABLE; timer_ocinitpara.output_nstate = TIMER_CCXN_DISABLE; timer_ocinitpara.oc_polarity = TIMER_OC_POLARITY_HIGH; timer_ocinitpara.oc_npolarity = TIMER_OCCP_NO_CHANGE; timer_ocinitpara.oc_idle_state = TIMER_OC_IDLE_STATE_LOW; timer_ocinitpara.oc_nidle_state = TIMER_OCNIDLE_STATE_NO_CHANGE; timer_channel_output_config(TIMER1, TIMER_CH_0, &timer_ocinitpara); // 配置Timer1的预分频器和重载值,计算PWM周期 timer_parameter_struct timer_initpara; timer_initpara.prescaler = SystemCoreClock / PWM_FREQ / 1000000 - 1; timer_initpara.alignedmode = TIMER_COUNTER_EDGE_ALIGNED_PWM_MODE; timer_initpara.counterdirection = TIMER_COUNTER_UP; timer_initpara.period = (1000000 / PWM_FREQ) - 1; timer_initpara.clockdivision = TIMER_CKDIV_DIV1; timer_init(TIMER1, &timer_initpara); // 配置PWM占空比 uint16_t duty_cycle = ((100 - PWM_DUTY_CYCLE) * (timer_initpara.period + 1)) / 100; timer_channel_output_pulse_value_config(TIMER1, TIMER_CH_0, duty_cycle); // 使能Timer1 timer_enable(TIMER1); } // 定义要输出PWM数据 #define PWM_DATA_SIZE 100 uint16_t pwm_data[PWM_DATA_SIZE]; // 初始化DMA void DMA_Init(void) { // 使能DMA时钟 rcu_periph_clock_enable(RCU_DMA); // 配置DMA通道0 dma_parameter_struct dma_initpara; dma_struct_para_init(&dma_initpara); dma_deinit(DMA0, DMA_CH0); dma_initpara.direction = DMA_MEMORY_TO_PERIPHERAL; dma_initpara.memory_addr = (uint32_t)pwm_data; dma_initpara.memory_inc = DMA_MEMORY_INCREASE_ENABLE; dma_initpara.periph_addr = (uint32_t)(&TIMER1->CCR0); dma_initpara.periph_inc = DMA_PERIPH_INCREASE_DISABLE; dma_initpara.memory_width = DMA_MEMORY_WIDTH_16BIT; dma_initpara.periph_width = DMA_PERIPHERAL_WIDTH_16BIT; dma_initpara.number = PWM_DATA_SIZE; dma_initpara.priority = DMA_PRIORITY_ULTRA_HIGH; dma_initpara.circular_mode = DMA_CIRCULAR_MODE_ENABLE; dma_init(DMA0, DMA_CH0, &dma_initpara); // 使能DMA通道0 dma_channel_enable(DMA0, DMA_CH0); } int main(void) { // 初始化PWM输出 TIM1_CH0_PWM_Init(); // 初始化DMA DMA_Init(); // 填充PWM数据 for (int i = 0; i < PWM_DATA_SIZE; i++) { pwm_data[i] = (i & 1) ? 0 : ((100 - PWM_DUTY_CYCLE) * (TIMER1->ARR + 1)) / 100; } while (1) { // 无限循环等待 } } ``` 这个示例代码中,首先通过`TIM1_CH0_PWM_Init()`函数初始化Timer1 CH0为PWM输出模式,并设置PWM的频率和占空比。然后,通过`DMA_Init()`函数初始化DMA通道0,将PWM数据传输到Timer1的CCR寄存器中。最后,通过填充`pwm_data`数组来生成PWM波形。在主函数中,使用一个无限循环来等待。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值