四路多段定时开关(一)信息工程毕业论文(3)
2013-06-01 01:32
导读:%模运算(取整数除法的余数) 主要就介绍一些我所用到的语句。 在程序设计中,主要利用了C语言的if、switch及for语句。其中if、switch为条件语句,for是一
% 模运算(取整数除法的余数)
主要就介绍一些我所用到的语句。
在程序设计中,主要利用了C语言的if、switch及for语句。其中if、switch为条件语句,for是一个循环控制语句,在程序中更常用到的语句是break语句,在switch语句中,在case子句执行完毕后,通过break语句使控制立即跳出switch语句。在循环语句中,break语句的作用是在循环体中测试到应立即结束循环时,使控制立即跳出循环结构,转而执行循环语句后的语句。
2-3 程序
2-3-1 程序中地址分配
程序设计中的地址分布,由于DS12C887中前14个字节是10字节用于记录时间、日历、闹钟和RAM以及4字节的控制、状态RAM。113字节通用RAM使用户使用,我先计算了我的地址分布,从第14个字节开始我用做存储每路的开关次数,每一路可设定每次开关的时间(小时、分钟、时长及功率),时长是以分钟为单位,最高可设置为99分钟。每一路开关每一次均要用四个字节,通过计算四路开关能在24小时内任意时间通断,每路24小时内最多可执行六次开与关,下表为我设定计算我在编程时的地址分布表。
表:DS12C887地址分配情况
路数 次数 第一次 第二次 第三次 第四次 第五次 第六次
第一路 14 15-18 19-22 23-26 27-30 31-34 35-38
第二路 39 40-43 44-47 48-51 52-55 56-59 60-63
第三路 64 65-68 69-72 73-76 77-80 81-84 85-88
第四路 89 90-93 94-97 98-101 102-105 106-109 110-113
例如程序:
for(i=0;i<4;i++);i为判断电路设计中的第几路,
{
switch(i)
{
case(0):
out0=0;
break;
……
}
for(j=0;j<XBYTE[14+25*i];j++);j为每路开关的开关次数。
{
if(((XBYTE[15+j*4+25*i]<hour)||((XBYTE[15+j*4+25*i]==hour)&&(XBYTE[16+j*4+25*i]<=min)))
&&(((XBYTE[15+j*4+25*i]+(XBYTE[17+j*4+25*i])/60)>hour)||(((XBYTE[15+j*4+25*i]+(XBYTE[17+j*4+25*i])/60)==hour)&&((XBYTE[16+j*4+25*i]+(XBYTE[17+j*4+25*i])%60)>min))))
{
switch(i)
{
case(0):
out0=XBYTE[18+4*j];
break;
……
}
举例在程序中设计第一路开关开关一次,即i=0,设定的开关次数(一次)存放在外部RAM(DS12C887)第14个字节中,XBYTE[14]=1,j=0时循环一次,,如果读取到第15个字节(小时)中数值小于或等于系统时间小时(hour)&&(与运算符)第16个字节(分钟)中数值小于或等于系统时间分钟(min)&&第15个字节数值+第17个字节(时长)数值/60大于等于系统时间小时(hour)&&第16个字节数值+第17个字节数值%60大于系统时间分钟(min),判断条件如果为真的情况下,输出第18个字节中设定的功率。
由于每路六次开关共用25个字节,因此循环语句用判断每路for (j=0; j< XBYTE[14+25*i];j++),每一路从14字节开始,后循环语句即用14+25*路数。
2-3-2主程序(main)
主程序中主要设置了CPU的工作模式及中断,T0为延时16ms;T1为显示时间设置为0.512ms;T2设置为延时100ms;设置芯片的工作模式:给外部RAM中A寄存器中写入0x20内容(XBYTE[0x0a]=0x20),即是将A寄存器中DV1位置1”,查看上述所讲DS12C887内容,[DV0 DV1 DV2]=[010]时,晶体振荡器开启并且保持时钟运行;
将外部RAM中B寄存器中写入0x1E内容,即是将B寄存器中UIE、SQWE、DM、24/12位置“1”,即是使得时钟芯片允许更新结束中断输出的IRQ;SQW输出设定频率的方波,采用二进制,并且为24小时制。
(转载自http://zw.NSEaC.com科教作文网)
主程序中还实现了通电时显示SZPT,一段时间延时后,显示0605(因为制做日期在五月份所以编程写入了0605),一段时间延时后,就读取时间显示小时和分钟。之后就是一个while循环语句。
2-3-3显示程序(display)
dis0=decode(d0); 此程序为解码程序
dis1=decode(d1);
dis2=decode(d2);
dis3=decode(d3);
key0=d3;数码显示器4
key1=d2;数码显示器3
key2=d1;数码显示器2
key3=d0;数码显示器1
switch(d)
{
case(0):
return 0x40;
break;…………
}
程序用的是switch选择语句,如果系统要显示零的话,返回数值为0x40。在设计中采用的是共阳极的七段数码显示器,当该位置“1”显示,在电路设计中,数码显示器又与SN74LS04芯片的一个非门相连,即该位为“0”时,数码管显示,其返回值计算如下表:
段号
显示数值 a
p2.0 b
p2.1 c
p2.2 d
p2.3 e
p2.4 f
p2.5 g
p2.6 十六进制
p2值
0 0 0 0 0 0 0 1 40
1 1 0 0 1 1 1 1 79
2 0 0 1 0 0 1 0 24
3 0 0 0 0 1 1 0 30
4 1 0 0 1 1 0 0 19
5 0 1 0 0 1 0 0 12
6 0 1 0 0 0 0 0 02
7 0 0 0 1 1 1 1 78
8 0 0 0 0 0 0 0 00
9 0 0 0 0 1 0 0 10
P 0 0 1 1 0 0 0 0C
内容来自www.nseac.com
T 0 1 1 1 0 0 1 4E
A 0 0 0 1 0 0 0 08
E 0 1 1 0 0 0 0 06
D 1 0 0 0 0 1 0 21
U 1 0 0 0 0 0 1 41
off 1 1 1 1 1 1 1 7F
2-3-4读取键盘并换算成键值(keytranslate)
这段程序的主要功能就是将杂乱无序的键盘使得有顺序可循。由于电路板上键盘不是按顺序排好的,因此通过编程当原来无序的键盘变得比较好操作。
case(0x0):
keyr=0;
break;
其具体程序对应的键盘值可看下表:
板上的顺序 0 4 8 12 1 5 9 13
编程后顺序 0 1 2 3 4 a b c
板上的顺序 2 6 10 14 3 7 11 15
编程后顺序 5 6 7 8 9 d e f
这段程序主要采用的是switch选择语句。
2-3-5外部中断1(key)
外部中断1为键盘中断,键进行读取。左图为:键盘中断一服务子程序图
keya,其功能在于,按第一下显示case(1): display (hour/10, hour%10, min/10,min%10);程序相同,按第二下显示年份,第三下显示为日期,第四下显示为星期几和秒。
Keyb,其功能在于,按下如果在SET为1并且0x0e不为0的情况下,如果条件key3<7为真的话,那么第14个字节即为第四段数码管的值,如果为假的情况下,蜂鸣器发声,并且显示“EAA0”;keyb==1 为真的情况下,显示为“1,off,off,XBYTE[0x0e]”,当0x0e不为“0”的情况下,keyb=2的情况下,显示为XBYTE[0x0f]及XBYTE[0x10]中的数值,若输入数值又将显示内容写入外部RAM中,语句如:XBYTE[4*l+0x0f]=key0*10+key1;XBYTE[4*l+0x10]=key2 *10 +key3;
(转载自http://zw.NSEaC.com科教作文网)
Keyd,其功能在于,进入设置和退出设置,当按下keyd键,显示为PASD,如果如果条件“(key0==1)&&key1==2)&&(key2==3)&&(key3==4)”为真的情况下,SET置“1”,并显示为“PASS”,即可以对系统进行设置修改,如果为假蜂鸣器发声,并显示“EAA0”。当系统修改好后,再按下keyd键,显示“0UEA”。
附录
附表1设备清单:
序号 设备名称 型号 数量
1 整流器 1
2 电磁电容 104 6
3 电磁电容 20 2
4 极性电容 470uf 2
5 极性电容 22uf 1
6 三端稳压器 7805 1
7 发光二极管 4
8 7段数码显示器 4
9 保险丝 1
10 继电器 4
11 蜂鸣器 1
12 电阻 2.2K 8
13 电阻 4.7K 7
14 按钮 17
15 时钟芯片 DS12887 1
16 单片机 AT89C52 1
17 驱动器 ULN2003A 1
18 反相器 SN7404N 1
19 键盘编码器 74C922 1
20 晶振 6MHZ 1
附图1:DS12C887地址分布图
结论
对于这一次的专题,我觉得真的有感觉到设计的感觉,跟实验问题有很不同的地方是我们可以自己构思功能,并且依据所要求的功能来设计自己的电路,完全要自己动手,因此在对于系统的功能都很清楚了。通过这次对单片机硬件、DS12C887的硬件结构、单片机C程序设计的学习,真的感觉收获不少,尤其是C语言的学习上,等于我利用了这次设计学习多了一门课程。如果事先就会C语言编程单片机我相信我能做的比目前好。
在开始编程的时候,由于自己在学习单片机的时候学的不够深,又由于设计安排在学完单片机一年以后的时候,忘的比较多,使得我总是不明白单片机如何读取DS12C887时间芯片的数据,也不知该如何写入。后通过苏老师指导方知将DS12C887芯片当做一个普通的外部RAM进行读写。
(科教范文网 lw.AsEac.com编辑整理)
一开始我们是用AT89C51进行编程,遗憾的是我第一次编程完程序之后,我的电路板居然不能完全容纳我的程序,竟然在implementation 时告诉我design is too large。后来经过研究和老师指点,我明白是我整个设计以及程序写了太多,导致容量不足。后来我们只有舍弃了AT89C51,改用了AT89C52芯片。实现了电路板一开始要想要实现的功能。
尽管如此,作专题重要的并不在于结果,而是自己在整个活动中的过程,经过了这一次专题,我体会到从设计到实际做出来的过程,而且也将我所学过的单片机知识完完全全的复习了一遍,并且还学到了不少,我想这才是做专题的最终目的,以及我的最大的收获。
参考文献:
徐爱华主编.单片机应用技术教程.北京:机械工业出版社,2003.7
胡伟,季晓衡编著.单片机C程序设计及应用实例.人民邮电出版社