一文带你吃透PWM,从原理到实战

PWM 是什么

PWM,全称是脉冲宽度调制(Pulse Width Modulation) ,是一种利用微处理器的数字输出来对模拟电路进行控制的非常有效的技术。简单来说,PWM 是一种对模拟信号电平进行数字编码的方法,通过高分辨率计数器的使用,方波的占空比被调制用来对一个具体模拟信号的电平进行编码。它利用微处理器的数字信号来控制模拟电路,广泛应用于测量、通信、功率控制与变换等许多领域。

PWM 信号本质上是一种方波信号,它具有固定的周期(Period)和可变的脉冲宽度(Pulse Width) 。周期是指一个完整的 PWM 信号循环所需的时间,而脉冲宽度则是指在一个周期内,信号处于高电平的时间长度。脉冲宽度与周期的比例关系被称为占空比(Duty Cycle) ,占空比的计算公式为:占空比 = (脉冲宽度 / 周期)× 100% ,它决定了 PWM 信号的平均电压或功率输出。例如,一个 PWM 信号的周期为 10ms,脉冲宽度为 2ms,那么它的占空比就是(2ms / 10ms)× 100% = 20% 。

从原理上来说,PWM 技术是基于面积等效原理发展而来的。面积等效原理指出,冲量相等而形状不同的窄脉冲加在具有惯性的环节上时,其效果基本相同。这里的冲量即指窄脉冲的面积,效果基本相同是指环节的输出响应波形基本相同。PWM 技术就是利用这一原理,通过改变脉冲宽度来等效地获得所需要的波形(如正弦波等)。

在实际应用中,PWM 技术的优势明显。比如在电机控制领域,通过 PWM 控制技术可以实现对电机转速、转矩等参数的精确控制,从而提高电机的运行效率和稳定性;在 LED 调光方面,PWM 调光技术可以使 LED 始终在恒流条件下工作,避免电流变化过程中的颜色偏差和亮度波动,同时,PWM 调光技术还可以提供更大的调光范围和更好的线性度,满足用户对于不同亮度需求的同时实现节能。

PWM 基本原理

关键参数

PWM 信号的关键参数包括周期(Period)、频率(Frequency)和占空比(Duty Cycle) 。

周期(T)是指 PWM 信号完成一个完整的脉冲序列所需的时间,单位通常为秒(s)、毫秒(ms)或微秒(μs) 。例如,一个 PWM 信号的周期为 10ms,表示每隔 10ms 它就会重复一次相同的脉冲序列。

频率(f)则是指在单位时间内 PWM 信号重复的次数,单位是赫兹(Hz) 。频率与周期成倒数关系,即 f = 1/T 。比如,若周期 T 为 10ms(0.01s),根据公式可算出频率 f = 1/0.01s = 100Hz ,这意味着该 PWM 信号每秒会重复 100 次。

占空比(D)是指在一个周期内,PWM 信号处于高电平的时间(TH)与整个周期时间(T)的比值,通常用百分比表示,计算公式为 D = (TH / T) × 100% 。例如,在一个周期为 20ms 的 PWM 信号中,如果高电平持续时间为 5ms,那么占空比 D = (5ms / 20ms) × 100% = 25% 。占空比决定了 PWM 信号的平均电压或功率输出,在电机控制中,占空比越大,电机获得的平均电压越高,转速也就越快;在 LED 调光应用里,占空比越大,LED 就越亮。

工作方式

PWM 的工作方式是通过控制开关器件(如 MOSFET、IGBT 等)的通断,使得输出端得到一系列幅值相等但宽度不等的脉冲。以直流电机控制为例,当 PWM 信号为高电平时,开关器件导通,电机通电运转;当 PWM 信号为低电平时,开关器件关断,电机断电。通过调节 PWM 信号的占空比,就可以改变电机在一个周期内通电的时间,从而控制电机的平均电压和转速。假设电机的额定电压为 12V,当 PWM 信号的占空比为 50% 时,电机在一个周期内有一半时间通电,其实际获得的平均电压约为 12V × 50% = 6V;当占空比提高到 80%,电机获得的平均电压变为 12V × 80% = 9.6V ,转速也会相应提高。在交流逆变电路中,PWM 技术通过控制开关器件的通断,将直流电压转换为交流电压,并通过调节脉冲宽度和频率,实现对交流输出电压的大小和频率的控制,以满足不同负载的需求。

面积等效原理

面积等效原理是 PWM 技术的重要理论基础。其核心内容是:冲量相等而形状不同的窄脉冲加在具有惯性的环节上时,其效果基本相同。这里的冲量指的是窄脉冲的面积(即窄脉冲的幅值与持续时间的乘积),效果基本相同是指环节的输出响应波形基本相同。以正弦波为例,将正弦波的半个周期分成若干等份,用一系列等幅不等宽的矩形脉冲来代替正弦波,只要这些矩形脉冲的面积与相应正弦波部分的面积相等(即冲量相等) ,那么这些矩形脉冲序列(也就是 PWM 波形)在经过具有惯性的低通滤波器等环节后,其输出响应与正弦波通过该环节后的输出响应基本相同。这就使得我们可以利用 PWM 技术,通过控制脉冲宽度来等效地获得所需要的波形,如正弦波、方波等,为电力电子设备的控制提供了一种高效、灵活的方法。

PWM 应用领域

电机控制

在电机控制领域,PWM 技术应用广泛,涵盖直流电机和步进电机等多种类型。

对于直流电机,其工作原理基于电磁感应,通电导体在磁场中会受到力的作用。PWM 控制直流电机的核心在于通过调节占空比来改变电机电枢两端的平均电压。当占空比增大时,电机电枢两端的平均电压升高,根据电机转速与电压的关系(转速公式:n = (U - IR) / CeΦ ,其中 n 为转速,U 为电枢电压,I 为电枢电流,R 为电枢电阻,Ce 为电动势常数,Φ 为磁通) ,电机转速随之增加;反之,占空比减小时,平均电压降低,转速下降。例如在电动汽车的直流电机驱动系统中,通过 PWM 技术精确控制电机转速,能够实现车辆的平稳加速、减速以及巡航控制,有效提升驾驶体验和能源利用效率。

步进电机则是将电脉冲信号转变为角位移或线位移的开环控制电机。每输入一个脉冲信号,步进电机就旋转一个固定的角度,这个角度称为步距角。PWM 在步进电机控制中主要用于调节电机的转速和扭矩。通过改变 PWM 信号的频率,可以控制步进电机的转速,频率越高,转速越快;而调节 PWM 信号的占空比,则可以改变电机绕组中的电流大小,从而控制电机的扭矩。在 3D 打印机中,步进电机用于精确控制打印头的移动,PWM 技术能够确保打印头按照预设的路径和速度精准移动,保证打印质量 。

电源管理

在开关电源中,PWM 技术发挥着关键作用。开关电源的基本工作原理是通过控制开关管的导通和关断,将输入的直流电压转换为高频脉冲电压,再经过整流、滤波等环节得到稳定的直流输出电压。PWM 技术通过调节开关管的导通时间与周期的比例(即占空比) ,实现对输出电压的精确控制。当输出电压低于设定值时,控制系统会增大 PWM 信号的占空比,使开关管导通时间延长,从而增加输出电压;反之,当输出电压高于设定值时,减小占空比,降低输出电压。以常见的手机充电器为例,内部的开关电源利用 PWM 技术,能够将 220V 的交流电转换为适合手机电池充电的稳定直流电压,并且在不同的充电阶段(如恒流充电、恒压充电) ,通过调整 PWM 信号的占空比,精确控制输出电压和电流,提高充电效率,同时减少能量损耗,降低充电器的发热问题。

LED 调光

在 LED 照明领域,PWM 调光技术凭借其出色的性能成为主流调光方式。LED 的亮度与通过它的电流成正比,PWM 调光通过控制 LED 的导通时间来调节其平均电流,从而实现亮度调节。具体来说,PWM 信号以高频率(通常大于 100Hz,人眼无法察觉闪烁的频率) 周期性地控制 LED 的开关。在一个 PWM 周期内,当信号为高电平时,LED 导通发光;信号为低电平时,LED 熄灭。通过改变高电平在一个周期内所占的比例(即占空比) ,可以改变 LED 的平均电流,进而调节其亮度。在智能照明系统中,用户可以通过手机 APP 或遥控器发送指令,控制系统根据指令调整 PWM 信号的占空比,实现对 LED 灯具亮度的无级调节,满足不同场景下的照明需求,同时达到节能的目的。

音频信号处理

在音频领域,PWM 技术可用于生成音频信号和控制音量。音频信号本质上是一种随时间变化的模拟信号,PWM 技术通过将音频模拟信号转换为数字脉冲信号来进行处理。具体过程是,根据音频信号的幅值变化,调整 PWM 信号的占空比。例如,当音频信号幅值较高时,增大 PWM 信号的占空比;幅值较低时,减小占空比。这样,通过一系列不同占空比的 PWM 脉冲序列就可以编码音频信号的信息。在播放音频时,PWM 信号经过低通滤波器后,能够还原出接近原始音频的模拟信号,实现声音的播放。此外,PWM 还可用于音频音量控制,通过改变 PWM 信号的整体幅值或占空比范围,来调整音频信号的强度,从而实现音量的调节。在数字音频播放器中,就常常利用 PWM 技术来精确控制音频信号的输出,为用户带来高质量的听觉体验。

PWM 实践:基于 STM32 的 PWM 控制 LED 亮度

硬件连接

以 STM32F407 开发板为例,将 LED 的阳极通过一个限流电阻连接到开发板的 3.3V 电源,阴极连接到开发板的 PA8 引脚(该引脚可复用为定时器的 PWM 输出通道) 。限流电阻的作用是限制通过 LED 的电流,防止电流过大损坏 LED,一般可选用 220Ω - 1kΩ 的电阻。简易电路图如下:

 

+3.3V

|

|

---

| | 限流电阻(如220Ω)

| |

---

|

|

LED

|

|

PA8(STM32)

软件配置

在 STM32CubeIDE 开发环境中进行如下配置:

  1. 创建新项目:打开 STM32CubeIDE,选择 “File” - “New” - “STM32 Project” ,输入项目名称并选择对应的 STM32F407 芯片型号,点击 “Finish” 完成项目创建。
  1. 配置引脚:在 “Pinout & Configuration” 选项卡中,找到 PA8 引脚,将其设置为 “TIM1_CH1” ,即定时器 1 的通道 1,用于 PWM 输出。
  1. 配置定时器:在 “Configuration” 选项卡中,选择 “TIM1” 。设置定时器的基本参数,如时钟源选择内部时钟,预分频器(Prescaler)设为 83,自动重装载值(Period)设为 999 。这样,PWM 信号的频率 f = 系统时钟频率 / (预分频器 + 1) / (自动重装载值 + 1) ,假设系统时钟频率为 84MHz ,则 f = 84000000 / (83 + 1) / (999 + 1) = 1kHz 。
  1. 配置 PWM 模式:在 “TIM1” 的 “Mode” 选项中,选择 “PWM Generation CH1” ,即 PWM 模式 1 。设置占空比(Pulse),初始值可设为 0 ,表示 LED 全灭。
  1. 生成代码:完成上述配置后,点击 “Project” - “Generate Code” ,生成初始化代码。

代码实现

在生成的代码基础上,在main.c文件中添加以下代码实现 LED 亮度渐变效果:

 

#include "stm32f4xx_hal.h"

TIM_HandleTypeDef htim1;

void SystemClock_Config(void);

static void MX_GPIO_Init(void);

static void MX_TIM1_Init(void);

int main(void)

{

HAL_Init();

SystemClock_Config();

MX_GPIO_Init();

MX_TIM1_Init();

if (HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1) != HAL_OK)

{

Error_Handler();

}

while (1)

{

// 亮度逐渐增加

for (int i = 0; i <= 1000; i++)

{

__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, i);

HAL_Delay(10);

}

// 亮度逐渐减小

for (int i = 1000; i >= 0; i--)

{

__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, i);

HAL_Delay(10);

}

}

}

void SystemClock_Config(void)

{

RCC_OscInitTypeDef RCC_OscInitStruct = {0};

RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

// 使用HSE作为时钟源

RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;

RCC_OscInitStruct.HSEState = RCC_HSE_ON;

RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;

RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;

RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL16;

if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)

{

Error_Handler();

}

// 配置系统时钟

RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK

| RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;

RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;

RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;

RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;

RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)

{

Error_Handler();

}

}

static void MX_TIM1_Init(void)

{

TIM_ClockConfigTypeDef sClockSourceConfig = {0};

TIM_MasterConfigTypeDef sMasterConfig = {0};

TIM_OC_InitTypeDef sConfigOC = {0};

TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = {0};

htim1.Instance = TIM1;

htim1.Init.Prescaler = 83;

htim1.Init.CounterMode = TIM_COUNTERMODE_UP;

htim1.Init.Period = 999;

htim1.Init.ClockDivision = 0;

htim1.Init.RepetitionCounter = 0;

htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;

if (HAL_TIM_Base_Init(&htim1) != HAL_OK)

{

Error_Handler();

}

sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;

if (HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig) != HAL_OK)

{

Error_Handler();

}

if (HAL_TIM_PWM_Init(&htim1) != HAL_OK)

{

Error_Handler();

}

sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;

sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;

if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK)

{

Error_Handler();

}

sConfigOC.OCMode = TIM_OCMODE_PWM1;

sConfigOC.Pulse = 0;

sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;

sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH;

sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;

sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET;

sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET;

if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)

{

Error_Handler();

}

sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE;

sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE;

sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF;

sBreakDeadTimeConfig.DeadTime = 0;

sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE;

sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH;

sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE;

if (HAL_TIMEx_ConfigBreakDeadTime(&htim1, &sBreakDeadTimeConfig) != HAL_OK)

{

Error_Handler();

}

HAL_TIM_MspPostInit(&htim1);

}

static void MX_GPIO_Init(void)

{

GPIO_InitTypeDef GPIO_InitStruct = {0};

// 使能GPIO时钟

__HAL_RCC_GPIOA_CLK_ENABLE();

// 配置PA8为复用推挽输出

GPIO_InitStruct.Pin = GPIO_PIN_8;

GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;

GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;

GPIO_InitStruct.Pull = GPIO_NOPULL;

GPIO_InitStruct.Alternate = GPIO_AF1_TIM1;

HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

}

void Error_Handler(void)

{

// 错误处理函数

}

关键代码解释:

  • __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, i); :设置 TIM1 通道 1 的比较值,从而改变 PWM 信号的占空比,实现 LED 亮度的调节。i的值从 0 到 1000 变化时,占空比从 0% 逐渐增加到 100% ,LED 亮度逐渐变亮;i从 1000 减小到 0 时,占空比从 100% 逐渐减小到 0% ,LED 亮度逐渐变暗。
  • HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1); :启动 TIM1 的 PWM 输出。

总结与展望

总结

PWM 技术作为一种高效且灵活的控制技术,凭借其独特的工作原理,在电机控制、电源管理、LED 调光以及音频信号处理等多个关键领域发挥着不可或缺的作用。通过调节脉冲宽度和占空比,PWM 实现了对模拟信号的数字化控制,为众多电子设备和系统提供了精确、稳定且节能的控制解决方案。在电机控制中,无论是直流电机的转速调节,还是步进电机的精确位置控制,PWM 都展现出了卓越的性能;在电源管理领域,它有效提升了开关电源的转换效率和稳定性;在 LED 调光方面,实现了平滑、精准的亮度控制;在音频信号处理中,也为高质量的音频输出提供了有力支持。通过基于 STM32 的 PWM 控制 LED 亮度的实践,我们更加深入地理解了 PWM 技术的实际应用和操作方法,从硬件连接到软件配置,再到代码实现,每一个环节都紧密相连,共同实现了对 LED 亮度的有效控制,也进一步验证了 PWM 技术的可行性和实用性。

展望

展望未来,PWM 技术有望在多个方向实现突破和发展。在精度提升方面,随着半导体技术和数字信号处理技术的不断进步,PWM 控制器将能够实现更高分辨率的脉冲宽度调节,进一步降低信号的误差和失真,满足对精度要求极高的应用场景,如高精度医疗设备、航空航天控制系统等。在效率优化上,研究人员将不断探索新的调制算法和控制策略,减少 PWM 信号在生成和传输过程中的能量损耗,提高系统的整体效率,这对于能源日益紧张的现代社会具有重要意义。随着物联网、人工智能、新能源汽车等新兴领域的快速发展,PWM 技术也将迎来更广阔的应用空间。在物联网设备中,PWM 可用于精确控制各类传感器和执行器,实现设备的智能化运行;在人工智能硬件中,为芯片的电源管理和散热系统提供高效控制;在新能源汽车领域,进一步优化电机控制和电池管理系统,提升汽车的续航里程和性能 。相信在技术的持续创新和应用需求的推动下,PWM 技术将不断演进,为各领域的发展注入新的活力,创造更多的价值。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

计算机学长

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值