Stark_GS · 2022年11月25日 · 广东

【GD32F427开发板试用】03-PWM单通道输出

【GD32F427开发板试用】03-PWM单通道输出


定时器和PWM产生简介及特点

高级定时器:(TIMER0、TIMER7)

高级定时器( TIMER0、TIMER7 )是四通道定时器,支持输入捕获和输出比较。可以产生 PWM 信号控制电机和电源管理。高级定时器含有一个 16 位无符号计数器。高级定时器是可编程的,可以被用来计数,其外部事件可以驱动其他定时器高级定时器包含了一个死区时间插入模块,非常适合电机控制。定时器和定时器之间是相互独立,但是他们可以被同步在一起形成一个更大的定时器,这些定时器的计数器一致地增加。

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

通用定时器L0:( TIMER1 TIMER2 TIMER3 TIMER4 )

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

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

通用定时器L1:( TIMER8 TIMER11 )

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

  • 总通道数: 2;
  • 计数器宽度: 16位;
  • 时钟源可选:内部时钟,内部触发,外部输入,外部触发;
  • 计数模式:向上计数;
  • 可编程的预分频器: 16位,运行时可以被改变;
  • 每个通道可配置:输入捕获模式,输出比较模式,可编程的PWM模式,单脉冲模式;
  • 自动重装载功能;
  • 中断输出:更新事件,触发事件,比较/捕获事件和中止事件;
  • 多个定时器的菊链使得一个定时器可以同时启动多个定时器;
  • 定时器的同步允许被选择的定时器在同一个时钟周期开始计数;
  • 定时器主-从管理

通用定时器L2:( TIMER9 TIMER10 TIMER12 TIME13 )

通用定时器 L2(TIMERx, x=9, 10, 12, 13) 是单通道定时器,支持输入捕获和输出比较,产生
PWM 信号控制电机和电源管理。通用定时器 L2 含有一个 16 位无符号计数器。
高级定时器是可编程的,可以被用来计数,其外部事件可以驱动其他定时器

  • 总通道数: 1;
  • 计数器宽度: 16位;
  • 时钟源只有内部时钟
  • 计数模式:计数模式:向上计数,向下计数和中央计数;
  • 可编程的预分频器: 16位,运行时可以被改变;
  • 每个通道可配置:输入捕获模式,输出比较模式,可编程的PWM模式,单脉冲模式;
  • 自动重装载功能;
  • 中断输出:更新事件,触发事件,比较/捕获事件和中止事件。

基本定时器( TIMER4 TIMER5 )

基本定时器( TIMER4 TIMER5 ) 包含一个无符号 16 位计数器。可以被用作通用定时器和为 DAC (数字到模拟转换器) 提供时钟。基本定时器可以配置产生 DMA 请求, TRGO 触发连接到 DAC。

  • 计数器宽度: 16位;
  • 时钟源只有内部时钟;
  • 计数模式:向上计数;
  • 可编程的预分频器: 16位,运行时可以被改变;
  • 自动重装载功能;
  • 中断输出和DMA请求:更新事件;

开发环境&参考文档

  • Keil-MDK 5.27.1.0
  • Windows11
  • 固件库-GD32F4xx_Firmware_Library_V3.0.2
  • GD32F427xx_Datasheet_Rev1.2
  • GD32F4xx_User_Manual_Rev2.7_CN
  • GD32F4xx 固件库使用指南_V1.0

代码部分

根据定时器的简介及特点大致了解到

  • TIMER0 TIMER7 这两个定时器适合做电机控制(带死区插入功能)
  • TIMER0、TIMER1 TIMER2 这三个定时器具有编码器的接口,其中 TIMER2、TIMER3 还具有霍尔的接口

这里我们使用 TIMER13 配置输出单通道 PWM (端口为 PA7)

pwm.h 文件

#ifndef _PWM_H_
#define _PWM_H_

#include "gd32f4xx.h"


void PWM_Init(void);

#endif


pwm.c 文件

这里需要注意的是Timer和APB1 APB2时钟之间还有一个倍频,这个地方需要特别注意,具体可以看时钟树,在数据手册2.5章,用户手册的4.2.1章都能找到的

#include "pwm.h"


void PWM_Init(void)
{
    //其中PA7 和 PB1 具有 TIMER13 的通道0 功能
    timer_parameter_struct Timer_ParamType;
    timer_oc_parameter_struct Timer_OC_ParamType;
    
    rcu_periph_clock_enable(RCU_GPIOA);//启用外设时钟功能
    rcu_periph_clock_enable(RCU_TIMER13);
    
    
    gpio_af_set(GPIOA,GPIO_AF_9,GPIO_PIN_7);//端口复用为TIMER13_CH0模式
    
    gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_7);
    gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_7);
    gpio_bit_set(GPIOA, GPIO_PIN_7);
    

    timer_deinit(TIMER13);
    
    timer_channel_output_mode_config(TIMER13,TIMER_CH_0,TIMER_OC_MODE_PWM0);    //配置通道输出模式

    Timer_OC_ParamType.ocidlestate = TIMER_OC_IDLE_STATE_HIGH;                    //空闲时通道输出极性
    Timer_OC_ParamType.ocnidlestate = TIMER_OCN_IDLE_STATE_LOW;                    //空闲时互补通道输出极性
    Timer_OC_ParamType.ocnpolarity = TIMER_OCN_POLARITY_HIGH;                    //互补通道输出极性
    Timer_OC_ParamType.ocpolarity = TIMER_OC_POLARITY_HIGH;                        //通道输出极性
    Timer_OC_ParamType.outputnstate = TIMER_CCXN_DISABLE;                        //禁用互补通道输出
    Timer_OC_ParamType.outputstate = TIMER_CCX_ENABLE;                            //使能通道输出
    timer_channel_output_config(TIMER13,TIMER_CH_0,&Timer_OC_ParamType);
    
    Timer_ParamType.alignedmode = TIMER_COUNTER_EDGE;                            //配置为边沿对其模式
    Timer_ParamType.clockdivision = TIMER_CKDIV_DIV1;                            //配置死区时间和采样时钟(DTS)之间的分频系数
    Timer_ParamType.counterdirection = TIMER_COUNTER_UP;                        //配置计数方向为向上计数
    Timer_ParamType.period = 1000-1;                                            //周期
    Timer_ParamType.prescaler = 100-1;                                            //预分频
    Timer_ParamType.repetitioncounter = 1;
    timer_init(TIMER13,&Timer_ParamType);
    
    timer_channel_output_pulse_value_config(TIMER13, TIMER_CH_0, 500-1);        //比较寄存器的数值
    
    timer_enable(TIMER13);
}

主函数

#include "gd32f4xx.h"
#include "systick.h"
#include <stdio.h>

#include "gpio.h"
#include "pwm.h"

int main(void)
{
    systick_config();    //配置系统时钟
    
    GPIO_Init();
    PWM_Init();

    while(1) 
    {
        gpio_bit_toggle(GPIOC, GPIO_PIN_6);    //反转PC6
        delay_1ms(200);
    }
}

PWM 波形

SDS00002.png

推荐阅读
关注数
4
文章数
14
目录
极术微信服务号
关注极术微信号
实时接收点赞提醒和评论通知
安谋科技学堂公众号
关注安谋科技学堂
实时获取安谋科技及 Arm 教学资源
安谋科技招聘公众号
关注安谋科技招聘
实时获取安谋科技中国职位信息