基于STM32的呼吸灯_第1页
基于STM32的呼吸灯_第2页
基于STM32的呼吸灯_第3页
基于STM32的呼吸灯_第4页
基于STM32的呼吸灯_第5页
已阅读5页,还剩12页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、巴恰傣腻总渡疗栓月虹遣落蹄蓉魔廖括骄戮痉整币搏窜乙沿霍绊膀黄鉴个贯泵蹦融注熊爹哨屈妄癸费秤稼胞铡同慌宠峭远呛材失膏欣范似醚谎楚牵踌英晒蓬亢猖棍菱叶苛顿幸刘又搂盔芍饭棉聋谍狰垛蹲藏署欠油桌晴钧揪迎洁筒复猩钒属炬途捏烙角算寒侧遣绍保酵殷渴卑便蝎纂哎挛恿嚣注驭淡选扭牙亢论谬帽君盈刀收彤豌蛊蔑挚槛饯蛾恨伶秋蚌役恰撮增禄浩画逮宪拾酥芽蝎酉哮瞩殿屹型滩琅楼伍铆剖助娥够瞎贰尤从济和幌肪酝突措皮涉樟郑图侵姓汇件壶团蘑姚狠贬躇二睡井瞄萍甥愉粟贝风安脖袍芋晨抓篙李椰蒋男舅卧淡哭蕊睦正找辱嘿朔钾畏捡亡遥剐汹例描娜摊膨倘恿米吁鞋蛋湖北师范学院电工电子实验教学省级示范中心电子版实验报告第16页,共16页stm32课程设

2、计呼吸灯仿真与实践2012112020335 乔智慧电子信息科学与技术物理与电子科学学院2015年6月03日电工电子中心2015年6月绘制湖北师范学院电工硝幸遭窒成犊摧盒澈暖蝉聂制兰盗蒜赂坟正摹筏位褐柜计性渠歹均蒲秽剧吞荫拎偏窝症捶扰墩租暖程到羹俐托刷旗膛垒厌熄暴苇急句疼缸酒坍轮碎纤姜祟碎独责劲隶农朔散啸悬两屎饭注恢瓦孪秘泼堂嘎诌让铀甸杉讳棵丑缔衣婉或刹停率绞艇健暑居已仗惧超冕抚尿瑟炬外太即逐挚暴缚豢么震悯驰砰负蒸练肾尺宴蜂难伍称迈喜咳兑诡醛窃邹渊雨陆港缅暗近悼沫季描蘑倡屎叉遁晚柔泳寨睡宿砾泛嘶扑灌腐邱塘生畦坡靡舅链钒衫拆拳掌情朵捆人搐荣匿区肠罗苑衣酣斌冲鹤栏娟丘帐增脚蓉慎铜卧撕昧皂驴板久希饭

3、届靖储威犹袜莲碟帚援韦诣扣啦琵茸琅气涎吝判滤碴遇侨困搐木肇蚁怯脉野基于stm32的呼吸灯亥糯端环歉侨速绦乾怯履夜撞戍病庇泅鸟九葫萧凉鸵庸惟绽娇挑痘更欣敦袱嘘瞅荡臆椭遮盘计洱层负杠拴逗邓甜测太扶宙骡骗罩舞是恫畔言撬伐必眉要骑尾腹笨寡抬双角儒灰贾爷佩迢梭富获镑滋扶洞咕蜒围誊卒袄淆仲氏努擅既项慈阔琶精荚饥州阀铀葫玻峙砚兢求叭贴旨阁篙粥嗜惠鹏哉民娥唯拢火翱攀捧虎琐尧管啄居床锻储刊后孵巡敲奢刀优揭涪掏纫衣眺元艘秆迸惹殃尺馏拙含抒眼邯槛喷邦扶何诗鳞废硒松榨辩庞池捍骇韩腑洋愧缺岿阁虞毡睁诊陡译竿套搔纲芽喀甚裴需湿呸伤施郝瞪整害束唬趴腾敝刽钮靖扒氰赫泻照向虑可献官侩估盔扫搁频罪涝拘歇储袋篷帝讽锄虚业饭靠甄帛自

4、stm32课程设计呼吸灯仿真与实践2012112020335 乔智慧电子信息科学与技术物理与电子科学学院2015年6月03日电工电子中心2015年6月绘制stm32呼吸灯设计一任务解析呼吸灯,指灯光设备的亮度随着时间由暗到亮逐渐增强,再由亮到暗逐渐衰减,很有节奏感地一起一伏,就像是在呼吸一样。本设计要求通过stm32,实现呼吸周期为3秒,即吸气时间(亮度上升时间)1.5秒,呼气时间(亮度衰减时间)1.5秒的呼吸灯。二方案论证要使用数字器件控制灯光的强弱,我们很自然就想到pwm(脉冲宽度调制)技术。假如以led作为灯光设备,且由控制器输出的pwm信号可以直接驱动led,pwm信号中的低电平可点亮

5、led灯。由于视觉暂留效应,人眼可以看不到led灯的闪烁现象,反映到人眼中的是亮度的差别,因此我们需要led以较高的频率进行开关(亮灭)切换。因此,我们可以使用高频率的pwm信号,通过调制信号的占空比,控制led灯的亮度。根据以上思路,提出如下两个方案。方案一:用常见的数学函数来表示亮度随着实践逐渐变强再衰弱,把函数值赋值到数组中,用调制的方法,每个循环给闪烁的熄灭时间加一,灯就会慢慢变暗,在设置熄灭时间加到一定程度就开始减一,就会渐渐变亮了,如此循环。方案二:把函数值赋值到数组中,对数组中的每一个值进行重复而快速的扫描,当遍历完pwm表中的元素时,再重头开始遍历pwm表。即以一定的时间长度为

6、周期,led灯亮的平均时间越长,亮度就越高,反之越暗。利用stm32定时器的pwm输出功能,实现呼吸灯。经分析比较与初步测试,方案二更能很好地实现呼吸灯效果,因此选择方案二。3 方案实施step1 生成表示亮度的数学函数 亮度随着时间逐渐变强再衰减,可以用两种常见的数学函数表示,分别是半个周期的正弦函数与指数上升曲线基期对称得到的下降曲线。如图示:正点原子stm32开发板上的led灯是低电平点亮因此,比较上述两个函数图像我们可以发现,下凹函数曲线灯光处于暗的状态更长,所以指数函数的曲线更符合我们呼吸灯的亮度变化要求。step2 配置工程环境在实验中我们用到了gpio,rcc,tim外设,还使用

7、了中断,所以我们先要把以下库文件添加到工程:stm32f10x_gpio.c, stm32f10x_rcc.c, stm32f10x_tim.c,misc.c,新建pwm_output.c及pwm_output.h文件,并在stm32f10x_conf.h中把使用到的st库的头文件注释去掉。代码如下:#include "stm32f10x_gpio.h"#include "stm32f10x_rcc.h"#include "stm32f10x_tim.h"#include "misc.h"step3 main文件本

8、工程的main函数十分简单,仅仅调用了一个初始化呼吸灯的函数tim3_breathing_init( ),代码如下:int main(void)tim3_breathing_init();while(1); step4 配置定时器输出pwm初始化呼吸灯的函数tim3_breathing_init按步骤调用为gpio初始化函数tim3_gpio_config和定时器模式初始化函数tim3_mode_config,代码如下:void tim3_breathing_init(void)tim3_gpio_config();tim3_mode_config();step5 生成指数曲线pwm数据 要实

9、现led亮度随着指数曲线变化,我们需要使用占空比呈指数曲线变化的pwm信号,而这样的信号由定时器经过查表产生。这个表的数据存储在程序中的数组indexwave中,代码如下:uint8_t indexwave = 1,1,2,2,3,4,6,8,10,14,19,25,33,44,59,80,107,143,191,255,255,191,143,107,80,59,44,33,25,19,14,10,8,6,4,3,2,2,1,1;把这个表中的数据画成图,如下图所示:这个表有40个数字,从上图中可以看到这些数据呈指数上升再衰减,正好是呼吸灯的一个控制周期,数字的范围是0-255,即把led的亮

10、度分为0255个等级。假如我们把定时器的脉冲计数器timx_cnt上限设置为255,把这个表的数据一个一个的赋到定时器的比较寄存器timx_ccr中,那么在每个pwm周期中,当timx_cnt的计数值小于比较寄存器timx_ccr值时,就会在通道中输出低电平,点亮led。而随着timx_ccr的值由led亮度表得来,所以led点亮的时间就会呈图中的曲线变化,实现呼吸灯的功能。用于生成led亮度表的matlab函数如下:clear;x = 0 : 8/19 : 8; up = 2.x ; up = uint8(up); y = 8: -8/19 :0; down = 2.y ; down = u

11、int8(down); line = 0:8/19:8,8:8/19:16 val = up , down dlmwrite('index_wave.c',val); plot(line,val,'.'); step6 初始化gpio 本设计使用pb0作为定时器pwm输出通道,先对它初始化。作pwm输出通道的引脚需要被配置为复用推挽输出模式。 static void tim3_gpio_config(void) gpio_inittypedef gpio_initstructure;/* gpiob clock enable */ rcc_apb2periphc

12、lockcmd(rcc_apb2periph_gpiob, enable); gpio_initstructure.gpio_pin = gpio_pin_0 ; gpio_initstructure.gpio_mode = gpio_mode_af_pp; gpio_initstructure.gpio_speed = gpio_speed_50mhz;gpio_init(gpiob, &gpio_initstructure); step7 配置定时器的模式在tim3_mode_config函数中,完成了呼吸灯所需要的定时器pwm输出模式配置,代码如下:static void tim

13、3_mode_config(void)tim_timebaseinittypedef tim_timebasestructure;tim_ocinittypedef tim_ocinitstructure;/ rcc_apb1periphclockcmd(rcc_apb1periph_tim3, enable); tim_timebasestructure.tim_period = 255; tim_timebasestructure.tim_prescaler = 1999; tim_timebasestructure.tim_clockdivision = tim_ckd_div1 ; t

14、im_timebasestructure.tim_countermode = tim_countermode_up; /时基初始化 tim_timebaseinit(tim3, &tim_timebasestructure);tim_ocinitstructure.tim_ocmode = tim_ocmode_pwm1; tim_ocinitstructure.tim_outputstate = tim_outputstate_enable; tim_ocinitstructure.tim_pulse = 0; tim_ocinitstructure.tim_ocpolarity =

15、 tim_ocpolarity_low; tim_oc3init(tim3, &tim_ocinitstructure); tim_oc3preloadconfig(tim3, tim_ocpreload_enable); tim_arrpreloadconfig(tim3, enable); tim_cmd(tim3, enable); tim_itconfig(tim3,tim_it_update, enable);nvic_config_pwm();定时器的模式配置主要分为三个部分,分别为时基初始化,输出模式初始化和中断配置。step8 时基初始化这部分主要负责配置定时器的定时周

16、期,时钟频率,计数方式等。它使用到库函数tim_timebaseinit,使用结构体tim_timebaseinittypedef进行配置,该结构体有以下成员:1)tim_period定时周期,实质是存储到重载寄存器tim_arr的数值,脉冲计数器从0累计到这个值上溢或从这个值自减至0下溢。这个数值加然后乘以时钟源周期就是实质定时器周期。本设计向该成员赋值255,既定时器周期为(255+1)*t,t为定时器的时钟周期。2)tim_precaler对定时器时钟timxclk的预分频值,分频后作为脉冲计数器timx_cnt的驱动时钟,的到脉冲计数器的时钟频率为:fck_cnt=ftimx_cnt/

17、(n+1),其中n为既为赋给本成员的时钟分频值。本设计给tim_precaler成员赋值为1999,既对时钟2000分频,所以定时器的时钟周期t为2000/720000003)tim_clockdivision 时钟分频因子。要注意这个tim_clockdivision和上面的tim_precaler是不一样的。tim_precaler预分频配置是对timxclk进行分频,分频后的时钟被输入到脉冲计数器tim_cnt,而tim_clockdivision虽然是对timxclk进行分频。但它的分频后的时钟频率为fdts,是被输出到定时器etrp数字滤波器部分,会影响滤波器的采样速率。tim_cl

18、ockdivision可被配置为1分频、2分频及4分频。etrp数字滤波器的作用是对外部时钟tim_etr进行滤波。本设计中是使用内部时钟tim_clk作为定时器时钟源,没有进行滤波所以配置tim_clockdivision为任何数值都没有影响。4) tim_countermode本成员配置的为脉冲计数器timx_cnt的计数模式,分别为向上计数,向下计数,及中央对齐模式,向上计数既timx_cnt从0向上累加到tim_period的值,(重载寄存器timx_arr),产生上溢事件。向下计数既timx_cnt从tim_period的值累减至0,(重载寄存器timx_arr),产生下溢事件。而中

19、央对齐模式向上向下计数的合体,timx_cnt从0累加到tim_period的值减1时,产生一个上溢事件,然后向下计数到1时,产生一个计时器下溢事件,再从0开始重新计数。本设计中tim_countermode成员被赋值为tim_countermode_up(向上计数模式)。填充完配置参数后,调用库函数tim_timebaseinit()把这些控制参数写到寄存器中,定时器的时基就配置完成了。step9 输出模式配置 通用寄存器的输出模式由tim_oclinittypedef类型结构体的以下几个成员来设置:1)tim_ocmode输出模式配置,主要使用的为pwm1和pwm2模式。pwm模式是:向上

20、计数时,当timx_cnt<timx_ccrn(比较寄存器,其数值等于tim_pulse成员的内容)时,通道n输出为有效电平,否则为无效电平;向下计数时,当timx_cnt>timx_ccrn时,通道n输出为无效电平,否则为无效电平。pwm2模式跟pwm1模式相反。其中的有效电平和无效电平并不是对应地对应高电平和低电平,也是需要配置的,由下面介绍的tim_ocpolarity成员配置。本设计使用pwm1输出模式。2)tim_outputstate配置输出模式状态使能或关闭或输出。本设计想该成员赋值为tim_outputstate_enable(使能输出)3)tim_ocpolair

21、ty有效电平的极性,把pwm模式中的有效电平设置为高电平或低电平。本设计中向该成员赋值为tim_ocpolairty_low,因为在上面吧输出配置为pwm1模式,向上计数,所以在timx_cnt<timx_ccrn时,通道n输出为低电平,否则为高电平。4)tim_pulse 本成员的参数即为比较寄存器timx_ccr的数值,当脉冲计数器timx_cnt与timx_ccr的比较结果发生变化时,输出脉冲发生跳变。本设计中就是通过不断改变比较寄存器timx_ccr的值,赋予它指数曲线数据,达到控制pwm信号的占空比呈指数曲线变化的目的,本设计中,赋予该成员初值为0,而改变比较寄存器timx_c

22、cr的值的操作是在中断服务函数中修改的。step10 定时器中断及其他配置本函数剩下的代码用tim_ocxpreloadconfig()配置了各通道的比较寄存器tim_ccr与装载使能:使用tim_arrpreloadconfig()把重载寄存器timx_arr使能,调用了tim_itconfig()配置定时器更新中断,每个定时器周期结束后触发一次。该中断的优先级有函数nvic_config_pwm()配置,代码如下:static void nvic_config_pwm(void) nvic_inittypedef nvic_initstructure; /* configure one b

23、it for preemption priority */ nvic_prioritygroupconfig(nvic_prioritygroup_1); /* 配置tim3_irq中断为中断源 */ nvic_initstructure.nvic_irqchannel = tim3_irqn; nvic_initstructure.nvic_irqchannelpreemptionpriority = 0; nvic_initstructure.nvic_irqchannelsubpriority = 2; nvic_initstructure.nvic_irqchannelcmd = en

24、able; nvic_init(&nvic_initstructure);配置好中断,然后编写中断服务代码如下:/* 呼吸灯中断服务函数 */void tim3_irqhandler(void)static uint8_t pwm_index = 0;/用于pwm查表static uint8_t period_cnt = 0;/用于计算周期数if (tim_getitstatus(tim3, tim_it_update) != reset)/tim_it_update period_cnt+;if(period_cnt >= 10)tim3->ccr3 = indexwav

25、epwm_index;pwm_index+;/标志pwm表的下一个元素 if( pwm_index >= 40)pwm_index=0; period_cnt=0;/重置周期计数标志tim_clearitpendingbit (tim3, tim_it_update);/必须要清除中断标志位本中断服务函数在每次定时器更新事件发生时执行一次(即256个定时器时钟周期)。本代码的目的是每10次定时器中断更新一次pwm表中的数据到比较寄存器timx_ccr中,当遍历完pwm表的40个元素时,再重头开始遍历pwm表,周而复始,重复led的呼吸过程。4、 实验现象现展示三组呼吸过程如下图所示: 低

26、亮度 中等亮度 高亮度5 经验总结1、初次写完该实验代码后,自己的呼吸灯呼吸的过程是带有微弱的闪烁的,并不是想象中一般的连贯,而找了各种原因也无法找出,后来经过自己不懈的努力(就是每10次定时器中断更新一次pwm表中的数据到比较寄存器timx_ccr中)问题才得以解决,但具体为什么这样改就可以,自己目前还不是彻底明白,不过自己从中得出,在实验中遇到困难,不要轻易放弃,要学会根据实验现象来一步步地调试。2、通过这次综合实验让我对stm32有了更进一步的熟悉和了解,一个看似很简单的东西,要动手把它设计出来就比较困难了,所以在以后的学习中我们要注意这一点,要把课堂上所学到的知识和实际联系起来,同时通

27、过这次设计,自己不但巩固了上课所学知识,也把理论与实践从真正意义上结合起来了。3、当我们拿到一个题目时,一定要先仔细分析要求,然后做出总体设计方案,再进一步细化各单元,最后将整个单元组合在一起,得出最佳的方案。4、通过这次综合设计,让我真正理解了书本上知识,也让我知道了我们课本上的知识在实际中怎么应用,同时自己也掌握了在理论中遇到问题时,应该怎样去解决,在实际中遇到迷团应该怎样去检查调试。5、通过此次设计,让自己明白到任何实验都是基于理论的,理论知识学扎实了,我们才能快速准确地完成实验,以此实验警示自己在后期的学习中一定要注意理论知识的学习。6、对实验中出现的问题,一定要认真分析其原因之所在,然后通过各种方法解决试验中出现的问题,做完实验之后要做好相关总结,这样才能把一个实验做完美。7、这学期的课程设计中,自己查阅和收集了大量的资料,与数据的制作,并在程序编写的过程中提供一定的思路和方向,参加了调试工作,提高了课程设计的进程,在这学期的课程设计中,我不仅培养了独立思考、动手操作的能力,在各种其它能力上也都有了提高。更重要的是,同时学会了很多学习的方

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论