STM32之呼吸灯实验
首先,我想引用一下在一片博文里 看到 的一段话,写的很详细,
首先来说,你要使用PWM模式你得先选择用那个定时器来输出PWM吧!除了TIM6、TIM7这两个普通的定时器无法输出PWM外,其余的定时器都可以输出PWM,每个通用定时器可以输出4路PWM,高级定时器TIM1、TIM8每个可输出7路PWM,这里为了方便起见,我们选择与实验相同的TIM3的通道2来说明。选好定时器及通道后,下一步就是要使能定时器的时钟,根据需要看看是否需要重映射IO,然后就是配置输出PWM的IO及定时器,到这里原子的视频及例程都有详细的介绍,这里只需要提一点有些网友疑惑的TIM_TimeBaseStructure.TIM_ClockDivision = 0;这句话是什么作用?其实仔细看过技术手册后发现这句话与PWM输出实验其实是没关系的,这句话是设置定时器时钟(CK_INT)频率与数字滤波器(ETR,TIx)使用的采样频率之间的分频比例的(与输入捕获相关),0表示滤波器的频率和定时器的频率是一样的。至于其余部分,我就不再赘述。
那么,下面就贴上我自己的代码
这个代码可是我改了一天的结果啊。。。。
/*****************************************
利用pwm控制led亮度,
其实我们看到的是灯在呼吸,实际上灯是一直在以很高的频率在闪烁,每次闪烁的亮度都不一样,越来越亮,或者暗
由于人的视觉暂留效应,我们看到灯一直在亮,而且亮度在渐变。 日期:2016.2.25 ********************************************/ #include "stm32f10x.h" /* LED亮度等级 PWM表 */
uint8_t indexWave[] = {,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,,,,}; //函数申明 void Init_LED(void);
void NVIC_Config_PWM(void);
void Init_TIMER(void);
void Init_PWM(void);
void Delay_Ms(uint16_t time);
void Delay_Us(uint16_t time); int main(void)
{
SystemInit(); //系统时钟配置 Init_LED(); //LED初始化
NVIC_Config_PWM();
Init_TIMER(); //定时器初始化
Init_PWM(); //PWM初始化设置
GPIO_SetBits(GPIOG,GPIO_Pin_14); // LED D2 输出为高 while(); } void Init_LED(void)
{
GPIO_InitTypeDef GPIO_InitStructure; //定义一个GPIO结构体变量 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD| RCC_APB2Periph_GPIOG |RCC_APB2Periph_AFIO,ENABLE);
//使能各个端口时钟,重要!!! GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14; //配置LED D2端口挂接到PG14端口
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //通用输出推挽
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //配置端口速度为50M
GPIO_Init(GPIOG, &GPIO_InitStructure); //将端口GPIOD进行初始化配置 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 ; //配置LED D5端口挂接到13端口
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用功能输出推挽,这是重映射必要地,AF表示复用
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //配置端口速度为50M
GPIO_Init(GPIOD, &GPIO_InitStructure); //将端口GPIOD进行初始化配置 GPIO_PinRemapConfig(GPIO_Remap_TIM4,ENABLE); //将定时器4通道2重映射到PD13引脚,重要!!
} //我看很多资料都是这样映射的 //还是野火比较专业,人的吸气呼气通常用时为3秒,算出来是这样的
//TIM_BaseInitStructure.TIM_Period = 256-1;
//TIM_BaseInitStructure.TIM_Prescaler = 2000-1; void Init_TIMER(void)
{ TIM_TimeBaseInitTypeDef TIM_BaseInitStructure; //定义一个定时器结构体变量 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); //使能定时器4,重要!! // TIM_DeInit(TIM4); //将TIM4定时器初始化位复位值 // TIM_InternalClockConfig(TIM4); //配置 TIM4 内部时钟 //TIM_BaseInitStructure.TIM_Period = 7200-1; //设置自动重载寄存器值为最大值 0~65535之间 1000000/1000=1000us=1ms
//TIM_Period(TIM1_ARR)=7200,计数器向上计数到7200后产生更新事件,
//计数值归零 也就是 1MS产生更新事件一次 TIM_BaseInitStructure.TIM_Period = -; TIM_BaseInitStructure.TIM_Prescaler = -; //自定义预分频系数为0,即定时器的时钟频率为72M提供给定时器的时钟 0~65535之间 TIM_BaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1; //时钟分割为0 TIM_BaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式 从0开始向上计数,计数到1000后产生更新事件 TIM_TimeBaseInit(TIM4, &TIM_BaseInitStructure); //根据指定参数初始化TIM时间基数寄存器 TIM_ARRPreloadConfig(TIM4, ENABLE); //使能TIMx在 ARR 上的预装载寄存器 TIM_Cmd(TIM4, ENABLE); //TIM4总开关:开启 TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE); //使能定时器中断 NVIC_Config_PWM(); //配置中断优先级 } void Init_PWM()
{
TIM_OCInitTypeDef TIM_OCInitStructure; //定义一个通道输出结构 TIM_OCStructInit(&TIM_OCInitStructure); //设置缺省值 TIM_OCInitStructure.TIM_Pulse = ; //设置占空比,占空比=(CCRx/ARR)*100%或(TIM_Pulse/TIM_Period)*100%
//PWM的输出频率为Fpwm=72M/7200=1Mhz; /* 下面五句话就把PWM 基本上配置完成,再加上上面定时器的使能,TIM_Cmd(TIM4,ENABLE) */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //PWM 模式 1 输出 , TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //使能输出状态 需要PWM输出才需要这行代码 TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //TIM 输出比较极性高 ,就是开始 计数到ccr之前都是high,因为这里的led是正逻辑点亮 TIM_OC2Init(TIM4, &TIM_OCInitStructure); //根据参数初始化PWM寄存器 ,使能通道CCR2 TIM_OC2PreloadConfig(TIM4,TIM_OCPreload_Enable); //使能 TIMx在 CCR2 上的预装载寄存器,很关键和容易遗漏的一部 //TIM_CtrlPWMOutputs(TIM4,ENABLE); //设置TIM4 的PWM 输出为使能 } void NVIC_Config_PWM(void) //配置嵌套向量中断控制器NVIC
{ NVIC_InitTypeDef NVIC_InitStructure; NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); //设置中断优先级分组2 NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn; //设定中断源为PC13 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = ; //中断占优先级为0 NVIC_InitStructure.NVIC_IRQChannelSubPriority = ; //副优先级为0 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能中断 NVIC_Init(&NVIC_InitStructure); //根据参数初始化中断寄存器 } void TIM4_IRQHandler(void) //中断入口函数
{
static uint8_t pwm_index = ; //用于PWM查表
static uint8_t period_cnt = ; //用于计算周期数 if (TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET) //TIM_IT_Update
{
period_cnt++;
if(period_cnt >= ) //若输出的周期数大于10,输出下一种脉冲宽的PWM波,在这里野火说他也不知道为什么大于10
{ TIM4->CCR2 = indexWave[pwm_index]; //根据PWM表修改定时器的比较寄存器值
pwm_index++; //标志PWM表的下一个元素 if( pwm_index >= ) //若PWM脉冲表已经输出完成一遍,重置PWM查表标志
{
pwm_index=;
} period_cnt=; //重置周期计数标志
} TIM_ClearITPendingBit (TIM4, TIM_IT_Update); //必须要清除中断标志位 }
} /*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
** 函数名称: Delay_Ms_Ms
** 功能描述: 延时1MS (可通过仿真来判断他的准确度)
** 参数描述:time (ms) 注意time<65535
** 作 者: Dream
** 日 期: 2011年6月20日
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/
void Delay_Ms(uint16_t time) //延时函数
{
uint16_t i,j;
for(i=;i<time;i++)
for(j=;j<;j++);
}
/*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
** 函数名称: Delay_Ms_Us
** 功能描述: 延时1us (可通过仿真来判断他的准确度)
** 参数描述:time (us) 注意time<65535
** 作 者: Dream
** 日 期: 2011年6月20日
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/
void Delay_Us(uint16_t time) //延时函数
{
uint16_t i,j;
for(i=;i<time;i++)
for(j=;j<;j++);
}
/*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
End:-D:-D:-D:-D:-D:-D:-D:-D:-D:-D:-D:-D:-D:-D:-D:-D:-D:-D:-D:-D
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/
STM32之呼吸灯实验的更多相关文章
- 【iCore4 双核心板_ARM】例程八:定时器PWM实验——呼吸灯
实验原理: STM32的定时器有PWM功能,iCore4的蓝色LED连接在定时器的输出接口上, 可以通过定时器的PWM输出控制LED的亮度,从而实验呼吸灯的功能. 核心代码: int main(voi ...
- STM32呼吸灯
使用STM32开发板和mbed平台实现的一个呼吸灯.材料,LED灯,电阻,STM32开发板. 先上一张效果图. 背景: 我们之前设置GPIO口使用了DigitalOut,数字信号输出.只能是GPIO口 ...
- 好玩的WPF第二弹:电子表字体显示时间+多彩呼吸灯特效button
我们先来看看Quartz MS字体动态显示系统时间的效果,难度相较于上一篇也要简单很多. 首先是定义一个TextBlock例如以下. <Grid> <TextBlock Name=& ...
- 浅浅的分析LED呼吸灯的实现和PWM的关系
前言 在本周,我们在python课上做了一个实验,用ARDUINO使小LED灯模仿出呼吸灯的效果,实验进行的很成功,但是机器当仅输出高/低电平的时候是怎么样才能做到渐亮渐暗(输出电压)的变化呢?在这里 ...
- [FPGA]Verilog利用PWM调制巧妙完成RGB三色彩虹呼吸灯(给简约的题目以美妙的解答)
概述 实现彩虹呼吸灯 题目就是这么简短,但这是目前我碰到的最有意思的一道题目,因为他有无数种解决方法,并且每一种都是那么高级或者巧妙,比如 可以利用3路不同初相的PWM调制信号驱动三颗RGB灯重叠呼吸 ...
- 12-ESP8266 SDK开发基础入门篇--PWM,呼吸灯
https://www.cnblogs.com/yangfengwu/p/11094085.html PWM其实没有什么,就是看着官方给的API,,,然后就是用呗 对了,其实对于RTOS SDK版本的 ...
- Android 呼吸灯流程分析
一.Android呼吸灯Driver实现 1.注册驱动 代码位置:mediatek/kernel/drivers/leds/leds_drv.c 602static struct platform_d ...
- Nubia Z5S 基于官方H207/4.4内核的Mokee4.4.4 RC3.2 (2014.7.31修复呼吸灯(能亮依旧不能呼吸))
特别感谢 yun3195 和 轻描淡写Yhw 帮忙測试 转帖请务必注明本链接地址: http://blog.csdn.net/syhost/article/details/36444259 此ROM ...
- PWM(脉宽调制)——LED特效呼吸灯设计
简述PWM PWM--脉宽调制信号(Pulse Width Modulation),它利用微处理器的数字输出来实现,是对模拟电路控制的一种非常有效的技术,广泛应用于测量.通信.功率控制与变化等许多领域 ...
随机推荐
- 如何更新 OpenStack 组件?- 每天5分钟玩转 OpenStack(161)
这是 OpenStack 实施经验分享系列的第 11 篇. 本节教大家更新 OpenStack 组件的方法.请注意,是更新(Update)而不是升级(Upgrade).更新是给组件打补丁,版本不变:而 ...
- 让SQL再快一点儿
文章转载自「开发者圆桌」一个关于开发者入门.进阶.踩坑的微信公众号 SQL即结构化查询语言(Structured Query Language),是一种特殊目的的编程语言,是一种数据库查询和程序设计语 ...
- 每天一个Linux命令 3
Linux grep命令详解: grep(global search regular expression(RE) and print out the line,全面搜索正则表达式并把行打印出来)是一 ...
- 从Hash Killer I、II、III论字符串哈希
首先,Hash Killer I.II.III是BZOJ上面三道很经典的字符串哈希破解题.当时关于II,本人还琢磨了好久,但一直不明白为啥别人AC的代码都才0.3kb左右,直到CYG神犇说可以直接随机 ...
- ansj 2.0.7 错误例子分析
我在做一个solr的项目,分词选定了ansj分词. 选择ansj的原因: 1)身边若干朋友的念叨,说是效果不错 2)网上看了若干评论,说是不错 3)自己尝试了一些case,觉得确实不错. 好了,项目中 ...
- 企业架构(TOGAF)学习
自从听了公司内部的一堂<企业架构设计>培训,顿时觉得如获至宝. 先说下笔者,笔者是一名二流本科毕业,工作三年,基层的软件开发工程师,梦想着有朝一日成长成一名架构师.可是笔者对于如何成长成一 ...
- input的type属性引申的日历组件
HTML5规范里只规定date新型input输入类型,并没有规定日历弹出框的实现和样式.所以,各浏览器根据自己的设计实现日历.目前只有谷歌浏览器完全实现日历功能.相信这种局面很快就会结束,所有的浏览器 ...
- 解决HTML textarea 标签出现大量空格
就是什么内容也不写,然后前面却有一堆空格 原因是 textarea标签换行了 <textarea cols=" id="serve_content" name=&q ...
- 头文件limits—各个类型的数据的范围
要想知道各个类型的数据如int.float.double.long等所能表示的范围,可以加上头文件<limits>,这些类型的范围都在类numeric_limits中定义了的. 类模板:t ...
- nodejs 使用mongoose 操作mongodb
nodejs操作mongodb可以使用mongoose: Mongoose is a MongoDB object modeling tool designed to work in an async ...