woshi_ziyu
发表于: 2021-5-6 10:10:46 | 显示全部楼层

脉宽调制(Pulse Width Modulation,简称PWM)是一种模拟调制技术,其中脉冲的持续时间或宽度随时间而变化。这种技术常用于产生具有特定频率和占空比的连续脉冲信号。简而言之,PWM就是在保持频率不变的同时改变脉冲宽度。


通过PWM信号,您可以轻松控制伺服电机的速度或LED的亮度。由于通用微控制器只能在其输出引脚上提供高电平或低电平,因此除非内置了数模转换器(DAC)或在外部连接DAC,否则它们无法提供变化的模拟电压。在这种情况下,微控制器可以被编程为输出具有变化的占空比的脉冲宽度调制(PWM),然后可以将其转换为变化的模拟电压。


因此,在本篇文章中,我们将一个LED连接到通用STM8S微控制器,该LED由微控制器生成的PWM信号进行控制,并且我们将使用STVD和Cosmic C编译器对微控制器进行编程。在此之前,让我们了解PWM信号的一些基础知识。


PWM信号的基础知识

您可能已经听说过,PWM代表脉宽调制。这是一种模拟调制技术,可用于多种不同的应用程序和项目。 PWM信号如下所示。

Pulse-Width-Modulation.png


上图是打开时间和关闭时间一样的通用方波。现在,假设方波的总周期为1秒,这意味着方波的开启时间和方波的关闭时间都是500ms。因此,如果我们连接一个LED并用此方波为其供电,则LED将在整个周期的一半时间内处于开启状态,而在一半的周期内处于关闭状态。看起来LED正在以一半的亮度发光。

PWM-Signal.png


在上图中,我们减小了占空比,如果考虑相同的1S周期,则开通时间为250ms,关断时间为750ms。现在,如果我们连接相同的LED,将观察到LED将变得更加暗淡,因为占空比降低了。


STM8S PWM发生器电路的硬件设置和要求

STM8S-PWM-Generator-Circuit.jpg


当我们使用PWM控制LED时,需要将LED与STM8S开发板连接。由于STM8S开发板上有一个LED,我将用它进行演示。我们还需要STM8S开发板以及ST-LINK编程器。除此之外,我们需要5V电源为板供电,由于开发板带有板载微型USB电缆,我们将使用它为板供电。


基于STM8S单片机的LED调光器的电路图

为了对电路进行编程,我们将ST-Link V2编程器连接至3.3V,SWIM和STM8S开发板的接地引脚。关于STM8微控制器,最有趣的是它只需要一个引脚即SWIM引脚即可对微控制器进行编程。

STM8S-Microcontroller-LED-Dimmer.png


如您在上面的示意图中所见,开发板上连接了一个测试LED,并将其连接到开发板最左侧的端口1.4。


STM8S微控制器上的PWM引脚

STM8S有20个引脚,其中8个引脚可以配置为PWM。下图显示了红色方框中标记的PWM引脚。这些引脚也是GPIO引脚,可用于其他功能。

ST-Micro-STM8S-Microcontroller.jpg


如上图所示,标记的引脚可以产生PWM信号。因此,我们将使用开发板上的其中之一来产生PWM信号。但是,启用PWM将禁用其他功能,因此我们需要注意选择将哪个引脚配置为PWM。本文我们将使用PIN D4生成PWM信号。

跳转到指定楼层
woshi_ziyu
发表于: 2021-5-6 10:26:47 | 显示全部楼层

编程STM8微控制器生成PWM信号

首先我们创建一个工作区和一个新项目。您可以添加所有头文件和源文件,也可以仅添加gpio、timer2、config和stm8s文件。打开main.c文件,然后开始编写程序。

Programming-STM8s-Microcontroller.png


确保已包含头文件,如上图所示。打开main.c文件并开始编写代码。可以从此处下载项目文件。代码说明如下。


在开始编码过程之前,您需要包括stm8s_gpio.c、stm8s_tim2.c,并且在源文件夹和头文件夹中,您需要包括stm8s_gpio.h、stm8s_tim2.h。您可以从STM8S103F3P6 SPL GitHub存储库中获取这些头文件。一旦完成,我们首先在代码中包含所有必需的库,并定义所有必需的变量。对于此实验代码,我们只需要将PWM值保存在单个变量中,这就是为什么我们包含一个名为pwm_duty的变量的原因。

  1. #include "STM8S.h"
  2. signed int pwm_duty = 0;
复制代码

声明了所有库和变量之后,就需要构建延迟函数,因为cosmic c编译器不提供任何预定义的延迟函数。我们将使用仅占用一个时钟周期的汇编指令NOP。而且由于微控制器的内核以2MHz的频率运行,因此我们可以轻松地估算延迟。因此,我们将延迟与两个for循环一起使用。这是使用C编译器制作延时函数最简单准确的方法。

  1. void delay_ms (int ms) //Function Definition
  2. {
  3.             for (int i=0; i<=ms; i++)
  4.                         for (int j=0; j<120; j++) // Nop = Fosc/4
  5.                                     _asm("nop"); //Perform no operation //assembly code
  6. }
复制代码

接下来,我们看一下main函数。我们在main函数中取消初始化GPIO引脚和Timer2。如果GPIO或Timer先前已用于其他应用程序,则应在使用它们之前对其进行初始化。这不是强制性的,但这是一个好习惯。

  1. GPIO_DeInit(GPIOD);
  2. TIM2_DeInit();
复制代码

接下来,我们必须将引脚声明为输出,借助TIM2_OC1Init()函数设置Timer2,并在定时器中使用预分频器以实现4KHz的PWM频率。我们通过在TIM2_TimeBaseInit()函数实现。完成此操作后,我们将使用TIM2_Cmd(ENABLE)函数启用计时器。对于这个项目,我们决定在板上使用PIN D4,它是具有PWM功能的PIN。

  1. GPIO_DeInit(GPIOD);
  2. TIM2_DeInit();         
  3. GPIO_Init(GPIOD,GPIO_PIN_4,GPIO_MODE_OUT_PP_HIGH_FAST);           
  4. TIM2_OC1Init(TIM2_OCMODE_PWM1, TIM2_OUTPUTSTATE_ENABLE, 1000,
  5.                    TIM2_OCPOLARITY_HIGH);           
  6. TIM2_TimeBaseInit(TIM2_PRESCALER_1, 500);
  7. TIM2_Cmd(ENABLE);
复制代码

接下来,我们定义无限循环函数,在循环中,我们设置了for循环,并启用了捕获和比较语句,这些语句将使我们能够设置PWM通道。

  1.   while(TRUE){                  
  2.     for(pwm_duty = 0; pwm_duty < 1000; pwm_duty += 2){
  3.       TIM2_SetCompare1(pwm_duty);
  4.       delay_ms(10);
  5.                         }                     
  6.     for(pwm_duty = 1000; pwm_duty > 0; pwm_duty -= 2){
  7.       TIM2_SetCompare1(pwm_duty);
  8.       delay_ms(10);
  9.     }
  10.   }
复制代码

使用上面的代码负责生成PWM信号,因为在第一个for循环中,PWM信号将从高电平变为低电平,并且由于下一个for循环,PWM信号将从低电平变为高电平,并且该周期将继续。


使用STM8S生成PWM信号

编译代码并将其上传到您的STM8S开发板上。如果遇到任何编译错误,请确保已添加所有头文件和源文件。上载代码后,您应该会看到引脚D4上连接的LED的亮度将改变。

Generating-PWM-Signal-Using-STM8S.jpg


完成所有操作后,我们可以在示波器中观察该PWM信号。

如果你能看到我的世界里那些渐渐消逝的美好,你就能体会到现在所拥有的幸福。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

主题 12 | 回复: 16



手机版|

GMT+8, 2024-4-25 19:46 , Processed in 0.048204 second(s), 11 queries , Gzip On, MemCache On. Powered by Discuz! X3.5

YiBoard一板网 © 2015-2022 地址:河北省石家庄市长安区高营大街 ( 冀ICP备18020117号 )

快速回复 返回顶部 返回列表