呼吸灯原理

1.在模拟电路中,呼吸灯的实现可以通过一个呈现正弦的电压控制,这个电压是连续变化的,所以肉眼看上去就是逐渐变暗,逐渐变亮。

2.而在数字电路中如何实现这种效果呢?就需要通过pwm,也就是脉冲宽度调制,将模拟量转换为数字量。只要能够用连续电压控制的东西都是可以通过pwm方式来驱动,效果是一样的。

3.

上面一块区域的面积等于对应下来的矩形的面积,当然,取得块的间隔越小(即pwm的周期越小),效果越好。这时,如果周期定了,就可以通过改变占空比来实现面积的改变,从而模拟出上面那张图的电压的连续变化。

注意:pwm波的高度是一定的,所以只能通过改变宽度(占空比)来实现面积的改变

4.说明:观察这张图,会发现下面的pwm波是中心与上面的对齐(即pwm中心为高电平),然后左右扩展,每个波的周期还是一样。当然这时可以的。但更多的是运用左对齐(起始为高电平),然后向右扩展直到面积到达要求。

5.stm32实现pwm输出的原理:设点一个值为a,然后在设置一个重装值b,b>a.开始计数,当计数值小于a时,输出高电平,当计数值大于a时,输出低电平,直到计数到b,到b后又重复来一遍。所以改变这个a就可以改变占空比、

6.PWM 的输出其实就是对外输出脉宽可调(即占空比调节)的方波信号,信号频率是由自动重装寄存器 ARR 的值决定,占空比由比较寄存器 CCR 的值决定。其示意图如图 19.1.2 所示:

从图 19.1.2 中可以看到,PWM 输出频率是不变的,改变的是 CCR 寄存器内的值,此值的改变将导致 PWM 输出信号占空比的改变。占空比其实就是一个周期内高电平时间与周期的比值。PWM 输出比较模式总共有 8 种,具体由寄存器 CCMRx 的位 OCxM[2:0]配置。我们这里只讲解最常用的两种 PWM 输出模式:PWM1 和 PWM2,PWM1 和 PWM2 这两种模式用法差不多,区别之处就是输出电平的极性不同。如图 19.1.3 所示:


pwm输出配置步骤

其实 PWM 输出和上一章一样也是通用定时器的一个功能,因此还是要用到定时器的相关配置函数

1.因为pwm是由定时器输出的,既然用到定时器,就先要使能定时器的时钟:

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM14,ENABLE);//我们用的为tim14定时器

2.因为用到io作为输出,所以要打开io口的时钟:

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF,ENABLE);//注意:io口的外设均是挂在AHB1总线上的

3.通过看手册,TIM14 的 CH1 通道对应的管脚是 PF9,而pf9有很多复用功能,所以要选择pf9的输出模式:通过函数:

void GPIO_PinAFConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_PinSource,
uint8_t GPIO_AF);//前两个参数不说了。第三个参数为复用为哪种功能,这里我们使用的是 TIM14 功能,所以参数为 GPIO_AF_TIM14

所以函数为:GPIO_PinAFConfig(GPIOF,GPIO_PinSource9,GPIO_AF_TIM14);//AF就是复用的意思

4.配置io口,同之前led时一样,只不过参数有些变化:

      GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF;//PF9 管脚模式配置为复用输出GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_100MHz;//速度不变GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;//推完输出不变GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP;//上啦输出不变GPIO_Init(GPIOF,&GPIO_InitStructure);

5.初始化定时器参数,包含自动重装值,分频系数,计数方式等.同前面使用定时器中断

      TIM_TimeBaseInitStructure.TIM_Period = pre;//预装值,这里依然通过参数传递进来TIM_TimeBaseInitStructure.TIM_Prescaler = psc;//预分频系数TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;//固定不变TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;//向上计数TIM_TimeBaseInit(TIM14,&TIM_TimeBaseInitStructure);

6.定时器基本的参数配置完了,但是还没设置它为pwm输出模式:
用到的函数为:

void TIM_OCxInit(TIM_TypeDef* TIMx,TIM_OCInitTypeDef* TIM_OCInitStruct);//

注意:我们知道每个通用定时器有多达 4 路 PWM 输出通道(对于 TIM9-TIM14 最多有 2 路),所以TIM_OCxInit 函数名中的 x 值可以为 1/2/3/4。函数的第一个参数相信大家一看就清楚,是用来选择定时器的。第二个参数是一个结构体指针变量:

typedef struct
{
uint16_t TIM_OCMode; //比较输出模式
uint16_t TIM_OutputState; //比较输出使能
uint16_t TIM_OutputNState; //比较互补输出使能
uint32_t TIM_Pulse; //脉冲宽度
uint16_t TIM_OCPolarity; //输出极性
uint16_t TIM_OCNPolarity; //互补比较输出极性
uint16_t TIM_OCIdleState; //空闲状态下比较输出状态
uint16_t TIM_OCNIdleState; //空闲状态下比较输出状态
}

这里我们比较常用的 PWM 模式所需的成员变量:
TIM_OCMode:比较输出模式选择,总共有 8 种,最常用的是 PWM1 和 PWM2。
TIM_OutputState:比较输出使能,用来使能 PWM 输出到 IO 口。
TIM_OCPolarity:输出极性,用来设定输出通道电平的极性,是高电平还是低电平。
结 构 体 内 其 他 的 成 员 变 量 TIM_OutputNState , TIM_OCNPolarity ,
TIM_OCIdleState 和 TIM_OCNIdleState 是高级定时器才用到的。

所以配置完为:

TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_Low;
TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;
TIM_OC1Init(TIM14,&TIM_OCInitStructure);

7.开启定时器

TIM_Cmd(TIM14,ENABLE);

8.修改 TIMx_CCRx 的值控制占空比(这一步写在主函数中,因为要实时去改变占空比).

其实经过前面几个步骤的配置,PWM 已经开始输出了,只是占空比和频率是固定的,例如本章要实现呼吸灯效果,那么就需要调节 TIM14 通道 1 的占空比,通过修改 TIM14_CCR1 值控制。调节占空比函数是:

void TIM_SetCompare1(TIM_TypeDef* TIMx, uint32_t Compare1);//对 于 其 他 通 道 , 分 别 有 对 应 的 函 数 名 , 函 数 格 式 是 TIM_SetComparex(x=1/2/3/4)。

分析:第一个参数不说了,第二个参数是计数值。。注意:这个计数值一定要小于前面设定定时器时总的预装载值(TIM_TimeBaseInitStructure.TIM_Period = pre);


代码:

pwm.c

#include "pwm.h"void TIM14_PWM_Init(u16 pre,u16 psc)
{GPIO_InitTypeDef GPIO_InitStructure;TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;TIM_OCInitTypeDef TIM_OCInitStructure;RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM14,ENABLE);//´ٍ؟ھ¶¨ت±ئ÷µؤت±ضسRCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF,ENABLE);//زٍخھسأµ½¶ث؟ع£¬ثùزشزھت¹ؤـ¶ث؟عت¼ت±ضس£¬ءيحâioµؤحâة趼تا¹ز½سشعAHB1×ـدكةدµؤGPIO_PinAFConfig(GPIOF,GPIO_PinSource9,GPIO_AF_TIM14);GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF;GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_100MHz;//ثظ¶بGPIO_InitStructure.GPIO_OType=GPIO_OType_PP;//حئحئحىتن³ِGPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP;//ةدہ­GPIO_Init(GPIOF,&GPIO_InitStructure);//شع³ُت¼»¯ز»دآTIM_TimeBaseInitStructure.TIM_Period = pre;//ةèضأ¶¨ت±ئ÷µؤضـئع£¬ز²¾حت£×¢زâ£؛صâہïخھ´«µؤ²خت‎TIM_TimeBaseInitStructure.TIM_Prescaler = psc;//¶¨ت±ئ÷ش¤·ضئµدµت‎TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;//ح¨³£²»ذق¸ؤثû£¬¹ج¶¨µؤ£¬ز»°مآج²¨µؤت±؛ٍسأTIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;//دٍةد¼ئت‎£¬´سءم؟ھت¼¼ئت‎£¬¼ئت‎µ½ضط×°ضµTIM_TimeBaseInit(TIM14,&TIM_TimeBaseInitStructure);//³ُت¼»¯ز»دآTIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1;TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_Low;TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;TIM_OC1Init(TIM14,&TIM_OCInitStructure);TIM_Cmd(TIM14,ENABLE);}

mian.c

int main()
{u8 fx = 0;u32 i = 0;//ำรภดภผำRCC_HSE_Config(8,336,2,7);Beep_Init();NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);SysTick_Init(168);key_init();LED_Init();TIM14_PWM_Init(500-1,84-1);//2000hz,ึฦฺถจมห,0.5MS//while(1)//{//  if(fx==0)//{//  i++;//  if(i==300)//  {//      fx=1;//  }//}//else//{//      i--;//if(i==0)//  {//      fx=0;//}//}// TIM_SetCompare1(TIM14,i);//delay_ms(10);//}/********the second code*****/while(1){while(i<=300){TIM_SetCompare1(TIM14,i);delay_ms(10);i++;}while(i!=0){TIM_SetCompare1(TIM14,i);delay_ms(10);i--;}}
}

补充:
1.主函数中注释代码是官方的代码,下面是我自己原创的代码。官方代码是引用了一个变量来判断方向。

2.观察主函数的代码,我们设定的定时器为0.5ms,意思就是pwm波的周期为0.5ms,而每次执行完TIM_SetCompare1(TIM14,i);波形(占空比)就会改变,而后面写的delay_ms(10);是为了维持这一个波形一段时间,反映在模拟信号上就是电压变化的很平缓,很慢,自然亮度的变化也就很缓慢自然。自然,这个延迟时间知道要大于你定时时间好几倍吧-.-


扩展

试试用pwm输出来控制板子上的蜂鸣器来实现控制他的声音大小

提示:看电路图发现beep连在pf9上,而pf9本来就是tim13的复用口。所以只需在这个代码基础上修改定时器的标号为tim13即可

stm32之定时器运用———呼吸灯相关推荐

  1. 嵌入式系统开发13——STM32输出PWM实现呼吸灯

    本文主要介绍在STM32F103C8T6上,利用定时器输出PWM波形,进而驱动LED实现呼吸灯. 目录 一.任务要求 二.PWM简介 1.什么是PWM 2.相关概念 3.PWM的产生 4.PWM的通道 ...

  2. 【跟着江科大学Stm32】STM32F103C6T6_实现呼吸灯_代码

    PWM.h #ifndef __PWM_H #define __PWM_Hvoid PWM_Init(); void PWM_SetCompare1(uint16_t Compare);#endif ...

  3. 嵌入式小白学习:STM32实现定时器控制LED灯

    嵌入式小白学习:STM32实现定时器控制LED 目录 嵌入式小白学习:STM32实现定时器控制LED Part1.理论基础 Part2.环境的配置 Part3.代码的更改 Part4.实物的连线 Pa ...

  4. 【STM32学习笔记-LED呼吸灯】

    STM32学习笔记-点亮LED灯 文章目录 STM32学习笔记-点亮LED灯 一.呼吸灯原理 二.呼吸灯代码 1.main.c 2.led.c 3.led.h 三.代码分析 一.呼吸灯原理 占空比:占 ...

  5. 呼吸灯51单片机c语言编程,51单片机基于定时器实现呼吸灯(C8051F020单片机)

    一.实现思路 原理:利用PWM信号控制LED灯的亮暗程度,实现LED灯由暗到亮又由亮到暗的渐变过程. 方法:通过定时器设置LED所接引脚的高低电平持续时间,模拟出PWM波. 二.关键问题--PWM的频 ...

  6. C语言开定时器做呼吸灯程序,[求助]呼吸灯的编程思路(C语言)

    /*************************************************************** * 程序说明:使用P3.2和P3.4来控制P0端口的LED灯,达到手动 ...

  7. C语言开定时器做呼吸灯程序,简单的基于51单片机定时器上呼吸灯程序

    #include #define ufloat unsigned float #define uchar  unsigned char #define uint   unsigned int ucha ...

  8. STM32实现定时器和LED呼吸灯

    目录 一.实现定时器 1.定时器的介绍 1.1定时器的概念及作用 1.2定时器的分类 2.新建项目 2.1新建 2.2选择STM32F103C8T6芯片 2.3配置SYS 2.4配置RCC 2.5配置 ...

  9. 单片机开发—呼吸灯的三种实现方法

    目录 一.前言 1.什么是呼吸灯 2.如何实现呼吸灯 二.利用for循环实现呼吸灯 三.利用定时器实现呼吸灯 1.利用定时器中断实现 2.利用定时器输出PWM波实现 四.总结 一.前言 提示:本文使用 ...

最新文章

  1. Oracle-01033错误处理
  2. linux后门查杀工具付费,查杀linux后门跑虚拟货币程序.md
  3. 印度软件业崛起的奥妙
  4. 【CodeForces - 1102C 】Doors Breaking and Repairing (思维,简单博弈)
  5. Golang——map集合初始化、键值操作、map作为函数参数的使用
  6. Java手写线程池(不带返回值、带返回值)
  7. 企业如何选择数据分析架构?——谈谈3种架构的利弊
  8. labview圆环里实物动画图形_LabVIEW编程技巧:功能强大的变体数据类型用法
  9. 一个WinForm记事本程序(包含主/下拉/弹出菜单/打开文件/保存文件/打印/页面设置/字体/颜色对话框/剪切版操作等等控件用法以及记事本菜单事件/按键事件的具体代码)...
  10. CSDN统计出错:一天访问量竟然有48798
  11. Innovus中timing eco后setup margin跑哪里去了?(知识星球福利活动)
  12. AltRun调用cmd并刷新DNS
  13. mysql odbc 卸载_Linux卸载MySQL
  14. xlsxwriter
  15. HTML页面只能使用微信浏览器打开
  16. ubuntu 16.04硬盘分区方案
  17. 使用Google Analytics统计用户留存率
  18. 安装vag服务器虚拟机,FusionAccess桌面云组件介绍/安装
  19. 中国联通大幅下调国际漫游费
  20. MATLAB语言的串口助手

热门文章

  1. es 常用DSL查询语序 以及springDataES对应和使用
  2. rabbitmq Confirm三种模式
  3. linux常用命令-1备份压缩
  4. 安固士科技|数字化智慧工地到底有哪些黑科技?
  5. 学生HTML旅游景点网页作业作品 (HTML+CSS 制作江苏盐城家乡主题网站)
  6. 文心一言员工跳槽工资翻倍,猎头:百万年薪很正常
  7. 可缩放性ImageView(可以放大缩小)
  8. SSM毕设项目四川省非物质文化遗产之传统手工技艺数字平台i7k3a(java+VUE+Mybatis+Maven+Mysql)
  9. WebRTC混音器模块
  10. 请你谈谈Redis主从复制的理解?