PWM原理介绍
PWM基础知识
1.PWM介绍
PWM (Pulse Width Modulation脉宽调制)是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术。PWM是一种对模拟信号电平进行数字编码的方法。通过高分辨率计数器的使用,方波占空比被调制用来对一个具体模拟信号的电平进行编码。PWM信号任然是数字的,因为在给定的任何时刻,满幅值的直流供电要么完全有,要么完全无。比如我们的电压输出是5v的,那么经过改变PWM的占空比,可以达到在一定时间内输出3.3V或者1.3V的效果
2.GD32PWM了解
屏幕剪辑的捕获时间: 2023/5/21 15:18
基本定时器根本就不能使用PWM的通道
3.PWM基本参数
PWM是脉冲宽度调试是具有三个非常重要的参数:频率,占空比和周期
频率:频率是值每秒信号从高电平到低电平再回到高电平的次数
占空比:占空比是指一个周期内高电平所占的比例
周期:周期是指一个完整的PWM信号持续时间。
4.PWM控制方法
采样控制理论中有一个重要结论:冲量相等而形状不同的窄脉冲加在具有惯性的环节上时,其效果基本相同。
PWM控制技术就是以该结论为理论基础,对半导体开关器件的导通和关断进行控制,使输出端得到一系列幅值相等而宽度不相等的脉冲,用这些脉冲来代替正弦波或其他所需要的波形。
5.PWM应用
PWM可应用于电机调速、功率调制、PID调节、通信等,配置简单、抗干扰能力强。可以通过PWM来控制LED灯的亮暗变化,可以通过PWM信号来控制无源蜂鸣器发出简单的声音以及实现功率继电器的线圈节能等。PWM用来驱动电机和调节电机转速是非常重要的内容。
PWM操做流程
通过驱动PWM实现一个呼吸灯的效果,通过PWM信号占空比的变化可以实现流过LED电流的不同,实现LED亮暗的渐变
一般人眼睛对于80HZ以上刷新频率则完全没有闪烁感,由于频率很高时看不到闪烁,占空比越大LED越亮,占空比越小LED越暗。所以在频率一走时,可以用不同占空比改变LED灯的亮度,使其达到一个呼吸灯的效果
1.配置PWM流程
1.配置通道引脚GPIO
PA
先使能时钟
配置IO模式mode
配置IO输出set
GPIO复用
2.配置定时器
开启定时器时钟1
配置时钟的预分频数
初始化时钟
初始化结构体参数
定时器初始化
3.配置输出结构体
定时器输出结构体
Ocpolarity 通道输出的极性,也就是配置为低电平有效还是高电平有效,这里配置为高电平有效TIMER——OC——POLARITY——HIGH
Outputstate 通道输出状态(也是使能通道),一般使能TIMER_CCX_ENABLE使能PWM输出到端口
4.配置定时器输出通道
//输出定时器通道极性
timer_ocintpara.ocpolarity=TIMER_OC_POLARITY_HIGH;
//输出定时器通道输出状态
timer_ocintpara.outputnstate=TIMER_CCX_ENABLE;
//配置输出结构体
timer_channel_output_config(BSP_PWM_TIMER,TIMER_CH_0,&timer_ocintpara);//初始化结构体
5.配置定时器输出通道占空比
Void timer_channel_output_pulse_value_config(uint32_t timer_periph,uint16_t channel,uint32_t)
Timer_channel_output_pulse_value_config(BSP_PWM_TIMER,BSP_PWM_TIMER_CH,5000-1);
//配置定时器通道输出脉冲
这里设置输出脉冲值5000-1,我们设置的定时器的周期为10000-1,则占空比为5000/1000=50%
配置外设定时器通道输出占空比
Void timer_channel_output_mode_config(uint32_t timer_periph,uint16_t ocmode);
Timer_channel_output_mode_config(BSP_PWM_TIMER,BSP_PWM_TIMER_CH,TIMER_OC_MODE_PWM0);//配置定时器通道输出比较模式
这里设置为PWM模式0,也就是配置为TIMER_OC_MODE_PWM0
6.定时器自动重装影子使能
Void timer_auto_reload_shadow_enable(BSP_PWM_TIMER);
2.呼吸灯函数
呼吸灯产生原理就是LED灯逐渐变亮在逐渐变暗,然后一直循环,控制LED灯的亮暗是通过改变PWM的占空比,占空比越大,LED灯越亮,占空比越小,LED灯越暗
3.实验现象
bsp_pwm.c
#include "bsp_pwm.h"
static void pwm_gpio_config(void)
{
//使能时钟
rcu_periph_clock_enable(BSP_PWM_RCU);
//配置GPIO模式
gpio_mode_set(BSP_PWM_PORT,GPIO_MODE_AF,GPIO_PUPD_NONE,BSP_PWM_PIN);
//配置GPIO输出与速度 CPIOA口 输出就是推挽输出 50 GPIO5
gpio_output_options_set(BSP_PWM_PORT,GPIO_OTYPE_PP,GPIO_OSPEED_50MHZ,BSP_PWM_PIN);
//配置GPIO的复用功能 PA5复用的话AF是1
gpio_af_set(BSP_PWM_PORT,BSP_PWM_AF,BSP_PWM_PIN);
}
void pwm_config(uint16_t pre,uint16_t per)
{
//配置结构体参数
timer_parameter_struct timere_initpara;
//输出初始化输出结构体
timer_oc_parameter_struct timer_ocintpara;
pwm_gpio_config();
//开启时钟
rcu_periph_clock_enable(BSP_PWM_TIMER_RCU);//这个是定时器1
//配置时钟的预分频数 200/4=50 从二百变为50 分频化
rcu_timer_clock_prescaler_config(RCU_TIMER_PSC_MUL4);
//初始化定时器
timer_deinit(BSP_PWM_TIMER);
//初始化结构体参数
timere_initpara.prescaler=pre-1; //定时1秒串20000
timere_initpara.alignedmode=TIMER_COUNTER_EDGE;
timere_initpara.counterdirection=TIMER_COUNTER_UP;
timere_initpara.clockdivision=TIMER_CKDIV_DIV1;
//这个是定时1秒的话它就是10000
timere_initpara.period=per-1;
timere_initpara.repetitioncounter=0; //重复定时器 只有高级的才可以用上这个是基本的不需要所以为0
timer_init(BSP_PWM_TIMER,&timere_initpara);
// //输出定时器通道极性
// timer_ocintpara.ocpolarity=TIMER_OC_POLARITY_HIGH;
// //输出定时器通道输出状态
// timer_ocintpara.outputnstate=TIMER_CCX_ENABLE;
//
// //配置输出结构体
// timer_channel_output_config(BSP_PWM_TIMER,BSP_PWM_CHANNEL,&timer_ocintpara);//初始化结构体
/* 输出结构体 */
timer_ocintpara.ocpolarity = TIMER_OC_POLARITY_HIGH;
timer_ocintpara.outputstate = TIMER_CCX_ENABLE;
timer_channel_output_config(BSP_PWM_TIMER,BSP_PWM_CHANNEL,&timer_ocintpara);
//配置定时器通道输出脉冲值
timer_channel_output_pulse_value_config(BSP_PWM_TIMER,BSP_PWM_CHANNEL,0);
//配置定时器通道模式
timer_channel_output_mode_config(BSP_PWM_TIMER,BSP_PWM_CHANNEL,TIMER_OC_MODE_PWM0);
//配置定时器失能的状态
timer_channel_output_shadow_config(BSP_PWM_TIMER,BSP_PWM_CHANNEL,TIMER_OC_SHADOW_DISABLE);
//定时器的优先输出配置 这个是高级定时器才使用的
//timer_primary_output_config(BSP_PWM_TIMER,ENABLE);
//配置定时器自动重装影子使能
timer_auto_reload_shadow_enable(BSP_PWM_TIMER); //如果是高级定时器的话要配置定时器的优先级
//定时器使能
timer_enable(BSP_PWM_TIMER);//定时器1启动
}
/*呼吸灯*/
void pwm_breathing_lamp(void)
{
static uint8_t direct=0;//方向
static uint16_t value=0;//
if(direct==0){//逐渐变亮
value +=300;
if(value>10000)
direct=1;
}else{//逐渐变暗
value -=300;
if(value<=0)
direct=0;
}
timer_channel_output_pulse_value_config(BSP_PWM_TIMER,BSP_PWM_CHANNEL,value);
delay_1ms(50);
}
bsp_pwm.h
#ifndef _BSP_PWM_H
#define _BSP_PWM_H
#include "gd32f4xx.h"
#include "systick.h"
#define BSP_PWM_RCU RCU_GPIOA
#define BSP_PWM_PORT GPIOA
#define BSP_PWM_PIN GPIO_PIN_5
#define BSP_PWM_AF GPIO_AF_1
#define BSP_PWM_TIMER_RCU RCU_TIMER1
#define BSP_PWM_TIMER TIMER1
#define BSP_PWM_CHANNEL TIMER_CH_0
void pwm_config(uint16_t pre,uint16_t per);
void pwm_breathing_lamp(void);
#endif