(3)GD32E502C-START 开发板学习——TIMER输出PWM

本文详细讲解了在GD32502中使用高级定时器实现带死区的互补PWM波,涉及时钟配置、GPIO设置、PWM模式及死区时间控制。
摘要由CSDN通过智能技术生成

一、前言

        这一节开始分享定时器(TIMER)的功能,定时器的功能有很多,比如:常用的定时计数(延时)、电机驱动或电源驱动PWM波、系统的时间片中断服务函数等。本小节以输出一个带死区的互补PWM,先简单介绍PWM的基本实现原理及概念。

        下图信息:蓝色线是一个从0到99的三角载波(循环);红色线是一个30的比较器值(可理解为计数器计数到30)、黄色线是99的周期值(可理解为计数器计数到99)、绿色线是输出对应的PWM波。

       他们之间的数学关系有:

        CK_PSC是定时器时钟源频率,GD32502最大时钟频率为100MHz,也可以配置其他大小的时钟频率;

        PSC是预分频系数,若分频1,则分频系数为1;

        ARR是计数器计数最大值,此处为99;

        CCR是设定有效脉宽值,此处为30;

上述信息可得:PWM频率:Freq = 100MHz   / (1 + 1)/ (99 + 1)=  500KHz   

                         PWM占空比:Duty = 30   / (99 + 1)= 30%

                         PWM分辨率:Reso = 1 /(99 + 1)= 0.01

        为什么图中绿线计数器到0时,PWM波置高,计数器计数到脉宽值30置低呢?

        那是因为用到了输出比较控制器,根据输出比较寄存器设定的值与计数器计数的大小关系,从而来配置PWM输出的波形。

二、定时器介绍(TIMER)

        定时器主要分为三种(基本定时器、通用定时器、高级定时器):能够实现的功能依次增加,由于本文选择输出一个带死区的互补PWM波,结合下图可知只能选择定时器0/7/19/20(高级定时器),因此选择了定时器0。

        高级定时器的主要特征如下:

        如果要使用其他功能,请参考用户手册。为了实现带死区的互补PWM波需要使用到时钟源为内部时钟预分频器、计数模式向上计数PWM模式死区时间配置等。

三、配置代码步骤

       配置步骤如下:

        1、开启时钟及预分频器等(GPIO时钟、系统配置时钟、定时器时钟)

        2、配置GPIO引脚模式(输出PWM通道口)

        3、配置比较器模式及死区配置(上升沿、死区、影子寄存器、使能等)

        

        补充1:查找GD32502的数据手册可知,选用高级定时器TIME0,输出的两个通道引脚口分别为PE4(TIMER0_MCH1)和PE5(TIMER0_CH1)。

         补充2:GPIO引脚口复用功能选择,PE4和PE5功能为PWM发波(TIMER0_MCH1和TIMER0_CH1),故选择为AF1

        接下来,跟到我一起来实现开头那种绿色线的输出PWM波(频率500KHz、占空比30%)

        

        代码展示

#include "gd32e502.h"
#include <stdio.h>

void gpio_config(void)
{
	//打开GPIOE时钟
    rcu_periph_clock_enable(RCU_GPIOE);

	//设置GPIO模式   备用功能模式   带上拉电阻   GPIO_PIN_x
    gpio_mode_set(GPIOE, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_4 | GPIO_PIN_5);
    
	//设置GPIO输出模式和速度   推挽输出模式   最大输出速度50M   GPIO_PIN_x
	gpio_output_options_set(GPIOE, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_4 |         
    GPIO_PIN_5);
	
	//复用功能选择
	gpio_af_set(GPIOE, GPIO_AF_1, GPIO_PIN_4 | GPIO_PIN_5);
}


void timer_config(void)
{
    timer_parameter_struct timer_initpara;      //定时器0配置结构体名重定义
    timer_oc_parameter_struct timer_ocintpara;  //PWM模式配置结构体名重定义
    timer_break_parameter_struct timer_breakpara;  //死区结构体配置名重定义
   
	rcu_periph_clock_enable(RCU_TIMER0);  //初始化定时器0时钟
    timer_deinit(TIMER0);  //定时器默认初始化
	
    //定时器0配置
    timer_struct_para_init(&timer_initpara);
    timer_initpara.prescaler         = 1;  //预分配系数1
    timer_initpara.alignedmode       = TIMER_COUNTER_EDGE; //无中央对齐计数模式
    timer_initpara.counterdirection  = TIMER_COUNTER_UP;   //向上计数
    timer_initpara.period            = 99;                 //周期计数值(100-1)
    timer_initpara.clockdivision     = TIMER_CKDIV_DIV1;  //时钟分配因子  
    timer_initpara.repetitioncounter = 0;    //重新计数从0开始
    timer_init(TIMER0, &timer_initpara);
		

    // PWM模式配置
    timer_channel_output_struct_para_init(&timer_ocintpara);
    timer_ocintpara.outputstate  = TIMER_CCX_ENABLE;     //输出通道使能
    timer_ocintpara.outputnstate = TIMER_CCXN_ENABLE;	 //互补通道使能
    timer_ocintpara.ocpolarity   = TIMER_OC_POLARITY_HIGH;  //通道输出高电平
    timer_ocintpara.ocnpolarity  = TIMER_OCN_POLARITY_HIGH; //互补通道输出高电平
    timer_ocintpara.ocidlestate  = TIMER_OC_IDLE_STATE_LOW; //空闲状态下通道输出低电平
    timer_ocintpara.ocnidlestate = TIMER_OCN_IDLE_STATE_LOW;//空闲状态下互补通道输出低电平

    //选择定时器0通道CH1  
    timer_channel_output_config(TIMER0, TIMER_CH_1, &timer_ocintpara);

    //死区配置
    timer_break_struct_para_init(&timer_breakpara);
    timer_breakpara.runoffstate      = TIMER_ROS_STATE_DISABLE;
    timer_breakpara.ideloffstate     = TIMER_IOS_STATE_DISABLE ;
    timer_breakpara.deadtime         = 10;    //10*(1/100MHz)= 100ns
    timer_breakpara.breakpolarity    = TIMER_BREAK_POLARITY_HIGH;
    timer_breakpara.outputautostate  = TIMER_OUTAUTO_ENABLE;
    timer_breakpara.protectmode      = TIMER_CCHP_PROT_0;
    timer_breakpara.breakstate       = TIMER_BREAK_ENABLE;
    timer_break_config(TIMER0, &timer_breakpara);

	//PWM通路CH1/MCH1配置
    timer_channel_output_pulse_value_config(TIMER0, TIMER_CH_1, 30);  //占空比30%
    timer_channel_output_mode_config(TIMER0, TIMER_CH_1, TIMER_OC_MODE_PWM0);  //选择PWM0 
    模式
    timer_channel_output_shadow_config(TIMER0, TIMER_CH_1, TIMER_OC_SHADOW_DISABLE);  // 
    不使能影子寄存器
   
    timer_auto_reload_shadow_enable(TIMER0);     //自动重新装载使能
	timer_primary_output_config(TIMER0, ENABLE); //输出通道使能
	timer_enable(TIMER0); 						 //使能定时器0
}


int main(void)
{
    gpio_config();
    timer_config();
    while(1);
}

四、效果展示

        成功输出了一对互补PWM波,满足500KHz,占空比30%。(不带死区时间

        加了死区100ns后的PWM波,满足500KHz,占空比变为25%。(带死区时间

 预告:下一小节来实现DAC采样功能

  • 24
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值