零基础国产GD32单片机编程入门(六)PWM波输出实战含源码

一.概要

脉冲宽度调制(PWM),是英文“Pulse Width Modulation”的缩写,简称脉宽调制,是利用单片机数字输出(1或0)来对外部模拟电路进行控制的一种非常有效的技术。
在这里插入图片描述
PWM波主要应用场景:
电机控制
PWM信号可以用来控制直流电机的转速和位置,实现对电机的精确控制。在无刷直流电机(BLDC)和步进电机中,利用PWM调制可以充分发挥电子设备的精确度和能效。

LED灯光调光
PWM信号可用于调控LED灯的亮度。通过改变PWM信号的占空比(on-time和off-time的比值),可以实现对LED灯光的调光操作,达到节能和避免眩光的效果。

电源管理
采用PWM技术的开关稳压器(如降压转换器)在电源管理中具有广泛的应用。

音频放大器
在数字音频放大器中,PWM信号用于控制音频信号的放大和调制。

混合动力电动汽车(HEV)和电动汽车(EV)
PWM信号用于控制电池充放电和电动机的驱动管理,提高电池的使用性能和寿命。

伺服系统
在伺服系统中,PWM信号用于传输伺服电机的控制信号,实现对伺服电机的精确控制。

二.PWM产生框架图

定时器部分框图如下,其中PWM相关的主要是基本定时器和PWM输出控制部分,基本定时器主要控制PWM输出的频率,PWM控制部分主要控制PWM输出的占空比。

在这里插入图片描述

PWM输出控制部分信号流向

主要寄存器
1.TIMERx_CHxCV
捕获比较(值)寄存器:设置比较值。

2.TIMERx_CNT
计数器值与捕获比较寄存器TIMERx_CHxCV进行比较,通过比较结果输出有效电平和无效电平 。

3.TIMERx_CAR
自动重装载寄存器,计数器(TIMERx_CNT)开始计数,直到计数器(TIMERx_CNT)达到TIMERx_CAR中存放的值后,重新回到0,依次循环 。

在PWM工作模式下,引入一个寄存器TIMERx_CHxCV ,这个寄存器用于控制PWM输出波的有效电平长度(占空比),假定定时器工作在向上计数 PWM模式,且当 CNT<TIMERx_CHxCV 时,输出 0,当 CNT>=TIMERx_CHxCV 时输出 1。当 CNT 达到 TIMERx_CAR值的时候,重新归零,然后重新向上计数,依次循环。改变 TIMERx_CHxCV 的值,就可以改变 PWM 输出的占空比,改变 TIMERx_CAR的值,就可以改变 PWM 输出的频率。

工作过程如下图所示
在这里插入图片描述

三.配置一个TIME输出1KHZ,占空比50%PWM波例程

1.硬件接线
STLINK接GD32F103C8T6开发板,STLINK接电脑USB口,PA1引脚接波形接收器接收引脚。

在这里插入图片描述
2.实验原理

通过配置定时器1,通道1(PA1引脚)输出1kHZ,50%占空比的PWM波。

3.主要代码如下

void gpio_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);//PA1配置成复用功能,TIM1的CH1
    gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_2);
    gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_3);
}

/**
    \brief      configure the TIMER peripheral
    \param[in]  none
    \param[out] none
    \retval     none
  */
void timer_config(void)
{
    /* -----------------------------------------------------------------------
    TIMER1 configuration: generate 3 PWM signals with 3 different duty cycles:
 

    TIMER1 channel1 duty cycle = (500/ 1000)* 100  = 50%

    ----------------------------------------------------------------------- */
    timer_oc_parameter_struct timer_ocintpara;
    timer_parameter_struct timer_initpara;

    rcu_periph_clock_enable(RCU_TIMER1);

    timer_deinit(TIMER1);

    /* TIMER1 configuration 配置周期1KHZ*/
    timer_initpara.prescaler         = 107;
    timer_initpara.alignedmode       = TIMER_COUNTER_EDGE;
    timer_initpara.counterdirection  = TIMER_COUNTER_UP;
    timer_initpara.period            = 999;
    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);
    timer_channel_output_config(TIMER1,TIMER_CH_2,&timer_ocintpara);
    timer_channel_output_config(TIMER1,TIMER_CH_3,&timer_ocintpara);

    /* CH1 configuration in PWM mode1,duty cycle 50%,配置占空比50% */
    timer_channel_output_pulse_value_config(TIMER1,TIMER_CH_1,499);
    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);

    /* CH2 configuration in PWM mode1,duty cycle 50% */
    timer_channel_output_pulse_value_config(TIMER1,TIMER_CH_2,499);
    timer_channel_output_mode_config(TIMER1,TIMER_CH_2,TIMER_OC_MODE_PWM0);
    timer_channel_output_shadow_config(TIMER1,TIMER_CH_2,TIMER_OC_SHADOW_DISABLE);

    /* CH3 configuration in PWM mode1,duty cycle 50% */
    timer_channel_output_pulse_value_config(TIMER1,TIMER_CH_3,499);
    timer_channel_output_mode_config(TIMER1,TIMER_CH_3,TIMER_OC_MODE_PWM0);
    timer_channel_output_shadow_config(TIMER1,TIMER_CH_3,TIMER_OC_SHADOW_DISABLE);

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

int main(void)
{
		rcu_apb2_clock_config(RCU_APB2_CKAHB_DIV1);//设置主频108M(#define __SYSTEM_CLOCK_108M_PLL_HXTAL         (uint32_t)(108000000)),8M外部晶振  (#define HXTAL_VALUE    ((uint32_t)8000000))
		systick_config();//配置1ms SysTick
		rcu_periph_clock_enable(RCU_AF);//AF时钟使能 
		gpio_config();//配置管脚
		timer_config();//1kHZ PWM波
	
    while(1)
    {
    
    }
 
}

4.测量波形结果

通过波形接收器测量PA1引脚
在这里插入图片描述

四.工程源代码下载

通过网盘分享的文件:4.PWM输出.zip
链接: https://pan.baidu.com/s/1VJ6w2cEt0tY__nRfXXFOvg 提取码: zbbu

如果链接失效,可以联系博主给最新链接
程序下载下来之后解压就行

CSDN代码

五.小结

脉冲宽度调制(PWM:Pulse Width Modulation)可以广泛应用于电机控制、灯光的亮度调节、功率控制等领域,所以在那些领域避免不了需要用到PWM输出技能。

  • 10
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
首先,需要配置定时器的工作模式为 PWM 模式,然后设置定时器的周期和占空比即可输出 PWM 。以下是使用 GD32F4xx 标准库的代码示例: ```c #include "gd32f4xx.h" void timer_pwm_init(void) { /* 使能定时器时钟 */ rcu_periph_clock_enable(RCU_TIMER0); /* 配置定时器的工作模式为 PWM 模式 */ timer_oc_parameter_struct timer_ocinitpara; timer_parameter_struct timer_initpara; timer_deinit(TIMER0); timer_struct_para_init(&timer_initpara); timer_initpara.prescaler = 0; // 定时器分频系数 timer_initpara.alignedmode = TIMER_COUNTER_EDGE; // 边沿对齐计数模式 timer_initpara.counterdirection = TIMER_COUNTER_UP; // 向上计数模式 timer_initpara.period = 999; // 定时器周期 timer_init(TIMER0, &timer_initpara); /* 配置定时器的输出通道 */ timer_channel_output_struct_para_init(&timer_ocinitpara); timer_ocinitpara.outputstate = TIMER_CCX_ENABLE; // 使能输出通道 timer_ocinitpara.ocpolarity = TIMER_OC_POLARITY_HIGH; // 输出极性为高电平 timer_ocinitpara.ocnpolarity = TIMER_OCN_POLARITY_HIGH; // 输出互补极性为高电平 timer_ocinitpara.ocidlestate = TIMER_OC_IDLE_STATE_LOW; // 输出空闲状态为低电平 timer_ocinitpara.ocnidlestate = TIMER_OCN_IDLE_STATE_LOW; // 输出互补空闲状态为低电平 timer_channel_output_config(TIMER0, TIMER_CH_0, &timer_ocinitpara); /* 设置定时器的占空比 */ timer_channel_output_pulse_value_config(TIMER0, TIMER_CH_0, 500); // 占空比为 50% /* 使能定时器 */ timer_enable(TIMER0); } int main(void) { timer_pwm_init(); while (1) { // do something } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值