河南师范大学 本科毕业论文
学号: **********
基于STM32的自行车转向刹车灯
学院名称: 物理与电子工程学院 专业名称: 电气工程及其自动化 年级班别: 2011 级 姓 名: 指导教师:
2015年5月
基于STM32的自行车转向刹车灯
摘 要
本课题选用了STM32F103C8T6单片机和ADXL345三轴加速度传感器,来控制全彩灯珠和红外线激光灯,达到指示自行车的刹车或者转向的功能。
本文首先介绍了STM32系列芯片和ADXL345加速度芯片的功能和特点。之后详细介绍了刹车灯系统的硬件和软件设计。难点是硬件设计中的问题与思考,重点软件设计中运用模块化编程的方法组建代码的过程。经过调试运行结果分析,该设计实现了刹车时全彩灯珠自动亮起,转向前主动触发,使红外线激光灯产生显著的转向信号的功能,满足了设计的要求。论文最后总结了设计中出现的问题以及解决方法。
关键字:STM32,ADXL345,自行车刹车灯,转向灯
I
The Bicycle Break Light and Steering Lamp Based on STM32
Abstract
This subject selects the STM32F103C8T6 micro-controller and ADXL345
three axis acceleration sensor, to control the RGBLED and infrared laser light, to indicate a bicycle braking or steering function.
First this paper introduces some information and characteristics of STM32
series chip and ADXL345 acceleration chip. And then introduces the design of hardware and software of the system. The difficulty is the problem and thinking in the process of hardware design, using the method of modular programming key software design building code. Through the detailed analysis of the operation result, the design and implementation of the RGBLED automatically lights up when braking,active triggering makes the infrared laser light generated signal function significantly before steering,in accordance with the design requirements. The thesis finally summarizes the problems occurred in design and their solutions.
Keywords:STM32,ADXL345,the bicycle break lights ,steering lamp
II
目 录
基于STM32的自行车转向刹车灯........................................ I 摘 要.............................................................. I 前 言............................................................... 1 1 . Cortex-M3与STM32简介 .......................................... 3
1.1Cortex-M3与STM32的关系 ..................................... 3 1.2 STM32的优越性 .............................................. 3 1.3 STM32的系统结构、内核及指令集示意图: ...................... 4 1.4 STM32F103C8T6的基本参数、内设与引脚位 ...................... 5 2. ADXL345与SPI简介 ............................................... 7
2.1 ADXL345简介 ................................................ 7 2.2 SPI介绍 .................................................... 8 3 硬件设计......................................................... 10
3.1 硬件设计概述............................................... 10 3.2 电源部分的硬件设计......................................... 12 3.3 STM32和ADXL345硬件设计 ................................... 13 3.4 全彩灯珠的设计............................................. 15 3.5转向按键与红外线激光灯的设计 ............................... 16 3.6其它硬件设计 ............................................... 18 4 软件设计......................................................... 21
4.1 STM32固件库开发概述 ....................................... 21 4.2 程序代码结构............................................... 21 4.3 main.c结构说明 ............................................ 22 4.4 按键功能软件设计........................................... 23 4.5 ADXL345的软件设计 ......................................... 26 4.6 模式切换的软件设计......................................... 27
III
5 总结............................................................. 30
5.1 在调试过程中出现的问题和解决办法........................... 30 5.2 在软件设计中总结的技巧..................................... 31 5.3 个人成长................................................... 31 参考文献........................................................... 33 致 谢............................................................. 34
IV
前 言
骑自行车既是一种环保的出行方式,又是一种健康的运动方式。
对于个人来说,骑自行车不仅可以减肥,使身体匀称,同时可以强化心脏功能,有避免高血压等疾病的功能。骑自行车可以使骑行者血液循环加速,主动吸入大量新鲜空气,从而使骑行者脑筋更清楚。有研究显示,骑自行车上班或者上学,可以提升人的幸福感。特别是在风景优美的地方骑行,会让人觉得心旷神怡,充分感受到运动的快乐和自然的美好。
对于自然来说,骑自行车出行可节约能源、降低噪音、减少污染,生态效应明显。建设“资源节约型、环境友好型”社会是我国经济社会发展的客观要求。个人开车上下班会对环境产生巨大危害,给城市交通也带来巨大压力。因此积极提倡自行车出行,是利国利民的好事。
然而,中国的自行车骑行氛围非常不乐观。中国曾是自行车的王国,却像一些发达国家一样过度强调汽车经济,各个城市汽车保有量连年上升,冷落自行车成为常见社会现象,鄙视普通骑行者更是成为大众心理。另外,由于汽车尾气,工厂排污等造成的环境污染,导致许多城市适合户外运动的天数越来越少。加之中国司机普遍素质不高,在驾驶机动车行车过程中常常占用自行车道。特别是从自行车道超车这种行为,给骑行者带来很大的威胁。尤其是在夜间,机动车占道超车的危害更大。与机动车不同,自行车出现刹车、转向等行驶状态的变化时,没有显著的指示。如果在转向或者刹车时自行车道被机动车占用的话,对于骑行者来说将是非常危险的事情。
本设计可以归类为骑行装备的一种,设计初衷是为了给骑行者提供一种较为显著的可以警示转向或者刹车的工具。与头盔、护膝之类传统的骑行装备相比,可以在危险发生前提供预警,减小危险发生的几率。按照实现方法来说的话,本设计属于基于STM32单片机的一个小型电子设备。与常见的长亮型市售刹车灯相比,更加智能,功耗也更低。与无光源反射式的后座警示灯相比,本设计的警示
1
方式更加显眼,也更加时尚。综上,本设计与其它骑行装备相比,是具有一定的独创性的智能化警示设备。
本设计虽然只是为了检验学习情况,而做的一个小制作性质的发明,但其设计思路却以正规产品思路为指导,没有追求一味地多添加功能,以增加其技术含量,而是真正考虑到如果要作为实际产品的话,需要考虑的功能、成本和功耗。因此,本设计最大程度追求降低功耗,裁去多余硬件,功能求专而不求多。
本文共分为5部来写,首先介绍了STM32系列芯片的和ADXL345芯片的特点,然后是系统硬件设计和系统软件设计,最后是总结设计中出现的问题及其解决办法,个人收获。
2
1 . Cortex-M3与STM32简介
1.1Cortex-M3与STM32的关系
STM32是采用Cortex-m3的内核的一种CPU,Cortex-M3是ARM架构的一种。 Cortex-M3采用ARM V7构架,支持Thumb-2指令集,同时具有很多强大的特性。较之ARM7 TDMI,Cortex-M3不仅拥有更强的性能、更高的代码密度、而且可以位带操作、中断嵌套、低成本、低功耗。
国内 Cortex-M3 市场,意法半导体公司的STM32是毋庸置疑的领跑者,不论是在市场占有率,技术支持还是使用氛围等方面,都远超其他对手。所以本设计在Cortex-M3芯片的时候,自然而然地就考虑了STM32。 1.2 STM32的优越性
STM32 的优越性体现在以下几个方面:
1. 超低的价格。几乎与8位单片机的价格持平是STM32最大的优势。就本设计所选的STM32F103C8T6而言,在北京中发电子市场买10片的话,每片仅需10.5元。而一块STCC52RC就需要9元。两者的性能差别却非常之大。
2. 丰富的外设。STM32 拥有包括:TIMER定时器、SPI通讯协议、I2C总线、USB通讯协议、CAN总线、数模转换器、 模数转换器、RTC、DMA 等众多外设或者功能,具有很高的集成度。本设计中单片机通过SPI与ADXL345三轴加速度芯片进行通信。
3. 丰富的型号。STM32中的M3系列内核拥有多个系列上百种型号,十分丰富。其封装库也有较多的选择,如QFN、LQFP、BGA 等。本设计选取了LQFP48L封装,是一种方便手工焊接,且体积较小的封装。
4. 优异的实时性能。由于STM32芯片的多数IO口都可以通过不同的映射设置,来作为中断输入,所以提供了较多的中断数量,最多可达84个,且具有16级可编程的优先级,合理地规划中断数量和优先级可以有效保障实时性能。
5. 杰出的功耗控制。STM32所有的外设都有自身的时钟开关,相应外设的时钟被设置为关闭的话可以有效降低功耗。本设计充分应用了STM32的这个
3
特性,所有的外设全部以中断的方式来控制,在不使用的时候关闭相应时钟,追求最大程度降低功耗。
6. 较快的开发速度。ST将各个寄存器的操作集成了一个官方固件库,将寄存器的使用方法封装到不同的函数中,开发者通过API直接调用这些函数即可操作寄存器,不需要深入底层注重这些寄存器的操作细节,因此大大提升了开发速度。
7. 极低的开发成本。STM32的官方仿真器价格很低,且国产的仿真器质量也可以接受,不像某些单片机仿真器动辄上千,另外支持SWD和JTAG两种调试办法,方便使用。本设计使用SWD调试,只需要2个IO口,即可实现仿真调试。
1.3 STM32的系统结构、内核及指令集示意图:
图1-1 STM32的系统结构
4
图1-2 Cortex-M3处理器内核与Cortex-M3芯片的关系
图1-3 Thumb-2指令集与Thumb指令集的关系示意图
1.4 STM32F103C8T6的基本参数、内设与引脚位
基本参数:
类别:集成电路(IC) 所属:嵌入式微控制器 位数:32位 最高速度:72MHz
5
输入/输出IO数:37 程序存储器容量:中型K 程序存储器类型:Flash闪存 RAM容量:20K x 8 电源电压:2 V-3.6 V ADC:10x12b
工作温度:-40°C-85°C 封装/外壳:LQFP-48L贴片式
图1-4 STM32F103C8T6内设与引脚图
6
2. ADXL345与SPI简介
2.1 ADXL345简介
概述
ADXL345是一种体积小巧的低功耗三轴加速度芯片传感器,拥有可达13位的分辨率和16g的测量范围。输出16位补码数据,可通过SPI或I2C接口访问。
ADXL345可以在倾斜检测中测量静态重力加速度,由于高达3.9mg/LSB的分辨率,小于1度的倾斜角变化可以检测到。还可以测量运动或冲击导致的动态加速度。本设计中使用的功能就是在运动状态中检测动态加速度,属于移动设备应用的ADXL345,可以说是恰如其分的选择。
该器件提供以下几种特殊检测功能:
活动与否检测功能:通过比较某轴上的加速度与用户自定义的值来检测是否运动。
震动检测功能:检测任意方向的有无震动。 掉落检测功能:判断传感器是否处在在掉落过程中。
这些功能可以映射到两个中断输出引脚(第8脚和第9脚)中的一个。 参数
功耗:测量模式23uA(VS=2.5V),待机模式0.1uA 分辨率:10位固定分辨率,最大可调分辨率13位 电源电压VS:2V-6.3V 引脚高电平:1.7V-VS 工作温度:-40°C至+85℃ 引脚结构与功能
7
图2-1 引脚配置图 表2-1 引脚功能描述表
2.2 SPI介绍
SPI是串行外设接口(Serial Peripheral Interface)的缩写,SPI是一种简单易用的通讯协议,正在被越来越多的芯片采用,它可进行全双工通讯,所以速度很快,可同步。只占用四根线,不但节省了宝贵的芯片IO口资源,而且有利于进行PCB布局设计。
8
表2-2 SPI功能描述表
名称 功能 SDO SDI SCLK CS 描述 数据输出 主要的通讯线,负责输入主设备的数据,输出从设备的数据 数据输入 主设备数据输出,从设备数据输入,在单向传输时可以不使用此线 时钟 时钟信号,主设备负责提供时钟脉冲,允许数据按位传输,共数据输入线和输出线按照这个脉冲传输数据 片选 从设备使能信号,由主设备控制某从设备是否被选中,因此同一总线上可以连接多个SPI从设备。 SPI是串行通讯协议,即数据是按位的传输的。由SCLK提供时钟脉冲。从设备向主设备的数据输出通过SDO线,数据在时钟上升沿(或下降沿时)改变,在下一个下降沿(或上升沿)被读取。这样,在SCKL提供不少于8次脉冲时,就可以完成一个8位数据的传输。
一个满足SPI协议的设备中,至少需要一个主设备。只可以主设备控制SCKL,从设备不允许控制。当主设备未曾控制SCKL时钟信号线产生跳变时,从设备不进行数据的采集和传输。这样的好处是,主设备只需要控制SCKL时钟线就可以控制与从设备的通讯。
时序介绍
图2-2 SPI时序图
9
3 硬件设计
3.1 硬件设计概述
本设计的硬件设计经历了两个版本,V1.0和V2.0。。 本设计采用的设计流程是:
1. 考虑预期功能,进行器件的类别选择。 2. 广泛搜集资料,设计原理图。 3. 考虑板子与器件大小,设计PCB。 4. 焊接第一版PCB,调试程序。
5. 修改错误,优化布局,设计第二版PCB。 本设计的硬件电路设计软件是altium designer 13。
最初的想法是设计一个自行车的刹车灯,看上去要酷炫。当时有两个方案: 其1是直接改装自行车的刹车手柄,使手柄的活动处与车把的固定端导电连通,刹车的时候这两处分离,则电气连接断开。这样子几乎可以保证百分之百亮起刹车灯。缺点是不具备普适性,每个自行车需要不同的改装,另外技术含量也大大降低。
其2是使用加速度传感器芯片。通过MCU控制传感器芯片,读取加速度值来判断刹车状态。这种方案是很难达到很高的准确率的,因为对于芯片来说,它无法判断产生的加速度是在加速还是在刹车。假设自行车匀速前进的时候,三轴加速度的值与静止状态是一样的,因此无法判断此时的加速度值与前进方向的关系。
本设计选择方案2,选择加速度芯片。考虑到酷炫,所以采用了全彩灯珠。根据色光三原色原理,红绿蓝三种颜色的LED灯珠足以产生绚丽的色彩。
在设计原理图的时候,主要参考了正点原子的战舰STM32开发板和github上的项目ProgrammableLED。
在设计PCB的时候,首先考虑了板子的尺寸。由于要使用电池供电,所以板子的大小就有了。查阅到电池盒的尺寸后,确定了板子的尺寸为3.3cm*6cm,双面板,单面放置贴片元器件。在确定器件封装的时候,充分考虑了手工焊接的和本人焊接的水平,多数阻容器件采用了0805这样的较大封装。
10
值得一提的是,在PCB设计过程中得到了专业硬件工程师的指导,在确定板子尺寸和器件封装后,器件采用了手工布局,具体的布局和布线流程是这样的:
1. 将MCU放在最中间的位置上。
2. 根据接插件的特殊要求放置接插件。比如电源接入口必须放在左端,而红外激光灯放在上端。
3. 放置有特殊要求的器件,如为了美观,要将两个全彩灯珠对称放在MCU两端。易发热的器件离其它器件远一点。
4. 将电源相关的器件放置在电源接入口的附近。主要是一些电容,将这些电容排列整齐并且大容值的放在前边。
5. 根据与MCU管脚的连接关系,选取器件的放置区域。如某器件与芯片连接的管脚在右边,则尽量将此器件放置在芯片右边。
6. 考虑到减小焊接难度,将相似器件放在一块。
完成布局以后一定要手工布线。一是因为手工布线可以加深对板子的理解,调试的时候效率会高很多。二是因为自动布线会产生较多的过孔,而打过孔的钻头是易坏部件,会增加成本,并且如果大批量生产的话板子摆放层数较多,则下层的过孔可能很小,不合乎要求。虽然这个设计很简单,自动布线是有效的,但是为了养成良好习惯,指导老师建议我手工布线。
手工布线中需要注意顶层和底层的线不要平行,防止信号干扰。不要有小于90度的拐角。根据通过的电流设置线宽,等等。
将第一版印制出来后,焊接完成,烧录程序。发现一些错误,不得不通过割线,飞线等方式来调试。然后在第一版上调试软件,然后基本实现了预期功能。有些问题无法确定是软件问题还是硬件问题,所以这一步很艰难。
虽然,较为稳妥的开发流程是,先在开发板上调试代码,确认代码无误后根据预期功能对开发板进行硬件裁剪,然后制版。这样子可以避免软件硬件问题混淆,这也是学生学习常用的开发手段。但是工业开发是没有开发板的,直接由硬件工程师设计好板子,软件工程师写程序。为了更好地锻炼自己,所以我采用了后者。
艰难地修正了一些错误,优化了器件布局后,发出第二版。
11
图3-1 器件布局3D效果图
3.2 电源部分的硬件设计
考虑到本设计将采用电池供电,且各个器件均可在3V电压下工作,因此电源部分设计较为简单,只采用了磁珠和电容,抑制高频噪声和信号干扰。电池使用一段时间后会使供电电压下降,这个问题本可以通过采用升压电路来解决。但是考虑到升压电路的效率最高只有80%多,会浪费较多电量,所以放弃了这个设计。
12
图3-2 电源和芯片滤波电路原理图
图3-3 电源模块3D效果图
3.3 STM32和ADXL345硬件设计
MCU与加速度芯片都是较小的封装,手工焊接难度大。
MCU的封装为LQFP48,相邻管脚的中心距离仅仅0.5mm,手工焊接需要格外小心,要想成功焊接需要掌握一些方法。首先,用烙铁对一个最边角的焊盘上锡,建议是1号引脚(在PCB上是小白圈标记的,在单片机封装上是凹陷的小坑标记的),然后用镊子将单片机按照正确的方位摆正,用烙铁焊接上1号引脚,多焊接周边的几个一脚也是可以的,因为这一步的目的是固定,而不是一步到位,如果歪斜,可以加热焊锡重新调整位置。在烙铁温度350度的情况下,时间不是太长的话,芯片一般不会被烧坏。MCU固定好之后,用较多的焊锡把其它三个边的引脚全焊上,同时要稍微用力向下按一下引脚,使引脚可以贴在焊盘上。这时肯定会出现引脚的粘连的,这不是焊接失败,只要沿着引脚的平行方向把多余的锡带走就好。使用烙铁带走焊锡的过程既要注意烙铁头的运动轨迹,不可贴着PCB
13
板,以免烫断走线,又要注意操作速度,太慢的话无法带走多余的焊锡。最后仔观察,确保没有短路。
ADXL345的芯片封装看上去好像间距较大,实则是板子焊接过程中最艰难的部分。由于它的引脚全在底面,只能使用热风焊接。首先要用酒精擦一擦焊盘,确保没有灰尘或者杂物;然后在焊盘上小心的涂上一点焊锡膏,需要保证每个触点上都有焊锡膏且焊锡膏不能过多。然后将芯片小心放在焊盘上,注意1号引脚的位置,各个引脚与焊盘的位置对正。用镊子固定住芯片,将热风的温度调整到350度左右,对准芯片加热约10秒。小心镊子也可能会变烫,最好使用带有胶皮的镊子。热风需要用最大风嘴最小风量对准芯片吹。焊锡膏融化时,要确认芯片引脚与焊盘对准。注意此时PCB非常烫,不要立即用手接触PCB板。
检查的时候可以用万用表确定有没有短路,根据原理图可以看到,1、6引脚联通,2、4、5引脚联通,其它脚联通的话就说明短路了。如果有虚焊,可以用烙铁尖沾一点焊锡压一下焊盘,焊锡就会自动补到引脚和焊盘之间;如果短路就只能用风把ADXL345取下来重新焊接。
图3-4 STM32F103C8T6原理图
14
图3-5 ADXL345原理图
图3-6 STM32F103C8T6的3D效果图
图3-7 加速度芯片贴盘效果图
3.4 全彩灯珠的设计
全彩灯珠可简称为RGBLED,本设计采用的是5050封装。本质上来说RGBLED就是三个LED灯。根据色光三原色原理,红,绿,蓝三种色的色光就足以产生其它各种颜色的光。灯珠本身白色的,配合变换的灯光,非常漂亮。
15
LED灯的焊接十分简单,却容易犯错,需要注意焊接温度,不能超过315度,且尽可能在3秒钟之内完成焊接。因为RGBLED非常容易烧坏。LED的正负极需要事先用万用表确认。注意3个限流电阻的阻值是不一样的,蓝色LED阻值较小。
图3-8 全彩灯珠原理图
图3-9 全彩灯珠贴盘效果图
3.5转向按键与红外线激光灯的设计
本设计的预期要实现转向灯功能,至少有两种方案:
其1是通过读取ADXL345的值。转弯的时候在转弯的方向会有一个小的加速度,单纯检测这个加速度难度较大。不过正常骑行的时候,转弯一般是需要减速的,这两个条件放在一起来检测的话可以减小难度。这个方案的弊端是,只能在转向的操作发生之后,才显示转弯,无法在转向之前就给出指示和预警,所以舍弃此方案。
其2是主动触发的方案。主动触发至少包括两个方法。1是利用车架与车把的倾角变化。直线骑行的时候车架与车把夹角是垂直的,但是转向的时候夹角就
16
会发生变化。如果在车架与车把之间放置金属片,使之向前骑行的时候不接触,转动车把,也就是转向的时候接触,就可以检测到转向。这个方法的缺点也是在转向操作之后才可以做出指示,故舍弃。2是有骑行者主动按下按键触发,就是本设计采用的方案。
转向按键是控制红外线激光灯的开关,也是模式切换的开关。红外线激光灯是指示左右转向的信号灯。激光灯发射出来的光投影到地面是一字线状,而不是点状。在光线较暗的情况下可以清楚地看到地上是平行于自行车的红色线条,这样就可以警示其它车辆注意自行车的转向。
两者的逻辑关系非常简单,按左转按键,则左边的红外线激光的闪烁,左侧地面形成线状投影。右侧亦然。但真正实现的时候还需要考虑一些别的因素。
首先是按键的选型。在实际使用中肯定是不能用轻触开关的,太小了。我选择了一款较大的按键开关,有弹簧结构,自动复位。也有螺丝与金属片,可以方便地固定线。
图3-10 转向按键电路原理图
红外线激光头选用了一款3V,5mW的工业级激光灯头。由于工作电流可能达到20mA,所以直接用单片机的引脚驱动可能是有一定的危险的,因此电路设计中采用了NPN型三极管驱动。三极管工作在开关状态,这样子单片机的引脚只需要很小的驱动电流就可以控制红外线激光头的亮灭。
17
图3-11 红外线激光头电路原理图
关于红外线激光头的选型也是很麻烦的一件事。在多数人的印象中红外线激光头非常亮,但是那只是点状光源,换成线状的就会发现亮度比较低。采用较大功率的红外线激光头的话会浪费较多的电量,同时低电压大功率的激光头非常容易损坏。即便是本设计选用了一款工业级的激光头,也还是在调试过程中就坏掉了好几个。如果升压,采用5V或者更高的电压,会使整个设计复杂得多。不但需要更大的体积,来至少串联3个电池,还需要稳压管来给芯片提供合适的电压。多次比较,本设计最终选取了这款3V,5mW的工业级激光灯头。 3.6其它硬件设计 SWD调试接口
调试接口采用了SWD接口。用标准的JTAG调试口需要5个,而用SWD调试接口只用4根线,2个IO口,但它们达到的效果是一样的,加上SWD调试也可以使用J-LINK仿真器,所以选择SWD调试。
图3-12 SWD调试接口原理图
18
串口和BOOT接口
串口调试是调试过程中非常有力的工具,它可以直接将需要的数据通过串口调试助手打印到电脑屏幕上,直观的看到某个变量的值或者IO口的电平状况,是单片机开发的必备接口。所以本设计也保留了STM32的串口。
BOOT可以确定STM32的启动模式,本设计出于调试加速度芯片设定值的需要,保留了BOOT0接口,这样子就可以将加速度值写入系统存储器,再从系统存储器驱动程序,在上位机上就可以看到加速度值,极大提升了调试效率。
表3-1 启动模式说明表
启动模式选择引脚 启动模式 BOOT1 X 0 1
BOOT0 0 1 1 主闪存存储器 系统存储器 内置SRAM 说明 主闪存存储器被选为启动区域 系统存储器被选为启动区域 内置SRAM被选为启动区域
图3-13 串口和BOOT接口原理
晶振
由于本设计中没有对时钟要求较高的部分,STM32F103C8T6自带的8MHz内部RC振荡器就足够使用了,所以就没有采用外部晶振。
19
图3-14 HSI与系统时钟(SYSCLK)的关系
20
4 软件设计
4.1 STM32固件库开发概述
意法半导体公司开发了一套STM32固件库。所谓的固件库,其实就是函数的组合,而这些函数操作的对象,就是单片机的各个寄存器。把完成某一功能,比如初始化IO口或者初始化定时器的寄存器集成在一个或者几个函数中,这样子开发人员在写代码的时候就不必直接操作寄存器。
STM32当然也可以像51系列单片机一样直接操作寄存器,但是这种开发方式需要开发人员熟练掌握这些寄存器的用法。STM32这种级别的CPU至少集成了几百个寄存器,全部熟悉这些寄存器对开发者来说时间花费太大,不能快速上手。由于单片机的代码主要有C语言编写(仍有一些对效率要求较高的地方用汇编语言),C语言是一种面向过程的语言,函数是面向过程的语言中最重要的组成部分,所以直接将寄存器操作封装在函数中是可行的,方便的。STM32的固件库开发方式是高效的。
由于官方固件库的强大,在软件设计中与其说是写代码,不如说是组建代码。本次软件设计基本流程就是考虑函数的预期功能,了解固件库函数的使用方法,调用函数实现功能。 4.2 程序代码结构
本设计的代码遵行着可读性高,易调试,易维护的原则,经过了多次修改,最终实现了以下的几点要求:
1. 按照硬件区分,不同的程序模块放在不同的.c文件中。 2. 同一个硬件按照不同的功能区分,封装在不同的函数中。 3. 不同的函数根据自己的作用域和工作特点,使用特定的关键字。 4. 函数的命名根据其功能来确定,多是其功能的英文简写。
5. 使用到的管脚、中断和中断处理函数按其功能进行全英文大写宏定义。 6. 谨慎地使用了全局变量和局部静态变量。 以上这几点也是单片机模块化编程需要注意的地方。
21
表4-1 程序中.c文件功能说明表
程序中的文件名 acc_sensor.c break_light.c button.c color_light.c display_state.c led.c power.c xl345.c 功能 加速度传感器的读、写、中断函数初始化以及中断处理函数 刹车灯模式定时器初始化和处理函数 按键定义,中断初始化和处理函数 呼吸灯模式(也可称为彩灯模式)中断初始化和处理函数 模式选择的初始化和处理函数 全彩灯珠和红外线激光灯的定义、初始化和中断处理 定义未使用的引脚,初始化用电模式转换函数 加速度芯片初始化和SPI接口处理函数 以上.c文件的功能虽然不相同,但基本结构都是一样的,以button.c为例说明,别的就不再赘述。
表4-2 button.c的代码结构说明
结构 头文件 功能 举例 宏定义 中断初始化 中断处理函数或者功能处理函数 将系统寄存器定义和其它#include \"stm32f10x.h\" 文件函数定义添加到文件 #include \"utils.h\" #include \"button.h\" 将引脚、中断处理等系统#define BTN_RIGHT_PIN 底层的功能起别名,方便GPIO_Pin_1 阅读 #define BTN_RIGHT_IRQ EXTI1_IRQn 设定中断的名字、优先级、static void _initButton(void) 触发方式,管脚映射等 static void _initAntiShakeTimer(void) 根据预期功能执行相应的void BTN_LEFT_IRQROUTINE(void) 处理任务 void BTN_ANTISHAKE_IRQROUTINE(void) 4.3 main.c结构说明
与常见的裸机程序不同,本设计的主函数非常简洁。这是因为模块化设计,将不同的功能封装到不同的函数中,所以主函数得以一目了然。
22
Main.c中代码如下:
#include \"stm32f10x.h\" #include \"utils.h\"
#include \"acc_sensor.h\" #include \"display_state.h\" #include \"button.h\" #include \"led.h\" #include \"xl345.h\" #include \"power.h\"
int main() {
PWR_SetUnusedPin(); //设置未使用的引脚
HW_CommonInit(); //硬件配置,设置中断优先级和上拉输入 LED_Init(); //初始化LED引脚和升压电路引脚 HW_InitSysTick(); //配置0.5MS系统时钟的中断和优先级 ACC_Init(); ////三轴加速度芯片的初始化 STATE_Init(); //开启刹车灯模式(默认模式),从ADXL读数据,开启定时器 BTN_Init(); //按键和定时器的初始化
while(1){
PWR_EnterSLEEPMode(); //开始休眠,等待中断 } }
可以看到其结构仅仅包括头文件和主函数两部分。而主函数内部仅仅做得是初始化,然后在死循环中进入睡眠,等待中断。这里的while(1)内并不是不断轮询,而是进入睡眠模式,降低功耗。
在睡眠模式中 Cortex-M3内核停止,所有外设包括Cortex-M3核心的外设,如NVIC、系统时钟等仍在运行,也就是说仍然可以通过ADXL345芯片的中断或者按键中断来唤醒MCU。 4.4 按键功能软件设计
模式切换在一般情况下是需要一个按键的,但是左右转向已经各分配一个按键了,3个按键全部放在车把上的话既不美观,也不方便,出于简化设备的需要,设定为长按(2秒以上)左按键或者右按键则改变模式。
23
按键功能的逻辑很简单:检测到外部中断线1和2电平为高就消抖,电平仍然变为高就是按键按下了,然后闪烁红外线激光灯,同时进行长按检测。确是长按的话就切换模式。
关于消抖和确定按键时长的延时功能也是本设计考虑的地方。延时可以通过delay函数,也就是让单片机不断地做加法来消耗时间这种方法,或者设置定时器,采用定时器中断的方法。反复对比效果,最终决定由定时器来消抖,用延时函数来确定按键时长。原因如下:
在正常骑行中,由于颠簸等因素,按键的外部中断引脚很可能经常产生瞬间的干扰电流。也就是说,在没有按下按键的情况下,也可能在外部中断线上读到上升电流。严格来说,这里所指的消抖功能并不是消除按键按下的过程中瞬间的电平不稳定,而是消除没有按下按键,由别的因素产生的干扰电平。如果此时唤醒单片机,执行延时函数,则很多的唤醒是不必要的,省电效果不如用定时器,即便CPU继续休眠,也可以实现延时功能。
确定按下按键后,判断长按还是短按则由延时函数来判断。看似是让单片机做无意义的数数,实则是因为一方面单片机已经唤醒,执行延时函数不会额外浪费电量;另一方面为了防止按键的定时器中断被按键外部中断打断,定时器中断的优先级是比较高的,此时仍然使用定时器中断可能丢失其它中断。
这里需要说明的是按键的定时器中断和外部中断的关系。两者优先级均为1,但定时器中断不会被外部中断打断。定时器中断的开启是在外部中断的执行函数中进行的。外部中断线的第二次电平判断发生在定时器中断的处理函数中。定时器设定的时长就是外部中断线(也就是按键的检测引脚)两次有效高电平之间的延时函数。
24
低电平
等待外部中断1或者2触发 设定定时器2开启 30毫秒过后 进入定时器2处理函数,关闭定时器,检测案件引脚电平 读取PB1和 高电平 PB2的电平 干扰,不处理 PB2为高电平 判断按键 PB1为高电平
进入左按键处理函数 进入右按键处理函数 图 4-1 按键触发流程图
25
左/右按键处理函数 红外线激光灯头闪烁2次,用时约2秒 没有按下,是短按 再次检测左/右按键 仍然按下,长按 闪烁8次结束按键
处理
图 4-2 按键处理流程图
切换模式 4.5 ADXL345的软件设计
ADXL345与单片机之间通过SPI协议连接,本文2.2已经介绍过了。 刹车状态的判断方法是:计算X,Y,Z轴加速度的平均值,每次比较当前加速度和平均加速度的差值,从而判断是否有状态变化。这样可以减小安装倾斜造成的测量误差。不过安装的时候仍然要尽量使加速度芯片与地面垂直,否则会增加错误率。比较加速度的时候除了水平方向,竖直方向的加速度也考虑在内,因为预期功能中有检测到连续震动时唤醒的功能。
参数的调整时使用了STM32的BOOT启动功能,将测量到的加速度值记录在单片机的flash中,下次启动时输出。这样可以收集到骑行状态中的加速度值,下次调整参数时依据记录的数值来调,提高了效率。现在加速度传感器的参数基本上是一个可用的状态,灵敏度还算比较高,误亮的几率很小(加速较快时误亮)。
ADXL芯片与单片机之间通信的逻辑很简单,见下边的流程图。
26
加速度芯片检测到连续震动 唤醒单片机 单片机推出睡眠模式,进入刹车灯模式没接受加速度值 刹车 判断加速度 没有刹车 亮黄灯,计时30秒 刹车 判断刹车状态变化 没有刹车 没超过 亮红灯,刹车 超过30秒 关闭LED,休眠
判断是否超过30秒图4-3 加速度芯片与单片机通信流程图
4.6 模式切换的软件设计
本设计中单片机主要工作在正常模式和睡眠模式。正常工作模式包括了刹车灯模式和呼吸灯模式。它们的区别和联系见下图
27
图4-3 正常模式与睡眠模式关系示意图
刹车灯模式和呼吸灯模式的转换是由一个模式标志位g_DisState决定的。g_DisState的值取自一个枚举类型。
enum DISPLAY_STATE { STATE_BREAK_LIGHT, //刹车灯 STATE_COLORLIGHT, //呼吸灯 STATE_MAX, //此模式重新回到刹车灯 };
这个枚举类型决定了刹车灯是初始状态。状态的转换是靠函数
STATE_NextState()来执行的。转换时只需要g_DisState++,就可以改变标志位。逻辑上是非常简单的。
void STATE_NextState(void) {
g_DisState++; if (STATE_MAX == g_DisState){ //再按一下回到默认状态 g_DisState = STATE_BREAK_LIGHT;
28
} STATE_SetState((enum DISPLAY_STATE)g_DisState); return; }
不同模式的处理函数都是通过一个指针函数切换的。 typedef void (*ACC_IRQHandler)(u8 irq);
定义了一个函数指针,相当于把类型 void (*)(u8 irq),取了一个别名叫做 ACC_IRQHandler。然后通过语句ACC_IRQHandler handler,g_handler = handler;就传递了处理函数。handler在blk_start,color_start,这两个模式开始函数中被赋值。
表4-3 刹车灯模式和呼吸灯模式的对比表
模式 刹车灯模式 全彩灯珠 红色高亮表示刹车,紫色(青色)表示正常行驶 色彩渐变,两灯交替闪烁 红外线激光灯 加速度传感器 退出 无操作不亮 工作,不停向长按转向按键按下按键对应单片机提供加进入呼吸灯模方向的闪烁 速度值以供判式 断刹车与否 静止30秒睡眠 常亮,在地面不工作 长按转向按键上投影出两条进入刹车灯模光线 式 按下按键对应静止不会进入方向仍闪烁 睡眠状态 呼吸灯模式 29
5 总结
5.1 在调试过程中出现的问题和解决办法
1. 网络标号写错导致的PCB错误。由于原理图中,ADXL345与STM32的唤醒线网络标号不一致,一个是WKUP,一个是WAKEUP,导致PCB中这两个本该连接的引脚没能连接。
解决办法:跳线。由于单片机引脚很小,加速度芯片特殊的封装更是看不到引脚,所以这个跳线的难度设置比焊接还大。并且即便跳线的一段粘到来对应引脚上,由于受力面积太小,轻轻一拽就掉了(我因为这个原因直接拽掉了加速度芯片的焊盘,报废了一个板子),所以跳线成功后就直接用热胶把线固定在了板子上。
2. 全彩灯珠封装画错,正负极画反了。
解决办法:还好是二极管,接反了也不会有太大损害。在原理图中看不出来画错了,是因为错在这个元器件的原理图和封装是自己画的,没能看出来引脚反了。第一个灯的解决方案是跳线6根。用笨的方法修正,但是板子也变得很难看。第二个灯的解决方案是把全彩灯珠进行中心对称,由下列左图的方位改成了右边的样子,不过原先的灯的顺序中第1个和第3个就互换了,由BRG变为GRB。相应的蓝色和绿色灯珠的限流电阻也需要换一下。
3. 接插件封装没有注意,直接使用了标准库中Header 4*1的封装,所以SWD的封装仅仅是2.间距的单排插针。
解决办法:手头有一个正点原子的战舰开发板,里边有一个J-LINK,翻了一下数据手册,发现JTAG接口可以用4根线完成SWD调试,就按照引脚说明接了4跟杜邦线在板子的4根单排插针上。 1号引脚VCC <==> VCC 7号引脚TMS <==> SWDIO 9号引脚TCK <==> SWDCLK 4号引脚GND <==> GND
30
图5-1 JTAG用作SWD调试示意图
5.2 在软件设计中总结的技巧
1. 先测试硬件,再进行模块化编程。
由于硬件电路是自己设计并且手工焊接的,很可能不可靠,所以在写代码之前先写一些非常简单的小程序测试一下某块硬件是否可用。如led与红外线激光灯的测试,仅仅需要一个GPIO_SetBits函数就可以看到亮不亮。随后进行模块化编程,各个模块分开来写,将这个模块的功能调试完毕再进行下一个模块。调试好的模块函数直接用关键字static隐藏在本文件中。
2. 了解嵌入式C语言的特点,结合实际使用嵌入式C语言编程技巧 由于在学校时老师讲述的C语言课程与嵌入式并没有什么联系,其深度与效果差不多只能让学生记住黑窗口与printf,这样的C基础在组建本设计的代码的时候还是很有压力的,因为嵌入式C与C的知识重点是不太一样的。
如static inline void _displayDeceleration(void)关键字,inline,表明这是一个内联函数,类似于宏定义,用预处理器实现,不用顾忌函数的参数压栈,代码生成等一系列操作,所以效率很高。
再如typedef,extern,struct等,这些关键字在C语言学习的时候不算事重点,但却是嵌入式开发中必须注意的,掌握这些技巧可以使嵌入式软件开发更有效率。 5.3 个人成长
借由这次毕业设计的机会,在软件设计方面,我重新全面地学习了STM32单片机的的使用。以前仅仅是看过教学视频,把单片机的例程下载到开发板中看一下,实则过后即忘,没有多大的收获。这次是实实在在自己开发一个电子设备,从硬件到软件有许许多多细节需要考虑,这是以前学习所没有想过的。遇到的一些问题,也无法像从前一样,直接问别人或者去开发板的技术论坛发问,
31
而是自己参考数据手册来解决问题。我发现善于使用数据手册可以解决大多数的嵌入式软件问题。
在硬件设计的方面我也收获很多。重新学习了AD13的使用,绘制原理图和PCB。这些倒还是书本中可以学到的知识,器件采购的知识真是无从学起,很多细节需要考虑。虽然淘宝上有很多根据BOM表配单的电子器件商人,但是具体的细节人家问起,我还是不清楚。比如红外线激光灯,我告诉人家我需要3V,电流20mA以下,尺寸较小,却没注意我想要的是线状的,最终人家给我发来点状的。诸如此类的问题是需要注意的。
发现了很多问题是让人开心的事,解决这些问题可以让自己成长。这次毕业设计实施的过程中,常常感觉在技术方面心有余而力不足,知识体系上有较多欠缺。但令人遗憾的是,大学马上就要结束,没有足够的时间来弥补自己的不足了。只有争取以后的时间里加倍努力了。
32
参考文献
[1]邱关源,罗先觉.电路[M] .北京:高等教育出版社[M],2006:168-170
[2]余孟尝.数字电子技术基础简明教程[M] .北京:高等教育出版社,2006:259-263 [3]杨素行.模拟电子技术基础简明教程[M] .北京:高等教育出版社,2006:139-158
[4] 黄智伟,王兵.朱卫华. STM32 32位ARM微控制器应用设计与实践[M].北京:北京航
空航天大学出版社,2012.
[5] 刘军.例说STM32[M] .北京:北京航空航天大学出版社[M],2011:69-75 [6] Stephen Prata .C Primer Plus.北京:人民邮电出版社[M] ,2008:125-1 [7] 正点原子.STM32开发指南V1.3.数据手册 [8] Joseph Yiu.C0rtex-M3权威指南V1.2.数据手册 [9] STM3F10xxxV1.2.参考手册
33
致 谢
我的毕业设计可以完成,首先要感谢我们的学院——物理与电子工程学院。大学四年,我在物理院学到了很多知识,也感谢物理院从大一就开始给予学生各种创新实践的机会。这些创新实践对我个人来说影响非凡。
借此机会,我也要感谢XXX老师。从大一开始,XXX老师就指导我开始学习嵌入式的知识,让我可以在物理院的嵌入式实验室内学习。袁老师对技术的执着和对嵌入式行业的理解一直鼓舞着我,不断钻研技术,提高动手。在我的毕业设计的过程中,袁老师也给予了我很大的支持。也要感谢XXX老师,是他鼓励我走出去,见识更广阔的世界,我才得以接触到真正的嵌入式工作环境,快速成长。在此谨向XXX老师、XXX老师以及其它电气专业的老师致以诚挚的谢意和崇高的敬意。
在毕业设计的实施过程中,我总能感觉到科技对人们生活的改变是多么巨大。虽然我的毕业设计只是个小发明性质的电子作品,但还是对我个人产生了很大的影响。最显著的就是让我变得热爱骑行,特别是夜间骑行,知道我的毕业设计会在我刹车的时候自动亮起,在呼吸灯的模式下渐变光芒,是非常开心的一件事。当然我也看到了自身能力和知识储备的不足,在未来的工作中我一定会不断提高自己的动手能力。
从开始进入课题到论文的顺利完成,需要感谢很多可敬的师长、同学、朋友,他们给了我无言的帮助。还有我的室友以及11级电气班的每一位同学们,谢谢你们给我了愉快的大学时光。
最后,再次对关心、帮助我的老师和同学表示衷心地感谢!
XXX
2015年5月于XXX大学
34
因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- igat.cn 版权所有 赣ICP备2024042791号-1
违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务