课题名称:作息时间控制 专业名称:通信工程技术 学生班级: 学生姓名: 学生学号: 指导教师:
前言
目前单片机渗透到我们生活的各个领域,几乎很难找到哪个领域没有单
片机的踪迹。导弹的导航装置,飞机上各种仪表的控制,计算机的网络通讯与数据传输,工业自动化过程的实时控制和数据处理,广泛使用的各种智能IC 卡,民用豪华轿车的安全保障系统,录像机、摄像机、全自动洗衣机的控制,以及程控玩具、电子宠物等等,这些都离不开单片机。更不用说自动控制领域的机器人、智能仪表、医疗器械了。因此,单片机的学习、开发与应用将造就一批计算机应用与智能化控制的科学家、工程师。
单片机广泛应用于仪器仪表、家用电器、医用设备、航空航天、专用设备的智能化管理及过程控制等领域。
作为在校大学生,主要是能够掌握基本单片机的使用,典型的代表是80C51系列。此次设计既是采用了AT89S52单片机,结合课堂所学知识,进一步掌握了它的结构及工作原理。
2
目录
第1章、方案的选择........................................4 第2章、电路结构及其原理...................................5
2.1、整体思路.........................................5 2.2、电源.............................................5 2.3、单片机系统.......................................5
2.3.1、电路及工作原理............................6
2.3.2、单片机芯片(AT89S52)的封装与信号引......7 第3章、程序设计...........................................8
3.1、程序整体框架.....................................8 3.2、程序.............................................8 第4章、调试..............................................9
4.1、硬件调试........................................9 4.2、软件调试........................................9 第5章、设计总结..........................................10 附录一、C 语言程序........................................11 附录二、单片机系统PCB 图..................................23 附录四、主要参考文献......................................24
3
第1章、方案的选择
方案一、利用单片机控制实现
采用单片机AT89S52小系统电路,通过C 语言程序实现数码管显示及打铃系统(利用蜂鸣器模拟实现),(本次作品中由于缺少蜂鸣器由发光二极管替代)。
方案二、利用集成芯片LM8361和存储器RAM6264
采用了大规模时钟集成芯片LM8361作时钟电路,用存储器RAM6264作译码器,利用译码器的读取、存储、写入时钟信号来控制其时间电路的显示以及响铃电路的正常运做即发出“嘀-嘟”的打铃声。
对比方案一、方案二,结合我们现学知识通过方案二单片机小系统实现作息时间控制相对而言电路结构较简单,更容易实现,故采用方案一。
第2章、电路结构及其原理
2.1、整体思路
采用+5V电源给单片机供电;上电后,单片机工作,将c 语言程序下载到单
片机内,由数码管(接P0口)显示;45分钟后蜂鸣器响10秒,十分中后蜂鸣器再响10秒,之后重复。(本次作品中由于缺少蜂鸣器由发光二极管替代)
2.2、电源
单片机是采用+5V电源供电。自制电源通过12V 变压器,经整流桥整流,滤波电路,稳压管7805稳压将220V 交流电压转换为+5V直流电压,其原理图如图2.1。
图2.1 +5V电源原理图
2.3、单片机系统 2.3.1、电路及工作原理
整个单片机系统主要由单片机芯片(AT89S52)、复位电路、振荡电路、蜂鸣器及数码管四部分组成。程序下载至单片机内后,上电时,单片机进入工作状态,振荡电路形成自激振荡器,单片机控制液晶和蜂鸣器实现程序内容。原理图如图2.2。
图2.2 单片机系统原理图
2.3.2、单片机芯片(AT89S52)的封装与信号引脚
AT89S52是40引脚双列直插式DIP (Dual In Line Package)的封装形式,其引脚排列见图2.3。
图2.3 AT89S52芯片
输入/输出口线
P0.0-P0.7 P0口8位双向口线 P1.0-P1.7 P1口8位双向口线 P2.0-P2.7 P2口8位双向口线 P3.0-P3.7 P3口8位双向口线
地址锁存控制信号ALE
在系统扩展时,ALE 用于控制把P0口输出的低8位地址送入锁存器存
起来,以实现低位地址和数据的分时传送。此外,ALE 可作为外部时钟或外部定时脉冲使用。
外部程序存储器读选通信号PSEN
在读外部ROM 时PSEN 低电平有效,以实现外部ROM 单元的读操作。 访问程序存储器控制信号EA
当EA 信号为低电平时,对ROM 的读操作是针对外部程序存储器的;而当EA 为高电平时,对ROM 的读操作是从内部程序存储器开始,并可延续至外部程序存储器。 复位信号RST
当输入的复位信号延续到2个机器周期以上高电平即为有效,用于完成单片机的复位操作。
外接晶体引线端XTAL1和XTAL2
当使用芯片内部时钟时,XTAL1和XTAL2用于外接石英晶体谐振器和微调电容;当使用外部时钟时,用于接入外部时钟脉冲信号。 地线V
SS
+5V电源V
cc
第3章、程序设计
3.1、程序整体框架
3.2、程序 见附录一
第4章、调试
4.1、硬件调试
电源的调试:电路板制作完成后,首先对电源进行测试,利用数字式万用表看电源输出是否为5V, 当然,由于误差存在,实际输出小于5V ,约为4.96V ,在误差允许范围内。
单片机系统的调试:电源正常后,给单片机系统供电,为避免单片机芯片烧坏,所以应先用万用表对芯片接电源处是否为5V ,确定正常后方可将芯片和装上去。向单片机下载一个简单的显示程序,检验单片机是否能够正常工作。
4.2、软件调试
C 语言程序编写完成后,进行编译、链接,无错误后,单步运行程序,看是否能正常运行通过。
第5章、设计总结
以上是我们组所设计的作息时间控制,它经过了多次的修改和整理,最终使各项功能得以实现。
在设计过程中我们分工合作,充分发挥了团体的力量。但在设计过程中我们也遇到了不少麻烦,主要是在C 语言程序这方面。由于老师上课时主要是讲汇编语言,而如果我们采用汇编实现所须功能的话,那将非常的复杂。对于C 语言来说我们还比较生疏,尽管如此我们还是通过多方面努力,利用C 语言完成了程序的编写。
通过这两周的学习,我们感觉有很大的收获:首先,通过学习使自己对课本上的知识可以应用于实际,使得理论与实际相结合,加深自己对课本知识的更好理解,同时实习也段练了我们个人的动手能力和自学能力,充分利用图书馆去查阅资料,增加了许多课本以外的知识,对protel 99和EWB 等仿真软件操作,能达到学以致用。对我们学生来说,理论与实践同样重要,这是我们以后在工作中说明自己能力的一个重要标准。
附录一 :
C 语言程序
#include
#define uchar unsigned char #define uint unsigned int sbit AA=P1^0; sbit BB=P1^1; sbit CC=P1^2; sbit DD=P1^3; sbit ff=P3^7;
uint year; //定义年变量 uchar month=1,day; //定义月 日变量 uchar yr1,yr2,mh1,mh2,dy1,dy2; //年月日缓冲变量 uchar second,minute,hour; //定义时分秒变量 uchar jsd1,jsd2,jme1,jme2,jhr1,jhr2; //时分秒缓冲变量 uchar second_ck,minute_ck,hour_ck; //定义闹钟变量 uchar sd_ck1,sd_ck2,me_ck1,me_ck2,hr_ck1,hr_ck2; //闹钟缓冲变量
uchar v,KB0,KB1,KB2; //定义按键变量 uchar *p; //指向显示缓冲区的指针变量 uchar counter1; //定时器0定时计数变量 uchar j,i;
uchar q;
uchar code MA[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d, //段码 0x7d,0x07,0x7f,0x6f,0x40};
uchar code WEI[]={0xfe,0xfd,0xfb,0xf7, //位码 0xef,0xdf,0xbf,0x7f};
uint code table[]={820,830,915,925,1010,1030,1115,1125,1210, //打铃时间表
1400,1445,1455,1540,1600,1645,1655,1740};
uchar pp[]={0,0,10,0,0,10,0,0}; //年月日 时钟显示缓冲区 uchar yf[]={32,29,32,31,32,31,32,32,31,32,31,32}; //月份数组 uchar clock[]={0,0,10,0,0,10,0,0}; //闹钟显示缓冲区 uchar bell[]={0,0,10,0,0,10,0,0}; //打铃时间比较缓冲区 uchar bj[]={0,0,10,0,0,10,0,0}; //定义是否进行比较数组
void ini(void); void zh0(void); void zh1(void); void zh2(void);
void zh3(void);
void delay(uint m); void display(void); void process(void); void key_y(void); void key_v(void); void key_0(void); void key_1(void); void key_2(void);
void process_v(void); void display1(void); void display2(void); void BJtime(void); void BJtime_1(void); void flash(void);
/*****************************主*****************************************/ void main(void) {
ini(); while(1) {
process(); key_y(); } }
/*****************************定时器初********************************************/ void ini(void) { TMOD=0x11; TH0=0x4c; TL0=0x00; TR0=1; ET0=1; EA=1; }
/*****************************数据处*****************************************/ void zh0(void) { pp[0]=jsd1; pp[1]=jsd2;
函数
始化子程序
理子程序
pp[3]=jme1; pp[4]=jme2; pp[6]=jhr1; pp[7]=jhr2; BJtime(); }
void zh1(void) { pp[0]=dy1; pp[1]=dy2; pp[3]=mh1; pp[4]=mh2; pp[6]=yr1; pp[7]=yr2; }
void zh2(void)
{ clock[0]=sd_ck1; clock[1]=sd_ck2; clock[3]=me_ck1; clock[4]=me_ck2; clock[6]=hr_ck1; clock[7]=hr_ck2; }
void zh3(void)
{ bell[7]=(table[q]/1000); bell[6]=(table[q]/100)%10; bell[4]=(table[q]/10)%10; bell[3]=table[q]%10; }
/*****************************延时*****************************************/ void delay(uint m) { while(--m);}
/*****************************显示*****************************************/ void display1(void) { j=0;
for(p=pp;p
子程序
子程序
j++; } }
void display2(void) { i=0;
for(p=clock;p
void display(void) { switch(v)
{ case 0: zh0();
display1();break; case 1: zh1();
display1();break; case 2: zh2();
display2();break; } }
void process(void) { if(year%4==0) yf[1]=30;
else yf[1]=29; if(v==0)
{ jsd1=second%10; jsd2=second/10; jme1=minute%10; jme2=minute/10; jhr1=hour%10; jhr2=hour/10; display(); }
if(v==1)
{ yr2=(year%100)/10; yr1=year%10; mh2=month/10; mh1=month%10; dy2=day/10;
dy1=day%10; display(); }
if(v==2)
{ sd_ck1=second_ck%10; sd_ck2=second_ck/10; me_ck1=minute_ck%10; me_ck2=minute_ck/10; hr_ck1=hour_ck%10; hr_ck2=hour_ck/10; display(); }
for(q=0;q
display(); zh3();
BJtime_1(); } }
/***************************************时钟与闹钟数据比较********************************************/ void BJtime(void) {
uchar n,b,s,ck; for(n=0;n
{ if(clock[n]==bj[n]) b=1;
else {b=0;break;} }
if(b==0) {
for(s=0;s
{ if(pp[s]==clock[s]) ck=1;
else { ck=0;break;} }
if(ck==1) {
flash(); } } }
/***************************************时钟与打铃时间比较********************************************/
void BJtime_1(void) {
uchar m,a,r,pk; for(m=0;m
{ if(bell[m]==bj[m]) a=1;
else {a=0;break;} }
if(a==0)
{ for(r=0;r
{ if(pp[r]==bell[r]) pk=1;
else { pk=0;break;} }
if(pk==1) {
flash(); } } }
/*****************************灯闪*****************************************/ void flash(void) {
uchar f;
for(f=0;f
delay(3000); } }
/*****************************判键子程*****************************************/ void key_y(void) {
while(1) {
if(AA==0)
{ delay(100); if(AA==0) { v++;
if(v==3) { v=0;}
while(1) {process(); if(AA==1) break;}
烁
序
} }
process(); key_v(); } }
void key_v(void) { switch(v)
{ case 0: key_0(); break; case 1: key_1(); break; case 2: key_2(); break; } }
/*****************************时钟调整子程序*****************************************/ void key_0(void) {
if(BB==0)
{ delay(100); if(BB==0) { KB0++;
if(KB0==5) {KB0=1;}
while(1) {process(); if(BB==1) break;} } }
switch(KB0) {
case 1: TR0=0; if(CC==0)
{ delay(100); if(CC==0)
{ second++; if(second==60) second=0;
while(1) {process(); if(CC==1) break;} } }
if(DD==0)
{ delay(100); if(DD==0)
{ second--; if(second==0) second=60;
while(1) {process(); if(DD==1) break;}
} }
break; case 2: if(CC==0)
{ delay(100); if(CC==0)
{ minute++; if(minute==60) minute=0;
while(1) {process(); if(CC==1) break;} } }
if(DD==0)
{ delay(100); if(DD==0)
{ minute--; if(minute==0) minute=60;
while(1) {process(); if(DD==1) break;} } }
break; case 3: if(CC==0)
{ delay(100); if(CC==0)
{ hour++; if(hour==24) hour=0;
while(1) {process(); if(CC==1) break;} } }
if(DD==0)
{ delay(100); if(DD==0)
{ hour--; if(hour==0) hour=24;
while(1) {process(); if(DD==1) break;} } }
break;
case 4: TR0=1; break; } }
/*****************************年月日调整子程序*****************************************/ void key_1(void) {
if(BB==0)
{ delay(100); if(BB==0)
if(KB1==4) {KB1=1;}
while(1) {process(); if(BB==1) break;} } }
switch(KB1) {
case 1: if(CC==0)
{ delay(100); if(CC==0)
{ day++; if(day==yf[month-1]) day=1;
while(1) {process(); if(CC==1) break;} } }
if(DD==0)
{ delay(100); if(DD==0)
{ day--; if(day==0) day=yf[month-1];
while(1) {process(); if(DD==1) break;} } }
break; case 2: if(CC==0)
{ delay(100); if(CC==0)
{ month++; if(month==13) month=1;
while(1) {process(); if(CC==1) break;} } }
if(DD==0)
{ delay(100); if(DD==0)
{ month--; if(month==0) month=12;
while(1) {process(); if(DD==1) break;} } }
break; case 3: if(CC==0)
{ delay(100); if(CC==0)
{ year++; if(year==21) year=9;
while(1) {process(); if(CC==1) break;} }
if(DD==0)
{ delay(100); if(DD==0)
{ year--; if(year==8) year=20;
while(1) {process(); if(DD==1) break;} } }
break; } }
/*****************************设置闹钟子程序*****************************************/ void key_2(void) {
if(BB==0)
{ delay(100); if(BB==0) { KB1++;
if(KB1==4) {KB1=1;}
while(1) {process(); if(BB==1) break;} } }
switch(KB1) {
case 1: if(CC==0)
{ delay(100); if(CC==0) { second_ck++; if(second_ck==61) second_ck=0;
while(1) {process(); if(CC==1) break;} } }
if(DD==0)
{ delay(100); if(DD==0)
{ second_ck--; if(second_ck==0) second_ck=60; while(1) {process(); if(DD==1) break;} } }
break; case 2: if(CC==0)
{ delay(100); if(CC==0) { minute_ck++; if(minute_ck==61) minute_ck=0;
while(1) {process(); if(CC==1) break;} } }
if(DD==0)
{ delay(100); if(DD==0)
{ minute_ck--; if(minute_ck==0) minute_ck=60; while(1) {process(); if(DD==1) break;} } }
break; case 3: if(CC==0)
{ delay(100); if(CC==0)
{ hour_ck++; if(hour_ck==25) hour_ck=0; while(1) {process(); if(CC==1) break;} } }
if(DD==0)
{ delay(100); if(DD==0)
{ hour_ck--; if(hour_ck==0) hour_ck=24; while(1) {process(); if(DD==1) break;} } }
break; } }
/*****************************定时器0中断程序*****************************************/ void Timer_0(void) interrupt 1 using 2 {
counter1++;
if(counter1==20) { counter1=0; second++;
if(second==60) { second=0; minute++;
if(minute==60)
{ minute=0; hour++;
if(hour==24) { hour=0; day++;
if(day==yf[month-1]) { day=1; month++;
if(month==13) { month=1; year++;
if(year==21) {year=9;} } } } } } }
TH0=0x4c; TL0=0x00; }
附录二:
单片机系统
PCB 图
参考文献
李广弟. 朱月秀. 冷祖祁. 《单片机基础(第3版)》. 北京航空航天大学出版社 杨志忠. 《数字电子技术》. 高等教育出版社 潘 松 黄继业. 《EDA 技术实用教程》. 科学出版社 康华光. 电子技术基础(第四版). 高等教育出版社 梁宗善. 新型集成块应用. 华中理工大出版社
课题名称:作息时间控制 专业名称:通信工程技术 学生班级: 学生姓名: 学生学号: 指导教师:
前言
目前单片机渗透到我们生活的各个领域,几乎很难找到哪个领域没有单
片机的踪迹。导弹的导航装置,飞机上各种仪表的控制,计算机的网络通讯与数据传输,工业自动化过程的实时控制和数据处理,广泛使用的各种智能IC 卡,民用豪华轿车的安全保障系统,录像机、摄像机、全自动洗衣机的控制,以及程控玩具、电子宠物等等,这些都离不开单片机。更不用说自动控制领域的机器人、智能仪表、医疗器械了。因此,单片机的学习、开发与应用将造就一批计算机应用与智能化控制的科学家、工程师。
单片机广泛应用于仪器仪表、家用电器、医用设备、航空航天、专用设备的智能化管理及过程控制等领域。
作为在校大学生,主要是能够掌握基本单片机的使用,典型的代表是80C51系列。此次设计既是采用了AT89S52单片机,结合课堂所学知识,进一步掌握了它的结构及工作原理。
2
目录
第1章、方案的选择........................................4 第2章、电路结构及其原理...................................5
2.1、整体思路.........................................5 2.2、电源.............................................5 2.3、单片机系统.......................................5
2.3.1、电路及工作原理............................6
2.3.2、单片机芯片(AT89S52)的封装与信号引......7 第3章、程序设计...........................................8
3.1、程序整体框架.....................................8 3.2、程序.............................................8 第4章、调试..............................................9
4.1、硬件调试........................................9 4.2、软件调试........................................9 第5章、设计总结..........................................10 附录一、C 语言程序........................................11 附录二、单片机系统PCB 图..................................23 附录四、主要参考文献......................................24
3
第1章、方案的选择
方案一、利用单片机控制实现
采用单片机AT89S52小系统电路,通过C 语言程序实现数码管显示及打铃系统(利用蜂鸣器模拟实现),(本次作品中由于缺少蜂鸣器由发光二极管替代)。
方案二、利用集成芯片LM8361和存储器RAM6264
采用了大规模时钟集成芯片LM8361作时钟电路,用存储器RAM6264作译码器,利用译码器的读取、存储、写入时钟信号来控制其时间电路的显示以及响铃电路的正常运做即发出“嘀-嘟”的打铃声。
对比方案一、方案二,结合我们现学知识通过方案二单片机小系统实现作息时间控制相对而言电路结构较简单,更容易实现,故采用方案一。
第2章、电路结构及其原理
2.1、整体思路
采用+5V电源给单片机供电;上电后,单片机工作,将c 语言程序下载到单
片机内,由数码管(接P0口)显示;45分钟后蜂鸣器响10秒,十分中后蜂鸣器再响10秒,之后重复。(本次作品中由于缺少蜂鸣器由发光二极管替代)
2.2、电源
单片机是采用+5V电源供电。自制电源通过12V 变压器,经整流桥整流,滤波电路,稳压管7805稳压将220V 交流电压转换为+5V直流电压,其原理图如图2.1。
图2.1 +5V电源原理图
2.3、单片机系统 2.3.1、电路及工作原理
整个单片机系统主要由单片机芯片(AT89S52)、复位电路、振荡电路、蜂鸣器及数码管四部分组成。程序下载至单片机内后,上电时,单片机进入工作状态,振荡电路形成自激振荡器,单片机控制液晶和蜂鸣器实现程序内容。原理图如图2.2。
图2.2 单片机系统原理图
2.3.2、单片机芯片(AT89S52)的封装与信号引脚
AT89S52是40引脚双列直插式DIP (Dual In Line Package)的封装形式,其引脚排列见图2.3。
图2.3 AT89S52芯片
输入/输出口线
P0.0-P0.7 P0口8位双向口线 P1.0-P1.7 P1口8位双向口线 P2.0-P2.7 P2口8位双向口线 P3.0-P3.7 P3口8位双向口线
地址锁存控制信号ALE
在系统扩展时,ALE 用于控制把P0口输出的低8位地址送入锁存器存
起来,以实现低位地址和数据的分时传送。此外,ALE 可作为外部时钟或外部定时脉冲使用。
外部程序存储器读选通信号PSEN
在读外部ROM 时PSEN 低电平有效,以实现外部ROM 单元的读操作。 访问程序存储器控制信号EA
当EA 信号为低电平时,对ROM 的读操作是针对外部程序存储器的;而当EA 为高电平时,对ROM 的读操作是从内部程序存储器开始,并可延续至外部程序存储器。 复位信号RST
当输入的复位信号延续到2个机器周期以上高电平即为有效,用于完成单片机的复位操作。
外接晶体引线端XTAL1和XTAL2
当使用芯片内部时钟时,XTAL1和XTAL2用于外接石英晶体谐振器和微调电容;当使用外部时钟时,用于接入外部时钟脉冲信号。 地线V
SS
+5V电源V
cc
第3章、程序设计
3.1、程序整体框架
3.2、程序 见附录一
第4章、调试
4.1、硬件调试
电源的调试:电路板制作完成后,首先对电源进行测试,利用数字式万用表看电源输出是否为5V, 当然,由于误差存在,实际输出小于5V ,约为4.96V ,在误差允许范围内。
单片机系统的调试:电源正常后,给单片机系统供电,为避免单片机芯片烧坏,所以应先用万用表对芯片接电源处是否为5V ,确定正常后方可将芯片和装上去。向单片机下载一个简单的显示程序,检验单片机是否能够正常工作。
4.2、软件调试
C 语言程序编写完成后,进行编译、链接,无错误后,单步运行程序,看是否能正常运行通过。
第5章、设计总结
以上是我们组所设计的作息时间控制,它经过了多次的修改和整理,最终使各项功能得以实现。
在设计过程中我们分工合作,充分发挥了团体的力量。但在设计过程中我们也遇到了不少麻烦,主要是在C 语言程序这方面。由于老师上课时主要是讲汇编语言,而如果我们采用汇编实现所须功能的话,那将非常的复杂。对于C 语言来说我们还比较生疏,尽管如此我们还是通过多方面努力,利用C 语言完成了程序的编写。
通过这两周的学习,我们感觉有很大的收获:首先,通过学习使自己对课本上的知识可以应用于实际,使得理论与实际相结合,加深自己对课本知识的更好理解,同时实习也段练了我们个人的动手能力和自学能力,充分利用图书馆去查阅资料,增加了许多课本以外的知识,对protel 99和EWB 等仿真软件操作,能达到学以致用。对我们学生来说,理论与实践同样重要,这是我们以后在工作中说明自己能力的一个重要标准。
附录一 :
C 语言程序
#include
#define uchar unsigned char #define uint unsigned int sbit AA=P1^0; sbit BB=P1^1; sbit CC=P1^2; sbit DD=P1^3; sbit ff=P3^7;
uint year; //定义年变量 uchar month=1,day; //定义月 日变量 uchar yr1,yr2,mh1,mh2,dy1,dy2; //年月日缓冲变量 uchar second,minute,hour; //定义时分秒变量 uchar jsd1,jsd2,jme1,jme2,jhr1,jhr2; //时分秒缓冲变量 uchar second_ck,minute_ck,hour_ck; //定义闹钟变量 uchar sd_ck1,sd_ck2,me_ck1,me_ck2,hr_ck1,hr_ck2; //闹钟缓冲变量
uchar v,KB0,KB1,KB2; //定义按键变量 uchar *p; //指向显示缓冲区的指针变量 uchar counter1; //定时器0定时计数变量 uchar j,i;
uchar q;
uchar code MA[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d, //段码 0x7d,0x07,0x7f,0x6f,0x40};
uchar code WEI[]={0xfe,0xfd,0xfb,0xf7, //位码 0xef,0xdf,0xbf,0x7f};
uint code table[]={820,830,915,925,1010,1030,1115,1125,1210, //打铃时间表
1400,1445,1455,1540,1600,1645,1655,1740};
uchar pp[]={0,0,10,0,0,10,0,0}; //年月日 时钟显示缓冲区 uchar yf[]={32,29,32,31,32,31,32,32,31,32,31,32}; //月份数组 uchar clock[]={0,0,10,0,0,10,0,0}; //闹钟显示缓冲区 uchar bell[]={0,0,10,0,0,10,0,0}; //打铃时间比较缓冲区 uchar bj[]={0,0,10,0,0,10,0,0}; //定义是否进行比较数组
void ini(void); void zh0(void); void zh1(void); void zh2(void);
void zh3(void);
void delay(uint m); void display(void); void process(void); void key_y(void); void key_v(void); void key_0(void); void key_1(void); void key_2(void);
void process_v(void); void display1(void); void display2(void); void BJtime(void); void BJtime_1(void); void flash(void);
/*****************************主*****************************************/ void main(void) {
ini(); while(1) {
process(); key_y(); } }
/*****************************定时器初********************************************/ void ini(void) { TMOD=0x11; TH0=0x4c; TL0=0x00; TR0=1; ET0=1; EA=1; }
/*****************************数据处*****************************************/ void zh0(void) { pp[0]=jsd1; pp[1]=jsd2;
函数
始化子程序
理子程序
pp[3]=jme1; pp[4]=jme2; pp[6]=jhr1; pp[7]=jhr2; BJtime(); }
void zh1(void) { pp[0]=dy1; pp[1]=dy2; pp[3]=mh1; pp[4]=mh2; pp[6]=yr1; pp[7]=yr2; }
void zh2(void)
{ clock[0]=sd_ck1; clock[1]=sd_ck2; clock[3]=me_ck1; clock[4]=me_ck2; clock[6]=hr_ck1; clock[7]=hr_ck2; }
void zh3(void)
{ bell[7]=(table[q]/1000); bell[6]=(table[q]/100)%10; bell[4]=(table[q]/10)%10; bell[3]=table[q]%10; }
/*****************************延时*****************************************/ void delay(uint m) { while(--m);}
/*****************************显示*****************************************/ void display1(void) { j=0;
for(p=pp;p
子程序
子程序
j++; } }
void display2(void) { i=0;
for(p=clock;p
void display(void) { switch(v)
{ case 0: zh0();
display1();break; case 1: zh1();
display1();break; case 2: zh2();
display2();break; } }
void process(void) { if(year%4==0) yf[1]=30;
else yf[1]=29; if(v==0)
{ jsd1=second%10; jsd2=second/10; jme1=minute%10; jme2=minute/10; jhr1=hour%10; jhr2=hour/10; display(); }
if(v==1)
{ yr2=(year%100)/10; yr1=year%10; mh2=month/10; mh1=month%10; dy2=day/10;
dy1=day%10; display(); }
if(v==2)
{ sd_ck1=second_ck%10; sd_ck2=second_ck/10; me_ck1=minute_ck%10; me_ck2=minute_ck/10; hr_ck1=hour_ck%10; hr_ck2=hour_ck/10; display(); }
for(q=0;q
display(); zh3();
BJtime_1(); } }
/***************************************时钟与闹钟数据比较********************************************/ void BJtime(void) {
uchar n,b,s,ck; for(n=0;n
{ if(clock[n]==bj[n]) b=1;
else {b=0;break;} }
if(b==0) {
for(s=0;s
{ if(pp[s]==clock[s]) ck=1;
else { ck=0;break;} }
if(ck==1) {
flash(); } } }
/***************************************时钟与打铃时间比较********************************************/
void BJtime_1(void) {
uchar m,a,r,pk; for(m=0;m
{ if(bell[m]==bj[m]) a=1;
else {a=0;break;} }
if(a==0)
{ for(r=0;r
{ if(pp[r]==bell[r]) pk=1;
else { pk=0;break;} }
if(pk==1) {
flash(); } } }
/*****************************灯闪*****************************************/ void flash(void) {
uchar f;
for(f=0;f
delay(3000); } }
/*****************************判键子程*****************************************/ void key_y(void) {
while(1) {
if(AA==0)
{ delay(100); if(AA==0) { v++;
if(v==3) { v=0;}
while(1) {process(); if(AA==1) break;}
烁
序
} }
process(); key_v(); } }
void key_v(void) { switch(v)
{ case 0: key_0(); break; case 1: key_1(); break; case 2: key_2(); break; } }
/*****************************时钟调整子程序*****************************************/ void key_0(void) {
if(BB==0)
{ delay(100); if(BB==0) { KB0++;
if(KB0==5) {KB0=1;}
while(1) {process(); if(BB==1) break;} } }
switch(KB0) {
case 1: TR0=0; if(CC==0)
{ delay(100); if(CC==0)
{ second++; if(second==60) second=0;
while(1) {process(); if(CC==1) break;} } }
if(DD==0)
{ delay(100); if(DD==0)
{ second--; if(second==0) second=60;
while(1) {process(); if(DD==1) break;}
} }
break; case 2: if(CC==0)
{ delay(100); if(CC==0)
{ minute++; if(minute==60) minute=0;
while(1) {process(); if(CC==1) break;} } }
if(DD==0)
{ delay(100); if(DD==0)
{ minute--; if(minute==0) minute=60;
while(1) {process(); if(DD==1) break;} } }
break; case 3: if(CC==0)
{ delay(100); if(CC==0)
{ hour++; if(hour==24) hour=0;
while(1) {process(); if(CC==1) break;} } }
if(DD==0)
{ delay(100); if(DD==0)
{ hour--; if(hour==0) hour=24;
while(1) {process(); if(DD==1) break;} } }
break;
case 4: TR0=1; break; } }
/*****************************年月日调整子程序*****************************************/ void key_1(void) {
if(BB==0)
{ delay(100); if(BB==0)
if(KB1==4) {KB1=1;}
while(1) {process(); if(BB==1) break;} } }
switch(KB1) {
case 1: if(CC==0)
{ delay(100); if(CC==0)
{ day++; if(day==yf[month-1]) day=1;
while(1) {process(); if(CC==1) break;} } }
if(DD==0)
{ delay(100); if(DD==0)
{ day--; if(day==0) day=yf[month-1];
while(1) {process(); if(DD==1) break;} } }
break; case 2: if(CC==0)
{ delay(100); if(CC==0)
{ month++; if(month==13) month=1;
while(1) {process(); if(CC==1) break;} } }
if(DD==0)
{ delay(100); if(DD==0)
{ month--; if(month==0) month=12;
while(1) {process(); if(DD==1) break;} } }
break; case 3: if(CC==0)
{ delay(100); if(CC==0)
{ year++; if(year==21) year=9;
while(1) {process(); if(CC==1) break;} }
if(DD==0)
{ delay(100); if(DD==0)
{ year--; if(year==8) year=20;
while(1) {process(); if(DD==1) break;} } }
break; } }
/*****************************设置闹钟子程序*****************************************/ void key_2(void) {
if(BB==0)
{ delay(100); if(BB==0) { KB1++;
if(KB1==4) {KB1=1;}
while(1) {process(); if(BB==1) break;} } }
switch(KB1) {
case 1: if(CC==0)
{ delay(100); if(CC==0) { second_ck++; if(second_ck==61) second_ck=0;
while(1) {process(); if(CC==1) break;} } }
if(DD==0)
{ delay(100); if(DD==0)
{ second_ck--; if(second_ck==0) second_ck=60; while(1) {process(); if(DD==1) break;} } }
break; case 2: if(CC==0)
{ delay(100); if(CC==0) { minute_ck++; if(minute_ck==61) minute_ck=0;
while(1) {process(); if(CC==1) break;} } }
if(DD==0)
{ delay(100); if(DD==0)
{ minute_ck--; if(minute_ck==0) minute_ck=60; while(1) {process(); if(DD==1) break;} } }
break; case 3: if(CC==0)
{ delay(100); if(CC==0)
{ hour_ck++; if(hour_ck==25) hour_ck=0; while(1) {process(); if(CC==1) break;} } }
if(DD==0)
{ delay(100); if(DD==0)
{ hour_ck--; if(hour_ck==0) hour_ck=24; while(1) {process(); if(DD==1) break;} } }
break; } }
/*****************************定时器0中断程序*****************************************/ void Timer_0(void) interrupt 1 using 2 {
counter1++;
if(counter1==20) { counter1=0; second++;
if(second==60) { second=0; minute++;
if(minute==60)
{ minute=0; hour++;
if(hour==24) { hour=0; day++;
if(day==yf[month-1]) { day=1; month++;
if(month==13) { month=1; year++;
if(year==21) {year=9;} } } } } } }
TH0=0x4c; TL0=0x00; }
附录二:
单片机系统
PCB 图
参考文献
李广弟. 朱月秀. 冷祖祁. 《单片机基础(第3版)》. 北京航空航天大学出版社 杨志忠. 《数字电子技术》. 高等教育出版社 潘 松 黄继业. 《EDA 技术实用教程》. 科学出版社 康华光. 电子技术基础(第四版). 高等教育出版社 梁宗善. 新型集成块应用. 华中理工大出版社