1微机课程设计说明书终版.docx
《1微机课程设计说明书终版.docx》由会员分享,可在线阅读,更多相关《1微机课程设计说明书终版.docx(66页珍藏版)》请在冰豆网上搜索。
1微机课程设计说明书终版
一、设计任务与目标
1.1设计课题
设计课题:
智能流星灯管的控制程序设计
1.2设计目的
通过小型微机应用产品的设计与调试过程,运用《微机原理及接口技术》课程所学的基本知识,在设计中加以应用,进而得到理解、巩固和提高,学习掌握分析与解决实际问题的方法与手段,提高设计、编程与调试的实际动手能力,作为工程技术工作的一次基本训练。
1.3设计任务
LED流星灯管是一种室外景观装饰灯,适用于悬挂在树枝上、屋檐下,其闪烁的效果就像夜空中一道道流星一样在空中划过。
这种新型的工程亮化产品,犹如流星般变化,光亮自然顺滑,可根据环境任意串接,可根据要求设定控制效果。
广泛应用于酒吧、迪吧厅、宾馆大厅、园林广场、步行街、庭院、歌舞厅、公园、道路、楼梯、花园、用于建筑、商场、发廊等装饰。
近来也用于演播厅装饰,数百个流星灯同步协调的变幻效果紧密配合现场音乐及节目环节,美轮美奂。
本设计以单片机为核心,实现LED流星灯常规控制功能,可通过键盘选择不同流速的流星灯,有良好的操作界面和显示界面。
对产品的单片机控制程序进行初步的设计,编写程序并在单片机实验板上模拟调试实现。
1.4设计功能
1、开机进行适当的有关接口部件及数码显示器、指示灯、讯响器等自检。
2、八位LED七段数码管作为时钟显示及其他界面信息显示。
3、4×4键盘设置“0”~“9”数字键以及产品设计所定义的功能键,按下键盘时应回馈短促的按键音以提供良好的操作手感。
4、装置基本显示模式为按照24小时制动态显示时、分、秒实时钟信息。
5、可操作“调校时钟”键进入调时界面,通过键盘定义的两对“+”、“-”复合功能键采用翻滚数字方式修改实时钟的时、分参数,按下“+”、“-”键翻滚一个值,保持按着0.5秒后以每秒5个值的速率翻滚,按“确定”键保存新的时刻且秒清零,按“取消”键不保存退出。
6、本装置驱动的16只LED构成流星灯串,采取PWM方式调节每只LED的亮度,PWM控制分辨率不小于1/20,PWM控制频率不低于100Hz。
7、LED流星灯的基本控制功能为模仿夜空中流星的视觉效果按一定的速度重复在16只LED组成的流星灯管流动。
8、可通过外接的按钮开关“+”、“-”随时调节流星灯的流动速度。
9、可通过键盘:
“换档”功能键及随后的数字键操作直接切换为指定的流动速度档。
10、非基本显示模式下无操作时间超过30秒钟后自动恢复为基本的显示时钟状态。
11、可由用户选择切换为12小时制显示实时钟,通过“A”、“P”指示上下午。
12、可选控逆向流动方式。
13、有多种流星光效,可通过键盘操作选择。
14、可程控,预先存入顺序控制流程表,自动控制流星灯依序演绎,顺控表每工步包含光效、方向、速度、时长等要素。
二、总体设计规划与方案论证
2.1设计规划
根据任务书的要求,要实现的基本功能有具有可键盘校时的实时时钟和可选择多种流速的流星灯,计划的进程安排如下:
课程设计进度安排表
时间
任务
2013.12.09
实现实时时钟及加减1校时的功能
2013.12.10
实现快调的校时功能及相应的显示界面
2013.12.11
实现整点报时及理解流星灯的编程原理
2013.12.12
实现流星灯的功能
2013.12.13
实现流星灯选档调速功能
2013.12.13~2013.12.14
完成外接按键调速及相应显示界面的编程
2013.12.15
对周末编写的程序进行调试与修改
2013.12.16
对基本能程序段的优化设计
2013.6.17~2013.6.20
进行扩展功能的编程及答辩
2.2设计方案论证
2.2.1流星灯中断选择
方案一:
独立中断,流星灯的程序独立于实时时钟的程序。
该方案的有点是可以灵活的调整PWM的周期,可使流星灯工作在最佳的频率中使流星灯的效果更佳。
但同时也存在一些不足,即PWM的周期不是很稳定,受到实时时钟中断的影响,导致PWM周期有时将会被拉长,使得显示的效果下降,其次主流程的执行时间也会被拉长,导致各个延时的时间不是预定的时间,同理实时时钟的程序也会受到流星灯中断的影响,导致走时不准确。
方案二:
流星灯的中断服务子程序与实时时钟中断服务子程序放在同一个中断中。
该方案的优点是PWM的周期不受到影响,同时实时时钟的走时精确,缺点是PWM的周期受到实时时钟的限制,不能灵活调整。
方案选择:
方案二中PWM的周期虽不能灵活调整,但是工作在该频率的流星灯显示的效果良好,再者实时时钟能够精确走时,且PWM周期稳定,相比之下,选择方案二。
2.2.2按键扫描方法
方案一:
扫描法。
采用扫描法可以解决端口的限制问题,但是其编程比较复杂,要逐个扫描按键,因此程序执行的时间比较长且繁琐。
方案二:
线反转法。
线反转法具有简练的特点,无论被按键是处于第一列或者最后一列,均只需经过两步便能获得被按键的行列值,但是采用反转法有个限制,就是行线设置为输出,列线要设置为输入,列线设置为输出时,行线要设置为输入,因此同个端口不能高低位分开设置输入输出状态的话,就得使用两个端口。
方案选择:
因为8255的C口的高低四位的输入输出状态可以分开设置,因此消除了反转法中端口的限制,且反转法的编程简单,因此采用线反转法来扫描按键是否按下。
2.2.3数码管的显示方式
方案一:
静态显示方式。
将各位共阴极(或共阳极)连接在一起并接地(或者接+5V),每位的段码有8位的端口来驱动,这中显示方法就是静态显示。
采用静态显示方式接口编程比较容易,而且数码管的亮度都比较高,但是占用的端口比较多,单片机的端口显然不够。
方案二:
动态显示方式。
将多个数码管的段码线的相应段并联在一起由一个8为的I/O口控制,而其共阴极或者共阳极分别由相应的I/O口控制,这种方式就是动态显示方式。
动态显示方式占用的I/O口比较少,但是编程比较繁琐,且亮度稍暗,占用单片机时间多,但是这种方案节省了很多端口,也是电路变得简单,因此选择方案二。
3、
总体软件设计说明及总流程图
3.1软件设计说明
根据任务书的要求,可知此次设计需要实现的基本功能有实时时钟、键盘校时、流星灯,流星灯调速等,以及良好的操作界面、良好的操作手感和显示界面。
因此整个程序必须包括实时时钟子模块,流星灯子模块,驱动数码管显示的显示更新子模块,判断键盘是否有输入及消抖动的键盘扫描子模块,判断外接按键是否有输入及消抖动的PB消抖子模块,将压缩的BCD码进行解压的拆字子模块,使用户具有良好的操作手感的按键音效子模块,设定按键对应功能的按键功能设定子模块,具有键盘选流速、外接按键调速的流星灯流速调整子模块和具有快调与慢调的键盘校时子模块。
有了这些基本的子模块再进行添加扩展模块,如小时制切换子模块,整点报时子模块,逆向流星灯子模块等等。
通过各个模块之间的相互配合,使得上述的功能能够实现。
因为硬件的限制,我们要设定不同的进程来实现相应的功能,因次需要用到进程码。
所谓的进程码是指在通过对进程单元存入不同的数据,在以后的编程中,则只需判断进程单元中的数据,就可根据不同的数据做不同的处理,即引领程序的进程,实现各个模块的配合。
在此次的程序设计中,我用了20H单元来存储进程码。
在常规进程中20H单元存储的数据是00H,当按下调时键时,将20H单元的数据改为10H,进入调时进程中,在常规进程中,如果按下的是调速键,则将20H单元的数据改为20H,进入调速进程。
当在非常规进程,就使能确定键、取消键,用于进程的切换。
常规进程下主要是实时时钟的显示,程序主要执行的是拆字程序中的常规拆字程序段,以及整点报时、显示更新和按键功能设置模块。
在进入调时进程时,将小时单元和分钟单元的数据存入暂存单元,在调整时,主要改变暂存单元里的数据,当调整完后,按下确定键就将进程改为常规进程,同时将暂存单元的数据存入原来的时、分单元。
主要执行的是拆字程序中的校时拆字程序段、键盘扫描子程序,键盘校时子程序、按键功能设置子程序、显示更新子程序。
当进入调速进程中,主要修改的是流速即改变步进值,通过不同的键号,选择不同的步进值,并加以显示,以提供良好的显示界面和操作界面。
综上所述,此次程序的设计是由进程码来引领程序的进程,在各个进程中做相应的功能处理子程序,在进程中同时又建立不同的标志位来引领不同的程序段实现不同的功能的切换。
3.2总流程图
中断:
四、系统资源分配及数据定义说明
4.1系统资源分配
4.1.1AT89S52资源分配
端口
资源配置
P0
数据总线和地址总线(A0~A7)
P1
LED灯(L0~L7)
P2
P2.0(8255(U3)片选端),P2.1(8255(U5)片选端)
P3
P3.2蜂鸣器
其他
电源,晶振,读写
4.1.28255(U3)资源分配
端口
资源配置
PA
数码管段码,“0”有效
PB
数码管位码,“1”有效
PC
矩形键盘
PD
数据传送
其他
电源端口,片选端口,控制端口,读写
4.1.28255(U5)资源分配
端口
资源配置
PA
LED灯(L8~L15)
PB
PB独立按键
PC
SW电平开关
PD
数据传送
其他
电源端口,片选端口,控制端口,读写
4.2数据定义说明
4.2.1数据定义说明
见附录一
4.2.2数据初值说明
MOVSP,#6FH;设定栈底指针,使堆栈数据从70H单元开存储,默认是07H,有可能数据会产生冲突,因此将指针指向6FH。
MOV38H,#36;38H单元为实时钟256uS计数单元,256*36=9216,刚好是10mS
MOV39H,#00H;39H单元为10mS计数单元,计满100为1S,一开始清零
MOV3EH,#00H;调时进程下,分钟暂存单元,开始时清零
MOV3FH,#00H;调时进程下,时钟暂存单元,开始时清零
MOVTMOD,#22H;选择中断的控制方式,初始化T1为定时方式2。
MOVTL1,#00H;置T1计数初值。
使定时器计满256次溢出,产生中断信号
MOVTH1,#00H
MOV20H,#00H;主进程单元,默认初始进程为常规进程(00H)
MOV21H,#0FFH;铃声逻辑缓冲单元初值全"1",使蜂鸣器不响,21H.7整点报时,21H.5按键音效
MOV22H,#00H;整点报时进程码存储单元,常规状态(00H),判断是否为整点
MOV23H,#00H;23H.0,小时制标志位,23H.1整点标志位,23H.2上下午标志位,23H.3上下午标志位暂存位
MOV24H,#00H;24H.0,时加长按标志位,24H.1时减长按标志位,24H.2分加长按标志位,24H.3分减长按标志位
MOV25H,#0FFH;P1输出缓冲单元,使LED灯全灭
MOV26H,#0FFH;8255(U5)A口输出缓冲单元,使LED灯全灭
MOV27H,#0FFH;光效存储单元
MOV28H,#0FFH;光效存储单元
MOV40H,#30;A/D数据0.3秒更新一次
MOV41H,#30;整点报时第一声0.3秒
MOV42H,#50;长按判定单元,超0.5S为长按
MOV43H,#20;实现快加功能,以0.2S加1的速率加
MOV44H,#03;音效设置单元,存储蜂鸣器响的时间
MOV45H,#100;无操作延时单元,与46H共同构成30S的延时
MOV46H,#10;无操作延时单元,与45H共同构成30S的延时
MOV48H,#00H;流星灯时间片i,每中断一次加1
MOV49H,#00H;PWM周期计数单元j,每一周期加1
MOV4AH,#07H;流速值J,决定流星灯的流动速率
MOV4BH,#00H;步值存储单元k,根据不同的步,进行不同的对位送操作
MOV52H,#07H;流星灯档位存储单元,默认是7档
MOV64H,#10H;新键码存储单元;无按键按下时键号为10H
MOV65H,#10H;前键码存储单元;无按键按下时键号为10H
5、局部程序设计说明
5.1总初始化
总初始化程序主要是在程序开始进入主流程时,对程序中有用到的数据单元赋予初值、开启需要的中断、设置中断服务子程序的入口、实现设备自检等,该程序段只有在程序开始时执行一遍,此后不再执行该该程序段。
此次设计的总初始化程序先设置了定时中断1的程序入口,驱动数码管从右往左逐个全亮显示、点亮所有的LED和使蜂鸣器响1秒以实现设备的自检,最后将接下来程序中有用到的数据单元赋予相应的初值。
5.2,主流程
5.2.1拆字子程序
在程序中,所有送数码管显示的单元存储的数据都是压缩的BCD码,在送到数码管显示缓冲单元时需要对压缩的BCD码进行解压,因此在显示更新之前就得将送显单元进行拆字。
所谓的拆字是将送显单元里的数据的高四位和低四位进行分离,并存入不同的地址单元或者存入相应的显示缓冲单元的低四位。
常用的拆字方法是将先把送显单元的数据与立即数(#0FH)相与,屏蔽高四位,将屏蔽后得到的数据存入相应的显示缓冲单元,接着是将送显单元的数据与立即数(#0F0H)相与,屏蔽低四位,所得的数据高四位与低四位相对换,再存到相应的显示缓冲单元。
此次设计的拆字子模块又分为24小时制拆字、12小时制拆字、校时拆字、流星灯调速拆字。
程序先判断当前进程是否为常规(00H)进程,是常规进程,继续判断小时格式转换标志位23H.0,为0,执行24小时制拆字程序段,为1,则执行12小时制拆字程序段;如果不是常规进程,则跳转判断是不是校时(10H)进程,如果是该进程则执行校时拆字程序段,其中还要判断是不是小时格式转换标志位23H.0,为0不显示上下午标志A、P,为1,则显示;若当前进程不是校时进程,则跳转判断是不是调速(20H)进程,是就进行调速拆字程序段,不是则返回主流程。
在常规进程下,24小时制拆字是将小时单元3CH、分钟单元3BH和秒钟单元3AH进行拆字,其中3CH低位送到36H,高位送到37H,3BH低位送到33H,高位送到34H,3AH低位送到30H,高位送到31H,32H和35H单元显示横杆,以隔离小时、分钟、秒钟,达到良好的显示效果;12小时制拆字同样是将小时单元3DH、分钟单元3BH和秒钟单元3AH进行拆字,但是送到的缓冲单元不一样,其中3CH低位送到36H,高位送到37H,3BH低位送到34H,高位送到35H,3AH低位送到32H,高位送到33H;30H单元用来显示上下午的标志A、P,31H单元显示空格。
在校时模式下,校时拆字是将小时暂存单元3FH、4FH、分钟暂存单元3EH进行拆字,若是24小时制,则将3FH单元进行拆字低位送到36H,高位送到37H单元,若是12小时制,则将4FH单元进行拆字低位送到36H,高位送到37H单元,在根据上下午标志位暂存单元23H.3,判断显示A还是P。
两种模式都将3EH低位送到33H,高位送到34H单元,35H送横杆的代码,其余单元赋予空额的代码。
在调速模式下,将挡位单元52H进行拆字,将52H单元的低位送到33H,改为送到34H,其余的单元赋予横杆的代码。
5.2.2开关量消抖动子程序
正常的时候我们按下或者释放按键时只希望电平变化一次,但是机械按键在按下或者释放的瞬间都会出现抖动,会出现高低电平的不断变换的情况,单片机在扫描端口电平时,会认为按键是按下了几次,会是程序的逻辑不能按我们原先设定的逻辑进行。
因此我们要将开关量的输入进行消抖动,通常采用的消抖动的方法有硬件消抖和软件消抖。
硬件消抖是利用电子元器件构成RS触发器进行消抖动,软件消抖常用的是滚动滤波法。
滚动滤波法是将采集到的开关量存于一个数据单元中,下次采集时将前一次采集的数据存于新的数据单元,此次扫描的存于原先的数据单元,这样滚存n个单元,然后比较这n个滚存单元的数据是否一致,一致的话将该数据存于另一单元,我们称之为开关量新态存储单元,在滚存之前我们将开关量新态存储单元的数据存入另一个单元,我们称之为开光量的前态存储单元。
当前态存储单元和新态存储单元的数据不同时,才认为按键有按下或者按键有释放。
因为按键抖动的时间大概是1~20ms左右,所以采集数据的周期至少要
ms。
消抖模块中,将29H,2AH,2BH,2CH,2DH设置为滚存单元,2EH单元设置为新态,将2FH设置为前态,将每次的采集到的数值赋给29H,进行滚存,当判断5个单元的数据一致使,将该数据赋予新态单元2EH。
在每次开始扫描前都要讲数据在5个单元中滚存一次,并将新态的数据赋予前态单元2FH。
5.2.3按键功能定义子程序
按键功能定义模块,是将功能选择性按键集中在一起而生成的一个新的模块。
在该模块中主要判断在常规进程下,调时键、调速键,小时制切换键是否有按下,在非常规进程下,判断确定键,取消键,是否按下,是否无按键操作。
在常规进程下,当调时键按下时,将24小时制的小时单元3CH更12小时制的小时单元3DH分别送到对应的暂存单元3FH、4FH,将分钟单元3BH送到分钟的暂存单元3EH,将上下午标志位23H.2暂存到23H.3,将进程有常规进程(00H)改为调时进程(10H)。
当按下的是调速键,则将进程改为调速进程(30H),当按下的是小时制切换键时,则将小时制标志位求反,不改变进程。
当在非常规进程下,判断取消键是否有压下,如果有压下,则将当前进程改为常规进程,暂存单元的数据不送到相应的单元。
若取消键没有压下,就判断确定键是否压下,有压下,就将暂存单元的数据送到相应的单元,即将3EH的数据送到3BH,将3FH单元的数据送到3CH,将4FH的数据送到3DH,将上下午标志暂存位23H.3送到23H.2。
同时将秒钟单元3AH,百分秒单元39H,以及计数单元38H单元清零。
若都没有按键按下,则转到无按键操作的程序段,经过三十秒的延时,若这30秒中没有任何操作,就将进程改为常规进程。
5.2.4键盘扫描子程序
判断片外的按键是否有按下,需要不断扫描端口电平的变化,并判断是哪个按键压下,因此需要编写一段程序来扫描端口的电平。
此次程序编程采用的是反转法来扫描端口电平。
方转法就是先让行线编程为输入线,将列线编程为输出线,并使输出线输出为全低电平,则行线中电平由高变低所在列为按键所在行;再把行线编程为输出线,列线编程为输出线,并使输出线输出全为低电平,则列线中电平由高变低所在列为按键所在列。
为了消除键盘的抖动,同样也设置了3个滚存单元63H,62H,61H,新键号存储单元64H,前键号存储单元65H,键值存储单元60H单元。
程序开始先将新键号64H的数据赋予前键号单元65H,接着将3个滚存单元的数据滚动存储(即62H的数据赋予63H,61H的数据赋予62H,),接着采用反转法扫描按键的位置,将键值存储在60H单元中(其中各个键所对应的键值为K0:
0EEH,K1:
0EDH,K2:
0EBH,K3:
0E7H,K4:
0DEH,K5:
0DDH,K6:
0DBH,K7:
0D7H,K8:
0BEH,K9:
0BDH,KA:
0BBH,KB:
0B7H,KC:
7EH,KD:
7DH,KE:
7BH,KF:
77H,)
接着根据每次所得到的键值与键值表相比较,如果相等则将该键值在键值表中的顺序号(键号)给61H,如果不等则接着往下查找,直至相等后者61H单元的数据位10H,就停止查表。
通过改变各键值在表中的顺序,就可以改变各个按键所对应的键号。
以下就是此次程序所用的键值表:
DB7DH,0EEH,0EDH,0EBH
DB0DEH,0DDH,0DBH,0BEH
DB0BDH,0BBH,7BH,7EH
DB0E7H,0D7H,0B7H,77H
最后将比较各个滚存单元的数据是否一致,若一致则将61H中的键号赋予64H单元。
5.2.5显示更新子程序
显示更新子程序主要的功能是根据显示缓冲显示单元存储的段码的序号,根据查找段码表得到相应的段码,送到段码驱动端口(0FEFCH),再输出对应位的位码,驱动数码管做出相应的显示。
此程序段主要采用的是间接寻址的方式,将显示缓冲单元的首地址30H赋予R0,将位码01H赋予R3,采用@A+PC的变址方式进行查找段码表。
每驱动一位数码管显示都需要调用1mS左右的延时,使得8个数码管能够稳定的显示。
以下是该程序段所用的段码表(0有效):
DB0C0H,0F9H,0A4H,0B0H,99H,92H,82H;字段码表。
"0"~"6"
DB0F8H,80H,90H,88H,83H,0C6H,0A1H;"7"~"9","A"~"D"
DB86H,8EH,0BFH,00H,0FFH,8CH,9CH;"E","F","-",全亮,空格,PF
5.2.6整点报时子程序
整点报时子程序采用小进程码来设置报时的音效,小进程单元为22H单元,默认是00H进程,其中01H,03H,05H进程是蜂鸣器响,但是响的时间不一样,02H,04H进程是蜂鸣器关闭的进程,关闭的时间也是不一样的。
通过判断小时标志位23H.1是否为1,如果不是就返回发主流程,如果是就将该标志位清零,并将22H单元中的数据由00H改为01H,将整点报时蜂鸣器逻辑存储位21H.7清零。
下次判断是不是01H进程,是,就开始减41H单元,并判断该单元的数据是否为0,若不是,则跳转返回到主流程,若是,就将进程改为下一进程02H,并关闭蜂鸣器21H.7置1,对41H重新赋值,若不是01H进程,就跳转判断是不是02H进程。
以此类推,直到最后进程05H结束,重新回到00H进程。
这样实现了滴三声的整点报时音效。
5.2.7键盘校时子程序
键盘校时子程序首先判断的是不是处于校时的进程,若不是则返回到主流程,不执行以下的程序段。
若是,就可以通过按键进行校时。
该子模块可分为6个功能块,分别是时加模块、时减模块、分加模块、分减模块、长按模块,按键释放模块。
其中时加、时减、分减、分减每个模块中又包含了快调与慢调的功能,长按模块主要是判断各个按键是否长按,若是长按,就建立各个按键的长按标志位分别是24H.0、24H.1、24H.2、24H.3对应时加键、时减键、分加键、分减键。
然后再4个校时模块中进行判断,实现快调与慢调的功能,以下以时加模块为例。
首先判断时加长安标志位24H.0是否为1,不是就判断时加键是否有压下,小时有就加1,没有就跳转判断下一模块,若为1,则调过判断按键检测部分,直接对小时以0.2S加1的速率进行快调。
在调整的时候同时调整12小时制的小时暂存单元4FH和上下午标志位的暂存位23H.3,使其与24小时制的小时暂存单元3CH保持同步,在时减的模块中药这样。
其余模块跟时加模块类似。
最后都要经过判断按键释放这一模块,如果按键释放则将各长按标志位清零,并对0.5S延时单元42H和0.2S延时单元43H赋初值。
5.2.8流星灯调速子程序
在调速进程下,执行流星灯调速子模块。
流星灯调速子程序模块主要分为外接按键PB调速模块和键盘选档模块。
其中PB调速模块分为PB6跟PB7调速模块,PB6速度变慢,PB7速度变快,以下以PB6调速为例。
PB6调速是通过判断2EH.6和2FH.6来判断按键PB6是否压下,若2FH.6为1,2EH.6为0就说明按键有压下,就对流速存储单元4AH加1,并通过换算将4AH单元的数据处于哪一档位赋予档位存储单元52H,接着判断上限,跟17H相比较,相等就将4AH的数据改为16H,防止其超过限制。
PB7调速同理。
键盘调速是在调速进程下才能执行的,采用