1、什么叫呼吸灯?
由亮到暗逐渐变化,很有节奏感地一起一伏,感觉好像人在呼吸,当手机收到消息,屏幕上的指示灯会渐变,比较显眼,能起到一个通知提醒的作用,其实这就是一个呼吸灯。
(备注:现在由于手机都在往全面屏发展,因此很多手机取消了呼吸灯这一功能,取而代之的是息屏显示,而这篇文章的目的也不是单纯地点亮一个呼吸灯,而是要了解背后的原理,知道什么是PWM,应该如何使用)

2、什么是PWM?
PWM:Pulse Width Modulation,脉冲宽度调制,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术。

可以将PWM理解为:对脉冲信号的处理技术,这里的“处理”指就的是改变占空比,从而改变最后呈现的效果。

既然是针对的是脉冲信号,肯定会有以下这些概念(关于脉冲就是不断跳跃的波,而PWM脉冲信号是矩形波):

PWM的频率:是指1秒钟内,信号从高电平到低电平再回到高电平的次数,也就是说一秒钟PWM有多少个周期。
单位:Hz

一般人眼睛对于80Hz以上刷新频率则完全没有闪烁感(因人而异)。
频率太小的话看起来就会闪烁,那么我们平时见到的LED灯,当它的频率大于50Hz的时候,人眼就会产生视觉暂留效果,基本就看不到闪烁了,而是一个常亮的LED灯。
频率很高时,看不到闪烁,占空比越大,LED越亮(平均电压越大);频率很低时,可看到闪烁,占空比越大,LED越亮。
所以,在频率一定下,可以用不同占空比改变LED灯的亮度,使其达到一个呼吸灯的效果。

PWM的周期:T=1/f
如果频率为50Hz,也就是说一个周期是20ms,那么一秒钟就有50次PWM周期。

占空比:在一个周期内,高电平的时间占整个周期时间
duty=t1/T
单位:% (0%-100%)

脉宽时间:高电平时间。

PWM原理:
单片机的IO引脚输出的是数字信号,且只能输出1和0。

TTL电平中,高电平为5V,低电平为0V,但是我们想要输出不同的模拟电压,比如输出3.75V应该怎么操作?

这里就要用到PWM,通过改变IO引脚输出方波的占空比,从而得到不同的模拟电压值,理论上来讲,可以输出任意不大于最大电压值(即0~5V之间任意大小)的模拟电压。

模拟电压=最大电压*占空比,这里的模拟电压是平均值,占空比越大,则模拟电压也越大。


如何产生PWM波?
使用单片机中的定时器I/O口可以产生PWM波。

那么下面再介绍一下定时器,区别于SysTick滴答定时器(一般只用于系统时钟的定时)

基本定时器只具有定时功能;而高级定时器比通用定时器多了三相六步电机的接口以及刹车功能,而这里我们只需要输出PWM波,使用通用定时器就够了。

如何使用定时器输出PWM波?换个问法就是:如何配置定时器输出PWM波?

通用定时器可以利用GPIO引脚进行脉冲输出,但是并不是任意GPIO 都具有STM32 定时器的输出通道功能,这需要根据芯片的引脚功能选择具有定时器输出通道功能的引脚来控制RGB 灯。

与定时器输出PWM有关的库函数:






在本次实验中使用的是PB5复用功能(重映射),也就是定时器3的通道2功能,呼吸灯是红灯。

实验:通过PWM波实现单色呼吸灯(LED从亮渐灭,再从灭渐亮,以此循环)

下面讲解代码:

pwm.h

#ifndef __TIMER_H
#define __TIMER_H#include "stm32f10x.h"void TIM3_Config(void);#endif

pwm.c

#include "pwm.h"//定时器3配置
void TIM3_Config(void)
{   static GPIO_InitTypeDef             GPIO_InitStructure;static TIM_TimeBaseInitTypeDef       TIM_TimeBaseStructure;static TIM_OCInitTypeDef              TIM_OCInitStructure;//1.使能定时器3时钟和GPIO时钟RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB  | RCC_APB2Periph_AFIO, ENABLE);  //使能GPIO外设和AFIO复用功能模块时钟//2.TIM3部分重映射GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE); //Timer3部分重映射  TIM3_CH2->PB5  //3.配置GPIO引脚为复用功能GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5;//选择GPIOB组的第0根引脚GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;//选择引脚为复用推挽功能GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;//选择引脚速度  GPIO_Init(GPIOB,&GPIO_InitStructure); //初始化GPIO//4.配置定时器3的频率,包括:分频值、计数值等TIM_TimeBaseStructure.TIM_Period=99;        //计数值TIM_TimeBaseStructure.TIM_Prescaler=0;            //分频值TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure);  //初始化定时器//5.配置定时器3的通道2占空比TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM2;TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;//打开或者关闭脉冲输出TIM_OCInitStructure.TIM_Pulse = 50; //比较值TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_High; //有效电平设置为高状态      TIM_OC2Init(TIM3,&TIM_OCInitStructure);//初始化定时器通道2//6.使能定时器3工作TIM_Cmd(TIM3,ENABLE);}

delay.h

#ifndef __DELAY_H
#define __DELAY_H#include "stm32f10x.h"void delay_us(uint32_t n);
void delay_ms(uint32_t n);#endif

delay.c


//延时函数
void delay_ms(uint32_t n)
{while(n--) //延时值{SysTick->CTRL=0;          //关闭滴答定时器,从最初的状态开始SysTick->LOAD=(720000*n)-1;   //配置计数值为(720000)-1 ~ 0(递减)SysTick->VAL=0;                //清除当前计数值值SysTick->CTRL=5;          //使能定时器时钟while((SysTick->CTRL & 0x10000)==0);  //等待计数值归为0}SysTick->CTRL=0;     //关闭滴答定时器
}void delay_us(uint32_t n)
{SysTick->CTRL = 0;             // Disable SysTick,关闭系统定时器SysTick->LOAD = (72*n)-1; // 配置计数值(72*n)-1 ~ 0SysTick->VAL  = 0;       // Clear current value as well as count flagSysTick->CTRL = 5;      // Enable SysTick timer with processor clockwhile ((SysTick->CTRL & 0x10000)==0);// Wait until count flag is setSysTick->CTRL = 0;         // Disable SysTick
}

main.c

#include "stm32f10x.h"
#include "pwm.h"
#include "delay.h"int main(void)
{int32_t i=0;   //为了使定时器比较值发生变化使用,这样可以实现动态PWM波//调用定时器3的配置函数TIM3_Config();//主函数循环while(1){//灯渐灭for(i=20;i>=0;i--){TIM_SetCompare2(TIM3,i);//赋值给定时器的比较值不断减1,delay_ms(1);}//灯渐亮for(i=0;i<=20;i++){TIM_SetCompare2(TIM3,i);//赋值给定时器的比较值不断加1,delay_ms(1);}}}

这是实现呼吸灯所有需要自己的代码,中断为空,下面为实验效果图:

/*Arduino实现呼吸灯程序*/
int LED_PIN=9;void setup(){//setup不做任何处理 }void loop(){//LED渐亮for(int fadeValue=0;fadeValue<=255;fadeValue+=5){//输出PWManalogWrite(LED_PIN,fadeValue);//fadeValue是脉冲宽度,即高电平的时间,也就是占空比delay(30);}  //LED渐灭for(int fadeValue=255;fadeValue>=0;fadeValue-=5){analogWrite(LED_PIN,fadeValue);delay(30);  }
}

最后一个是使用Arduino UNO板实现呼吸灯,相比STM32这个Arduino呼吸灯程序非常地简单,但是点亮呼吸灯并不是最终目的,而是要通过呼吸灯学会用定时器输出PWM波,每个板子都有板子的适用场所,相比Arduino,可以使用32实现一些更加复杂的功能,比如通过PWM波还可以控制舵机方向、电机转速等。


由于本人也是刚开始学习STM32,属于新手一枚,在学习途中肯定会遇到很多疑问,所以自己建了一个STM32技术交流群,欢迎大家进群交流技术,彼此解答疑惑。

作者能力水平有限,文章难免存在错误和纰漏,请大佬不吝赐教,非常欢迎大家与小白杨进行技术交流,希望在此能遇到志同道合的朋友,一起学习技术。

STM32_PWM呼吸灯相关推荐

  1. 通用定时器输出PWM波实现呼吸灯

    STM32F1系列含有8个定时器,分为基本定时器,通用定时器和高级定时器.基本定时器 TIM6 和 TIM7 是一个 16 位的只能向上计数的定时器,只能定时,没有外部IO.通用定时器 TIM2/3/ ...

  2. arduino 呼吸灯_如何改善您的Arduino呼吸机:用于临时COVID-19呼吸机设计的RTS和SCS简介...

    arduino 呼吸灯 The world as we know it was recently taken by storm. That storm was the outbreak of the ...

  3. 延时函数介绍和呼吸灯的实现

    文章目录 延时函数介绍 呼吸灯原理 杨桃32学习笔记,本文图片文字皆为转述 延时函数介绍 分为delay_s秒,delay_ms毫秒,delay_us微秒延时,最大参数不能超过65535. 呼吸灯原理 ...

  4. css怎么动画中该透明度,通过css3动画和opacity透明度实现呼吸灯效果

    本文介绍了通过css3动画和opacity透明度实现呼吸灯效果的方法,分享给大家,具体如下: 呼吸灯 /*也可以通过加层罩,通过设置层罩透明度来实现亮度动画*/ body{ background-co ...

  5. android呼吸灯动画,Android高德地图自定义定位蓝点实现呼吸灯功能

    还是先上个图吧: cluster.gif 说下实现的原理,首先这个定位小蓝点是由两张图片组成的,最底层的一张白色圆形图片以及上一层的蓝色圆形图片,只要不停的对蓝色图片进行透明度动画操作就可以实现这个效 ...

  6. 【Verilog HDL 训练】第 10 天(PWM 呼吸灯)

    5月8日 PWM 用verilog实现PWM控制呼吸灯.呼吸周期2秒:1秒逐渐变亮,1秒逐渐变暗.系统时钟24MHz,pwm周期1ms,精度1us. 今天的题目我是第一次见,答案借鉴大神的:Veril ...

  7. 生活娱乐 达尔优的键盘鼠标如何打开和关闭呼吸灯

    http://item.jd.com/1105057.html FN+Scrllock为开关按钮 FN+PuUp为调节灯光 http://item.jd.com/1154075.html 鼠标底面有开 ...

  8. 启明智显分享| ESP32学习笔记参考--PWM(脉冲宽度调制) 篇,配PWM控制 LED呼吸灯代码示例参考

    提示:启明智显专为智能产品提供一站式彩屏显示+连接+云端服务+APP软件开发.维护等解决方案,帮厂商快速实现硬件的智能化.作为启明云端旗下方案公司,我们用心整理了开发小伙伴在开发过程中可能会遇到的问题 ...

  9. android8 通知呼吸灯_android学习笔记----解决兼容8.0以上和8.0之前版本通知栏显示、振动、LED呼吸灯闪烁问题(真机验证)...

    Android 8.0系统的通知栏适配文章讲解(郭霖大神的): 然后开始试验了: 模拟器: 真机(华为荣耀V9,8.0系统),下拉横幅需要手动打开,除非是厂家白名单,比如QQ.微信 我在oppo手机6 ...

最新文章

  1. angular-fullstack test
  2. VTK:可视化算法之Office
  3. php变量与数组相互转换的方法(extract与compact
  4. .NET环境下每日集成(4):CruiseControl.Net配置注意事项
  5. 实现打印异常日志_老生常谈SpringAop日志收集与处理做的工具包
  6. http协议知识msdn
  7. 低解密指数攻击_CTF中RSA的一些攻击思路
  8. SQL注入攻击原理与防御措施
  9. [PowerQuery]Excel 如何开启PowerQuery组件
  10. 计算机英语词典 txt,9种Txt格式朗文英语词典免费分享
  11. 人脸对齐—级联回归模型和深度学习模型
  12. 【Linux】网站后台设置及管理
  13. (二)mybatisPlus实现ActiveRecord(AR)操作
  14. 工具类库系列(六)-TimeTool
  15. 专家教你用!!!google .
  16. python agg函数,python pandas自定义agg函数
  17. 牛客小白月赛23(A、B
  18. python的一些语句的意思
  19. HDU 4997 Biconnected (状态压缩DP)
  20. ×××互联网信息服务管理办法(×××292号令)

热门文章

  1. 服务器 显示w3wp.exe,关于windows2008+IIS7服务器中W3wp.exe问题
  2. 为什么要新零售 新零售的“人、货、场”需要哪些变化?
  3. hdoj 4875 逃生
  4. 记录一道题目附件是咒语.txt的杂项题writeup
  5. 欢迎使用微信 7.0
  6. slam‘s degenerate problem
  7. 微信公众号点击菜单出现多条文章
  8. plsa java_PLSA算法(转)
  9. 1355 巧克力 (线段树点+区间)
  10. 如何评价短视频 app 「抖音」?