DE | EN | CN

ESE模块9 PWM 脉冲宽度调制

在mySTM32 light板上调光LED。脉冲宽度调制PWM是一种重要的技术,用于生成伪模拟值。通过相对较低的成本,例如使用一个RC电路,也可以从这个信号中生成真正的模拟值。 通常情况下,这并不是必需的,就像我们将在这个例子中真正看到的那样。实际上,我们应该说看不到。我们的眼睛不会察觉PWM信号由许多脉冲组成。PWM不仅用于驱动LED,还用于驱动直流电机、步进电机、伺服电机、逆变器、电加热器、电磁阀等,可能的应用案例列表相当长。因此,所有现代微控制器都具有使用硬件模块生成PWM信号的能力。定时器非常适合执行此任务。

开发一种微控制器应用程序,LED逐渐淡入和淡出,以适合人眼观察。

要求:

  • PWM频率必须无闪烁
  • LED的淡入和淡出应该清晰可见
  • 淡入和淡出也可以是非线性的

SRS PWM

进行以下准备工作:

  • 创建一个新的类图
  • 目标语言ARM C ++
  • 目标平台STM32F042 mySTM32板灯HAL
  • 为PEC应用程序(XMC,STM32,AVR)的下载图模板应用程序框架
  • STM32F0分配驱动程序包
  • (可选)分配模板stm32F042_48Mhz

任务是对LED进行平滑的渐变控制,让人眼感觉LED在渐亮和渐暗。为此,需要生成相应的PWM信号。PWM信号不是模拟信号,而是一系列脉冲,脉冲宽度不同。每个脉冲始终对应于完整的可用电压,即在我们的情况下是3.3V,脉冲之间的间隔相应为0V。高电平和低电平之间的比例产生了所需的有效电压。

几乎所有现代微控制器都具有定时器生成一个或多个PWM信号的功能。为此,硬件和软件开发人员需要在数据手册中了解可能的定时器、PWM通道和引脚分配。硬件PWM不能在任何引脚上使用。我们可以使用mySTM32 light参考卡来了解这些信息。mySTM32 light Referenzkarte

对于引脚B0,可以使用TIMER 3通道3。 在PEC框架中,我们可以使用库模块PecPwmChannel。该模块具有使LED变暗所需的所有功能。

UML设计图,帮助理清逻辑思维。

必须将特定的硬件定时器3、通道3、引脚B0相互连接。

MERKE: PWM = Timer + Channel + Pin 注意:PWM =计时器+通道+引脚

实现应包括上述设计图中描述的元素。另外必须将Timer3,Channel3和PinB0的特定硬件连接。在资源管理器中搜索相应的元素,拖放到图中,并将其连接到Led类的Pwm。为使Led灯缓慢的变亮或变弱,我们需要一个变量作为计数器,在类控制器的属性里添加duty。由于库模块将PWM信号控制在0到1000之间,因此我们至少需要一个16位的值。使用以下表示形式可以帮助实现设计:

在这个例子中,需要初始化和启动具有所需PWM频率的定时器。PWM频率对于眼睛来说不应低于60 Hz,对于耳朵来说不应低于200 Hz(在实际应用中,功放会发出嗡嗡声),但也不应该太高。过高的频率可能会导致不希望的效果,取决于导线长度和被驱动的器件。因此,我们应该避免将频率设置得太高。请在Controller类的onStart()操作中补充以下代码。

Controller::onStart():void
// boot sequence after start SysTick
// Initialisierung PWM Channel
// startet Timer mit gewünschter PWM Frequenz
pwm.configHz(1000);

代码解释:

1. pwm.configHz(1000);:配置PWM通道的频率为1000 Hz。这意味着PWM信号将以1000赫兹的频率发出。

首先,我们开发一个简单的解决方案,以相对缓慢的速度增加PWM信号的占空比。为此,我们使用计数变量duty。PecPwmChannel库模块的setDuty(duty)操作预期的值范围是从0(LED关闭)到1000(LED最大亮度)。因此,计数器可以从0到1000递增。通过添加一个小的延迟,我们确保缓慢增加的过程确实足够慢,以供眼睛感知。请将以下代码记录在Controller类的onWork()操作中。

Controller::onWork():
duty++;
if (duty>=1000)
{
    duty=0;
}
pwm.setDuty(duty);
waitMs(1);

代码解析:

1. duty++;:增加duty变量的值,使PWM的占空比逐渐增加。

2. if (duty>=1000):检查duty变量是否大于等于1000。

  1. 如果是,则执行以下操作:
    1. 将duty变量重置为0,以便重新开始PWM的占空比增加过程。

3. pwm.setDuty(duty);:设置PWM通道的占空比为当前duty变量的值。这确定了LED的亮度。

4. waitMs(1);:等待1毫秒。这个语句是为了控制PWM信号变化的速度,使其不要太快。

翻译程序。将可执行程序传送到控制器的程序存储器中。

  • 1.将红色LED连接到引脚B0
  • 2.创建应用程序(编译和链接)
  • 3.传输(烧录)
  • 4.测试应用程序

第一个简单的解决方案生成以下波形:

通过信号线波,可以很好地看到LED的闪烁。 下一个解决方案是实现LED的缓慢调光。 我们需要生成以下波形:

因此必须使用计数器,在上升之后,下降的信号曲线也随之变化。
更改Controller类的onWork()操作的代码,如下所示:

Controller::onWork():void
duty++;
if (duty<1000) {
    pwm.setDuty(duty);
}
else if (duty<2000) {
    pwm.setDuty(2000-duty);
}
else {
    duty=0;
}
waitMs(1);

解析代码:

1. duty++;:递增duty变量的值,以便控制PWM的占空比。

2. if (duty<1000):检查duty变量是否小于1000。

  1. 如果是,则执行以下操作:
    1. 使用当前的duty值设置PWM通道的占空比。

3. else if (duty<2000):如果duty大于或等于1000,但小于2000,则执行以下操作:

  1. 使用2000减去duty的值来设置PWM通道的占空比。这样做的效果是,LED的亮度会在duty达到1000后逐渐减小。

4. else:如果duty大于等于2000,则执行以下操作:

  1. 将duty重置为0,以便重新开始PWM的占空比调整过程。

5. waitMs(1);:等待1毫秒。是为了控制PWM信号的变化速度,使其不要太快。

创建,传输和再测试此应用程序。
可以清楚地看到LED的变化。

但是,即使是这种信号波形对我们的眼睛来说也并不是非常舒适的。这是因为我们对亮度的感知不是线性的。在低亮度范围内,我们的眼睛可以很好地感知到亮度的小变化。
但是从至少50%开始,我们几乎无法感知到亮度的变化。一种解决方法是将信号波形不是线性地而是指数地调整。这可能看起来是这样的,如下图信号曲线所示:

使用公式POTENCE(X,Y),可以在Excel中以1000个步骤实验确定所需的信号曲线。 结果大约为POTENCY(1.00693; step)。相应的C / C ++函数是pow(x,y),可以在#include“ math.h”中找到。 为此,必须在Controller类中进行相应的输入。选择控制器类,然后在上下文菜单(鼠标右键)中选择菜单项“定义…”。 在“声明/实现”对话框中,添加以下内容:

现在我们可以使用math.h中的函数pow(x,y)。 更改Controller类的onWork()操作的代码,如下所示:

Controller::onWork():void
//---------------------------------------------------------------
// atmende LED mit Exponentialfunktion pwm 0-1000 #include math.h
duty++;
if      (duty<1000) pwm.setDuty( pow(1.00693,duty) );
else if (duty<2000) pwm.setDuty( pow(1.00693,2000-duty) );
else                duty=0;
waitMs(1);

这段代码实现了一个呼吸灯效果,使用了指数函数作为PWM的占空比。下面是代码的解析:

1. duty++;:递增duty变量的值,以便控制PWM的占空比。

2. if (duty<1000):检查duty变量是否小于1000。

  1. 如果是,则执行以下操作:
    1. 使用pow函数计算以1.00693为底的duty次幂,并将结果作为PWM的占空比。这样做的效果是,LED的亮度会根据duty的增加呈指数增加。

3. else if (duty<2000):如果duty大于或等于1000,但小于2000,则执行以下操作:

  1. 使用pow函数计算以1.00693为底的(2000-duty)次幂,并将结果作为PWM的占空比。这样做的效果是,LED的亮度会根据duty的减小呈指数减小。

4. else:如果duty大于等于2000,则执行以下操作:

  1. 将duty重置为0,以便重新开始PWM的占空比调整过程。

5. waitMs(1);:等待1毫秒。是为了控制PWM信号的变化速度,使其不要太快。

创建,传输和测试此应用程序变体。
现在可以清楚地看到LED柔和灯光变化,LED呼吸灯。

总结

  • 1.创建并打开类图
  • 2.选择用于PEC应用程序的图模板,为STM32F0加载并插入驱动程序包
  • 3.在资源管理器/导航器中找到所需的块并拖到图中
  • 4. 聚合类
  • 5.创建类的属性和操作
  • 6.将类和模板组装到组件中
  • 7.在操作中创建必要的源代码
  • 8.在类图中创建并刻录ARM应用程序
  • 9.配置和使用SiSy ControlCenter

视频总结

oder die schnelle Version ohne Sprachkommentare

练习 7

扩展应用程序以通过19200波特率与SiSy控制中心建立UART连接。将用于LED驱动的PWM值作为8位数字发送到SiSy控制中心。
在控制中心的示波器视图中跟踪信号波形。

继续:

搜索关键词