目录
- 1、什么是PWM?用来做什么的?
- PWM(Pulse Width Modulation)脉冲宽度调制
- 常见用到 PWM 的情况:
- 2、什么是输出比较?
- 输出比较模式![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/42434920ca0940b1b10832155a4da3a5.png)
- 3、数字信号和模拟信号?
- 数字信号
- 模拟信号
- 4、了解PWM方波
- PWM基本结构
- 参数计算
- 4、源码参考
1、什么是PWM?用来做什么的?
PWM(Pulse Width Modulation)脉冲宽度调制
在具有惯性的系统中,可以通过对一系列脉冲的宽度进行调制,来等效地获得所需要的模拟参量,常应用于电机控速等领域
PWM参数:
频率 = 1 / TS 占空比 = TON / TS 分辨率 = 占空比变化步距
常见用到 PWM 的情况:
电机调速控制:例如直流电机、步进电机等,通过调整 PWM 信号的占空比来改变电机的平均电压,从而实现电机转速的调节。
LED 亮度调节:不同的占空比使 LED 获得不同的平均电流,进而改变其亮度。
电源管理:在开关电源中,利用 PWM 控制功率开关管的导通和关断时间,实现稳定的输出电压调节。
音频信号生成:在一些简单的音频设备中,PWM 可用于生成近似的音频波形。
温度控制:例如在加热或冷却系统中,控制加热元件或制冷设备的工作时间比例。
2、什么是输出比较?
输出比较(OC)是通过比较计数器(CNT)和捕获/比较寄存器(CCR)的值的关系,对输出电平进行操作,以输出特定频率和占空比的 PWM 波形。捕获/比较寄存器在输入捕获和输出比较中共用。每个高级定时器和通用定时器都有 4 个输出比较通道,高级定时器的前 3 个通道还有死区生成和互补输出功能。在输出比较中,电路会对比 CNT 和 CCR 的值,CNT 自增,CCR 是给定值,根据 CNT 与 CCR 的大小关系(大于、小于、等于),输出相应的置 1 或置 0 电平。
输出比较模式
3、数字信号和模拟信号?
数字信号
以离散的数值(通常是 0 和 1)在离散时间点上表示信息的信号,具有抗干扰强、易存储处理和精度高等优点。
常用:串口通信、IIC、PWM等
模拟信号
模拟信号是在时间和幅度上连续变化、能精确反映物理量实际变化,但易受干扰和产生失真的信号
常用:ADC(模拟信号转数字信号读取电压值)
DAC(x)一些如stm32f103c8t6没有数模转换功能,无法直接输出一个模拟信号
PWM 使用数据信号,尽可能的模拟模拟信号
4、了解PWM方波
PWM基本结构
参数计算
通过调节占空比,可模拟模拟量控制电压变换
4、源码参考
#include "stm32f10x_tim.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x_gpio.h"
#include ".\pwm\pwm.h"
/*********************************************************************
@Function : PWM初始化
@Parameter : arr:自动重装值。
psc:时钟预分频数
@Return : N/A
@Read :Tout=((arr+1)*(psc+1))/Ft us,Ft=定时器工作频率,单位:Mhz
**********************************************************************/
void PwmInit(uint16_t arr,uint16_t psc)
{
/* 配置结构体变量 */
GPIO_InitTypeDef GPIO_InitStructure; // 定义GPIO初始化结构体变量
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; // 定义定时器基本配置结构体变量
TIM_OCInitTypeDef TIM_OCInitStructure; // 定义定时器输出比较模式配置结构体变量
/* 时钟使能 */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); // 使能TIM2时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO, ENABLE); // 使能GPIOA时钟和复用功能时钟
/* 引脚配置 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; // TIM2_CH2->PA1
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // 复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure); // 初始化GPIOA
/* TIM配置 */
TIM_TimeBaseStructure.TIM_Period = arr; // 自动重装载值
TIM_TimeBaseStructure.TIM_Prescaler = psc; // 预分频值
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; // TIM向上计数模式
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); // 根据配置的结构体初始化TIM2
/* PWM配置 */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; // TIM脉冲宽度调制模式2
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; // 比较输出使能
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; // TIM输出比较极性高
TIM_OC2Init(TIM2, &TIM_OCInitStructure); // 初始化TIM2的通道2
/* 使能TIM3 CCR2 */
TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Enable); // 使能TIM2的通道2的预装载
/* 使能TIM3 */
TIM_Cmd(TIM2, ENABLE); // 使能TIM2
}
#include "bord.h"
#include ".\sys\sys.h"
/*********************************************************************
@Function : 程序入口
@Parameter : N/A
@Return : N/A
**********************************************************************/
int main(void)
{
uint16_t led0pwmval=0;
uint8_t dir=1;
delay_init(); //启动滴答定时器
usart1_init(9600); //USART1初始化
SystemTinerInit(1000-1,3600-1); //系统时间初始化 定时100ms
LED_Init(); //板载LED初始化
ExpLEDInit(); //开发板LED初始化
PwmInit(1899, 0); //不分频。PWM频率=72000000/900=80Khz
printf("初始化成功!\r\n");
while(1)
{
if(dir) // 如果 dir 为真,则递增 led0pwmval;否则递减
led0pwmval++;
else //否则递减
led0pwmval--;
if(led0pwmval > 1000) // 如果 led0pwmval 大于 300,则将 dir 置为 0,改变递增方向
dir = 0;
if(led0pwmval == 0) // 如果 led0pwmval 等于 0,则将 dir 置为 1,改变递减方向
dir = 1;
delay_ms(2);
/* 设置定时器 TIM2 的比较值,控制 PWM 信号的占空比 */
TIM_SetCompare2(TIM2, led0pwmval);
}
}