stm32之定时器运用———呼吸灯
呼吸灯原理
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之定时器运用———呼吸灯相关推荐
- 嵌入式系统开发13——STM32输出PWM实现呼吸灯
本文主要介绍在STM32F103C8T6上,利用定时器输出PWM波形,进而驱动LED实现呼吸灯. 目录 一.任务要求 二.PWM简介 1.什么是PWM 2.相关概念 3.PWM的产生 4.PWM的通道 ...
- 【跟着江科大学Stm32】STM32F103C6T6_实现呼吸灯_代码
PWM.h #ifndef __PWM_H #define __PWM_Hvoid PWM_Init(); void PWM_SetCompare1(uint16_t Compare);#endif ...
- 嵌入式小白学习:STM32实现定时器控制LED灯
嵌入式小白学习:STM32实现定时器控制LED 目录 嵌入式小白学习:STM32实现定时器控制LED Part1.理论基础 Part2.环境的配置 Part3.代码的更改 Part4.实物的连线 Pa ...
- 【STM32学习笔记-LED呼吸灯】
STM32学习笔记-点亮LED灯 文章目录 STM32学习笔记-点亮LED灯 一.呼吸灯原理 二.呼吸灯代码 1.main.c 2.led.c 3.led.h 三.代码分析 一.呼吸灯原理 占空比:占 ...
- 呼吸灯51单片机c语言编程,51单片机基于定时器实现呼吸灯(C8051F020单片机)
一.实现思路 原理:利用PWM信号控制LED灯的亮暗程度,实现LED灯由暗到亮又由亮到暗的渐变过程. 方法:通过定时器设置LED所接引脚的高低电平持续时间,模拟出PWM波. 二.关键问题--PWM的频 ...
- C语言开定时器做呼吸灯程序,[求助]呼吸灯的编程思路(C语言)
/*************************************************************** * 程序说明:使用P3.2和P3.4来控制P0端口的LED灯,达到手动 ...
- C语言开定时器做呼吸灯程序,简单的基于51单片机定时器上呼吸灯程序
#include #define ufloat unsigned float #define uchar unsigned char #define uint unsigned int ucha ...
- STM32实现定时器和LED呼吸灯
目录 一.实现定时器 1.定时器的介绍 1.1定时器的概念及作用 1.2定时器的分类 2.新建项目 2.1新建 2.2选择STM32F103C8T6芯片 2.3配置SYS 2.4配置RCC 2.5配置 ...
- 单片机开发—呼吸灯的三种实现方法
目录 一.前言 1.什么是呼吸灯 2.如何实现呼吸灯 二.利用for循环实现呼吸灯 三.利用定时器实现呼吸灯 1.利用定时器中断实现 2.利用定时器输出PWM波实现 四.总结 一.前言 提示:本文使用 ...
最新文章
- Oracle-01033错误处理
- linux后门查杀工具付费,查杀linux后门跑虚拟货币程序.md
- 印度软件业崛起的奥妙
- 【CodeForces - 1102C 】Doors Breaking and Repairing (思维,简单博弈)
- Golang——map集合初始化、键值操作、map作为函数参数的使用
- Java手写线程池(不带返回值、带返回值)
- 企业如何选择数据分析架构?——谈谈3种架构的利弊
- labview圆环里实物动画图形_LabVIEW编程技巧:功能强大的变体数据类型用法
- 一个WinForm记事本程序(包含主/下拉/弹出菜单/打开文件/保存文件/打印/页面设置/字体/颜色对话框/剪切版操作等等控件用法以及记事本菜单事件/按键事件的具体代码)...
- CSDN统计出错:一天访问量竟然有48798
- Innovus中timing eco后setup margin跑哪里去了?(知识星球福利活动)
- AltRun调用cmd并刷新DNS
- mysql odbc 卸载_Linux卸载MySQL
- xlsxwriter
- HTML页面只能使用微信浏览器打开
- ubuntu 16.04硬盘分区方案
- 使用Google Analytics统计用户留存率
- 安装vag服务器虚拟机,FusionAccess桌面云组件介绍/安装
- 中国联通大幅下调国际漫游费
- MATLAB语言的串口助手
热门文章
- es 常用DSL查询语序 以及springDataES对应和使用
- rabbitmq Confirm三种模式
- linux常用命令-1备份压缩
- 安固士科技|数字化智慧工地到底有哪些黑科技?
- 学生HTML旅游景点网页作业作品 (HTML+CSS 制作江苏盐城家乡主题网站)
- 文心一言员工跳槽工资翻倍,猎头:百万年薪很正常
- 可缩放性ImageView(可以放大缩小)
- SSM毕设项目四川省非物质文化遗产之传统手工技艺数字平台i7k3a(java+VUE+Mybatis+Maven+Mysql)
- WebRTC混音器模块
- 请你谈谈Redis主从复制的理解?