单片机综合设计报告
----万年历
学院:信息学院
班级:09通信A班
学号:0915231007
姓名:陈振耀
指导老师:戴在平
时间:2011.12
1
第一章:设计目的与设计要求 ........ 3
1.1、设计目的 ................................ 3
1.2、设计任务和要求 .................... 3
第二章:硬件设计 ............................ 3
2.1引言 ........................................... 3
2.2整体设计方案 ........................... 4
2.3系统工作原理 ........................... 4
2.4电路功能使用说明 ................... 5
第三章 :软件总体设计方案 ............. 6
3.1软件的总体设计 ....................... 6
3.2控制电路的C语言源程序 ...... 9
第四章 : 实验设计结果分析 ....... 24
第五章 :总结 ................................... 25
第六章: 问题解决 ..................... 25
2
第一章:设计目的与设计要求
1.1、设计目的 1.通过单片机综合实验设计,熟练掌握汇编语言的编程方法和编程过程,将理论联系到实践中去,提高我们的动脑和动手的能力。
2.通过简易数字温度计设计的设计,掌握STC89C51的使用方法,和简单程序的编写,最终提高我们的对时序图的识别能力.
1.2、设计任务和要求
基本功能:
可调节的万年历(年、月、日、星期)、数字时钟(24小时制时、分、秒);
拓展功能:
实现两个可定时闹钟;
实现可存储的秒表;
用于训练表;
第二章:硬件设计
2.1引言
随着时代的进步和发展,单片机技术已经普及到我们的生活,工作,科研,各个领域,已经成为一项比较成熟的技术,此次设计利用STC89C52单片机芯片实现电子钟系统设计计,其硬件原理框图如图1所示,其中显示采用液晶LCD1602.
3
图1 硬件原理图
本次设计时钟电路,使用了STC89C52单片机芯片控制电路,单片机控制电路简单且省去了很多复杂的线路,使得电路简明易懂,使用键盘键上的按键来调整时钟的时、分、秒,用一扬声器来进行定时提醒,同时使用C语言程序来控制整个时钟显示,使得编程变得更容易,这样通过四个模块:键盘、芯片、蜂鸣器、显示屏即可满足设计要求。
2.2整体设计方案
设计的PCB如下图所示,其中主控芯片采用STC89C52,,用液晶LCD1602显示,实现万年历以及其他拓展功能。
2.3系统工作原理 设计的电路主要由主控模块、液晶显示模块、按键模块和闹钟模块共4个模块组成。仿真图如图2.
本设计采用c语言程序设计,使单片机控制液晶显示器时、分、秒,当秒计数计满60时就向分进位,分计数器计满60后向时计数器进位,小时计数器按“23翻0”规律计数。时、分、秒的计数结果经过数据处理可直接送显示器显示。当计时发生误差的时候可以用校时电路进行校正。设计采用的是时、分、秒显示,单片机对数据进行处理同时在液晶显示器上显示。
主控模块:本系统主控模块采用的单片机AT89C51,外接12MHz晶振。AT89C51具有40个引脚,128×8位内部RAM ,32可编程I/O线 ,两个16位定时器/计数器,5个中断源。可编程串行通道,低功耗的闲置和掉电模式, 片内振荡器和时钟电路也是其主要特性。 液晶显示模块:LCD1602采用标准的16脚接口,其中:
4
第1脚:GND为地电源
第2脚:VCC接5V正电源
第3脚:V0为液晶显示器对比度调整端,接正电源时对比度最弱,接地电源时对比最高,对比度过高时会产生“鬼影”,使用时可以通过一个10K的电位器调整对比度
第4脚:RS为寄存器选择,高电平时选择数据寄存器、低电平时选择指令寄存器。
第5脚:RW为读写信号线,高电平时进行读操作,低电平时进行写操作。当RSRW共同为低电平时可以写入指令或者显示地址,当RS为低电平RW为高电平时可读忙信号,当RS为高电平RW为低电平时可以写入数据.
第6脚:E端为使能端,当E端由高电平跳变成低电平时,液晶模块执行命令。
第7~14脚:DB0~DB7为8位双向数据线。
第15~16脚:空脚。
图2 仿真图
2.4电路功能使用说明
各个控制键的功能:功能切换选择键k1可选择进入万年历、闹钟、秒表、训练表功能; 进入万年历功能可以通过功能键k1选择调整年月日、星期以及时间(k3加、k4减); 进入闹钟功能可以通过k1调整闹钟定时;
进入秒表功能可以通过k2开始,k3存储,k2复位;
进入训练表可以通过k1设定时间(k3加,k4减),k2暂停计时。
5
AT89C51单片机,通过编写程序对lcd1602显示进行控制。
蜂鸣器用于闹钟声音提醒。
第三章 :软件总体设计方案
3.1软件的总体设计 系统是由AT89C51单片机控制,系统分为主函数部分和各模块子函数部分2个部分。系统主函数部分主要是调用各个模块的子函数。本系统的时间是通过软件进行设置,使用定时器使电子钟运行,并将值送入主控芯片,通过液晶显示器LCD1602来显示,时间、日期的修改通过按键来控制的。所以要对定时器、液晶显示器进行初始化。而其他模块的初始化在各模块函数中初始化。各模块的子函数包括LCD1602显示模块、DS18B20测温模块、时钟模块、按键扫描模块。闹钟设置模块包含在时钟模块和按键扫描模块中。
主程序
通过调用其他函数来实现系统的总体功能,其工作流程如下:
(1)系统启动后,进行定时器和LCD显示初始化。
(2)LCD1602显示日期、星期、时间。
(3)可以通过按键进行显示模式设置,调整日期、时间、还可以进行万年历查询,进行秒表、闹钟、训练表功能。
6
图3-1主程序流程图
液晶显示模块 于本系统是采用LCD1602显示的,系统的软件设计通过P0口输出数据,数据命令选择端P2.6,读写选择端是P2.5,使能信号选择端为P2.7。程序主要进行LCD1602的初始化设定,及根据时序图编写LCD1602的写指令、写字符函数。此外还需编写显示字符串函数等。 时钟函数 时钟函数包括年、月、日、时、分、秒、星期的计算方法。时间控制程序主要是定时器0计时中断程序每隔17ms中断一次当作一个计数,每中断一次则计数加1,当计数60次时,则表示1秒到了,秒变量加1,同理再判断是否1分钟到了,再判断是否1小时到了,再判断是否1天到了,再判断是否1月到了,再判断是否1年到了,若计数到了则相关变量清除0。
月份算法:先给出一般年份的每月天数。如果是闰年,第二个月天数不为28天,而是29天。星期算法:算出当前时间距20xx年1月1日(星期六)的天数,通过公式week=(6+sum%7)%7计算当前显示日期是星期几。
闰年的判断规则为,如果该年份是4或100的整数倍或者是400的整数倍,则为闰年;否则为非闰年。
当电子钟运行的时间与所设定的时间相同时,蜂鸣器响,直到过了设置时间后不响。
7
按键扫描函数
本系统的时间、日期设置、闹钟设置、万年历判断、秒表、训练表是通过个按键进行设置,分别为KEY_1、KEY_2、KEY_3、KEY_4、按键。系统启动后按KEY_1进入设置程序,对当前项进行设置,调整顺序依次为:年、月、日、时、分、秒。设置时时钟停止运行,按KEY_1对各个设置项进行切换,第7项为设置完成,时钟开始运行。KEY_3键为加1,KEY_4键为减1,KEY_1为模式选择按键,KEY_2为确定/复位按键,。
整体流程图:
8
3.2控制电路的C语言源程序
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
/* sbit lcden=P3^4;
sbit lcdrs=P3^5;
sbit lcdwr=P3^6;
sbit beep=P2^3;
sbit keyd=P3^7;
sbit key1=P3^0;
sbit key2=P3^1;
sbit key3=P3^2;
sbit key4=P3^3; */
sbit lcden=P1^2;
sbit lcdrs=P1^0;
sbit lcdwr=P1^1;
sbit beep=P1^3;
sbit key1=P2^0;
sbit key2=P2^1;
sbit key3=P2^2;
sbit key4=P2^3;
uchar num[]="0123456789";
uchar keyz=0;
uchar p3;
uchar t=0;
uchar menu=0;
uchar set=0,q=0;
uchar code pos[]={
0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f, 0xc0,0xc1,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xcb,0xcc,0xcd,0xce,0xcf };
uchar rsw[80]={0,0};
uchar sw[]={3,6,9,15,20,23,26};
uchar aw[]={3,6,11,14};
uchar w=0,wa=0,cd=3;
int rn=0,rnx=0;
int sec=55;
int min=59;
int hour=23;
uint day=29;
9
uchar mon=2;
int year=2012;
uchar week1[35]="Mon Tues Wed ThursFri Sar Sun ";
uchar menu_c[]="1.Setting2.Alarm3.Stopwatch ";
uchar menu_c1[]="1.Count Down ";
uchar week=2;
uchar stopwatch_flog=0,alarm_flog=0,alarm1=0,alarm2=0,bs=1,cd_flog=0,cd_flog1=0,cd_set=0; uchar mil=0,st_sec=0,st_min=0,st_hour=0;
uchar rs_mil=0,rs_sec=0,rs_min=0,rs_hour=0;
int d_hour=0,d_min=0,d_sec=0,d_mil=0;
int f_min=0,f_hour=0,s_min=0,s_hour=0;
void delay(uint z)
{uint x=0;
uint y=0;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void wcom(uchar com)
{ lcdrs=0;
P0=com;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
void wdate(uchar date)
{ lcdrs=1;
P0=date;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
void init()
{
lcden=0;
lcdwr=0;
wcom(0x38);
wcom(0x0c);
wcom(0x06);
wcom(0x01);
}
void xss(uint h)
{ if(h==1){
//液晶初始化 10
wcom(0x80+0x03);
wdate(num[year%10]); wcom(0x80+0x02);
wdate(num[(year%100)/10]); wcom(0x80+0x01);
wdate(num[(year%1000)/100]); wcom(0x80+0x00);
wdate(num[year/1000]); }
if(h==2){
wcom(0x80+0x06);
wdate(num[mon%10]); wcom(0x80+0x05);
wdate(num[mon/10]); }
if(h==3){
wcom(0x80+0x09);
wdate(num[day%10]); wcom(0x80+0x08);
wdate(num[day/10]); }
if(h==4){
wcom(0x80+0x0b);
wdate(week1[5*(week-1)]); wcom(0x80+0x0c);
wdate(week1[5*(week-1)+1]); wcom(0x80+0x0d);
wdate(week1[5*(week-1)+2]); wcom(0x80+0x0e);
wdate(week1[5*(week-1)+3]); }
if(h==5){
wcom(0x80+0x44);
wdate(num[hour%10]); wcom(0x80+0x43);
wdate(num[hour/10]);
}
if(h==6){
wcom(0x80+0x47);
wdate(num[min%10]); wcom(0x80+0x46);
wdate(num[min/10]);
11
}
if(h==7){
wcom(0x80+0x4a);
wdate(num[sec%10]);
wcom(0x80+0x49);
wdate(num[sec/10]);
}
} void be()
{
delay(50);
beep=!beep;
delay(50);
beep=!beep;
} void stopw(uchar y)
{ if(y==0)
{
TH0=(65536-10000)/256;
TL0=(65536-10000)%256;
ET0=1;
TR0=1;
}
if(y==1) ET0=0,TR0=0;
if(y==2) mil=0,st_sec=0,st_min=0,st_hour=0; }
void xs_menu(uchar z)
{ uchar l;
if(z==0)
{for(l=0;l<29;l++)
{wcom(pos[l]);
wdate(menu_c[l]);
}
}
if(z==1)
{
for(l=0;l<14;l++)
{wcom(pos[l]);
wdate(menu_c1[l]);
}
}
//时钟设置显示 //蜂鸣器 //秒表 12
} //显示菜单 void xs_rsw(uchar z)
{ wcom(0x80);
wdate(num[(z+1)/10]);
wcom(0x81);
wdate(num[(z+1)%10]);
wcom(0x82);
wdate('.');
wcom(0x83);
wdate(num[rsw[z*8+0]]);
wcom(0x84);
wdate(num[rsw[z*8+1]]);
wcom(0x86);
wdate(num[rsw[z*8+2]]);
wcom(0x87);
wdate(num[rsw[z*8+3]]);
wcom(0x89);
wdate(num[rsw[z*8+4]]);
wcom(0x8a);
wdate(num[rsw[z*8+5]]);
wcom(0x8c);
wdate(num[rsw[z*8+6]]);
wcom(0x8d);
wdate(num[rsw[z*8+7]]);
wcom(0x85);
wdate(':');
wcom(0x88);
wdate(':');
wcom(0x8b);
wdate(':');
} void xs_sw_cd(uint z)
{ uint a,b,c,d,e,f,g,h;
if(z==1)
{a=st_hour/10;
b=st_hour%10;
c=st_min/10;
d=st_min%10;
e=st_sec/10;
f=st_sec%10;
g=mil/10;
h=mil%10;
}
if(z==2)
//显示秒表记录 13
{a=d_hour/10;
b=d_hour%10;
c=d_min/10;
d=d_min%10;
e=d_sec/10;
f=d_sec%10;
g=d_mil/10;
h=d_mil%10;
}
wcom(0xc3);
wdate(num[a]); wcom(0xc4);
wdate(num[b]); wcom(0xc6);
wdate(num[c]); wcom(0xc7);
wdate(num[d]); wcom(0xc9);
wdate(num[e]); wcom(0xca);
wdate(num[f]); wcom(0xcc);
wdate(num[g]); wcom(0xcd);
wdate(num[h]); wcom(0xc5);
wdate(':');
wcom(0xc8);
wdate(':');
wcom(0xcb);
wdate(':');
}
void xsg_alarm(uchar z)
{ if(z==0)
{wcom(0x82);
wdate(num[f_hour/10]); wcom(0x83);
wdate(num[f_hour%10]); }
if(z==1)
{wcom(0x85);
wdate(num[f_min/10]); wcom(0x86);
wdate(num[f_min%10]); 14
}
if(z==2)
{wcom(0x8a);
wdate(num[s_hour/10]);
wcom(0x8b);
wdate(num[s_hour%10]);
}
if(z==3)
{wcom(0x8d);
wdate(num[s_min/10]);
wcom(0x8e);
wdate(num[s_min%10]);
}
}
void xs_alarm()
{ uchar i=0;
wcom(0x80);
wdate('1');
wcom(0x81);
wdate('.');
wcom(0x84);
wdate(':');
wcom(0x88);
wdate('2');
wcom(0x89);
wdate('.');
wcom(0x8c);
wdate(':');
for(i=0;i<4;i++)
xsg_alarm(i);
}
void count_down()
{
if(d_sec<0) d_sec=59,d_min--;
if(d_min<0) d_min=59,d_hour--;
if(d_hour==0&&d_min==0&&d_sec==0&&cd_set==0) { stopw(1),d_mil=0,be(),cd_flog=0,cd_flog1=0; wcom(0xc0);
wdate(' ');
}
}
void key()
{ uint p;
if(key1==0&&key2!=0)
15
{ if(menu==0)
{menu=1;
if(set==0&&alarm_flog==0&&stopwatch_flog==0) wcom(0x01),xs_menu(0); }
else
if(menu==1&&set==0&&alarm_flog==0&&stopwatch_flog==0)
menu=2,wcom(0x01),xs_menu(1);
else
{ menu=0,set=alarm_flog=stopwatch_flog=cd_flog=0,
stopw(0); rn=0;rnx=0;
wcom(0x01);
wcom(0x0c);
q=0;
if(cd_flog1==0) stopw(1);
for(p=0;p<80;p++) rsw[p]=0;
mil=st_sec=st_min=st_hour=0;
}
delay(250);
}
if(key2==0&&menu==1&&set==0&&alarm_flog==0&&stopwatch_flog==0) set=1,wcom(0x01),wcom(0x0f),delay(300);
if(key2==0&&menu==2) wcom(0x01),xs_sw_cd(2),cd_flog=1;
if(key2==0&&cd_flog==1&&menu==2)
{wcom(0x0f);
cd_set=1;
cd++;
if(cd==7) cd=3,stopw(0),count_down(),cd_set=0,wcom(0x0c),cd_flog1=1; delay(250);
}
if(key2==0&&set==1)
{w++;
if(w==7) w=0;
delay(300);
}
if(key2==0&&alarm_flog==1)
{wa++;
if(wa==4) wa=0;
delay(300);
}
if(key2==0&&stopwatch_flog==1&&alarm_flog==0&&set==0&&cd_flog==0) {stopw(q);
q++;
if(q==3) q=0;
xs_sw_cd(1);delay(300) ;
16
}
if(key3==0&&alarm_flog==0&&menu==1&&stopwatch_flog==0&&set==0) { alarm_flog=1,
wcom(0x01),
wcom(0x0f);
xs_alarm();
delay(250);
}
if(key3==0&&stopwatch_flog==1)
{
rsw[rn*8+6]=(mil/10),
rsw[rn*8+7]=(mil%10),
rsw[rn*8+4]=(st_sec/10), rsw[rn*8+5]=(st_sec%10),
rsw[rn*8+2]=(st_min/10), rsw[rn*8+3]=(st_min%10),
rsw[rn*8+0]=(st_hour/10), rsw[rn*8+1]=(st_hour%10);
xs_rsw(rn);rnx=0;
rn++;
if(rn==10) rn=0;
}
if(key3==0&&cd_set==1&&menu==2)
{ if(cd==4) d_hour++;
if(d_hour==100) d_hour=0;
if(cd==5) d_min++;
if(d_min==60) d_min=0;
if(cd==6) d_sec++;
if(d_sec==60) d_sec=0;
xs_sw_cd(2);
delay(200);
}
if(key3==0&&set==1)
{if(w==0)year++,xss(1);
if(year>9999)year=0,xss(1);
if(w==1)mon++,xss(2);
if(mon==13)mon=1,xss(2);
if(w==2)day++,xss(3);
if(day==31)day=0,xss(3);
if(w==3)week++,xss(4);
if(week==7)week=1,xss(4);
if(w==4)hour++,xss(5);
if(hour==24)hour=0,xss(5);
if(w==5)min++,xss(6);
17
if(min==60)min=0,xss(6);
if(w==6)sec++,xss(7);
if(sec==60)sec=0,xss(7);
delay(250);
}
if(key3==0&&alarm_flog==1)
{ if(wa==0)
{ f_hour++;
if(f_hour==24) f_hour=0;
xsg_alarm(0);
}
if(wa==1)
{ f_min++;
if(f_min==60) f_min=0;
xsg_alarm(1);
}
if(wa==2)
{ s_hour++;
if(s_hour==24) s_hour=0;
xsg_alarm(2);
}
if(wa==3)
{ s_min++;
if(s_min==60) s_min=0;
xsg_alarm(3);
}
delay(250);
}
if(key4==0&&menu==1&&set==0&&alarm_flog==0&&stopwatch_flog==0) stopwatch_flog=1,wcom(0x01),xs_sw_cd(1),stopw(1),delay(300); if(key4==0&&set==1)
{if(w==0)year--,xss(1);
if(year<0)year=9999,xss(1);
if(w==1)mon--,xss(2);
if(mon==0)mon=12,xss(2);
if(w==2)day--,xss(3);
if(day==0)day=31,xss(3);
if(w==3)week--,xss(4);
if(week==0)week=7,xss(4);
if(w==4)hour--,xss(5);
if(hour<0)hour=23,xss(5);
if(w==5)min--,xss(6);
if(min<0)min=59,xss(6);
if(w==6)sec--,xss(7);
18
if(sec<0)sec=59,xss(7);
delay(250);
}
if(key4==0&&alarm_flog==1)
{ if(wa==0)
{ f_hour--;
if(f_hour<0) f_hour=23;
xsg_alarm(0);
}
if(wa==1)
{ f_min--;
if(f_min<0) f_min=59;
xsg_alarm(1);
}
if(wa==2)
{ s_hour--;
if(s_hour<0) s_hour=23;
xsg_alarm(2);
}
if(wa==3)
{ s_min--;
if(s_min<0) s_min=59;
xsg_alarm(3);
}
}
if(key4==0&&stopwatch_flog==1)
{ xs_rsw(rnx);
rnx++;
if(rnx==rn) rnx=0;
delay(200);
}
if(key4==0&&cd_set==1&&menu==2)
{if(cd==4) d_hour--;
if(d_hour<0) d_hour=99;
if(cd==5) d_min--;
if(d_min<0) d_min=59;
if(cd==6) d_sec--;
if(d_sec<0) d_sec=59;
xs_sw_cd(2);
delay(200);
}
// if(key3==0&&key4==0&&stopwatch_flog==1) // mil=0,st_sec=0,st_min=0,st_hour=0,delay(200); if(key1==0&&key2==0&&menu==0)
19
{if(bs==0) bs=1,be();
else bs=0,be();
delay(200);
}
if(key2==0&&key3==0&&menu==0)
{ if(alarm1==1) alarm1=0;
else alarm1=1;
be();
delay(200);
}
if(key3==0&&key4==0&&menu==0)
{ if(alarm2==1) alarm2=0;
else alarm2=1;
be();
delay(200);
}
} //按键功能 void xs()
{ uchar i=0;
if(min==60)
{ min=0;
if(set==0)hour++;
}
if(hour==24)
{ hour=0;
if(set==0)
day++,week++;
}
if(week==8) week=1;
if((mon==1||mon==3||mon==5||mon==7||mon==8||mon==10||mon==12)&&day==32) { day=1;if(set==0)mon++;
}
if((mon==4||mon==6||mon==9||mon==11)&&day==31)
{ day=1;if(set==0)mon++;}
if(year%4!=0&&mon==2&&day==29)
{ day=1;if(set==0)mon++;}
if(year%4==0&&mon==2&&day==30)
{ day=1;if(set==0)mon++;}
if(mon==13)
{mon=1;
if(set==0)year++;
}
if(stopwatch_flog==1)
20
{ wcom(0xcc);
wdate(num[mil/10]); wcom(0xcd);
wdate(num[mil%10]); wcom(0xc9);
wdate(num[st_sec/10]); wcom(0xca);
wdate(num[st_sec%10]); if(st_sec==60)
{st_sec=0,st_min++; wcom(0xc6);
wdate(num[st_min/10]); wcom(0xc7);
wdate(num[st_min%10]); }
if(st_min==60)
{ st_min==0,st_hour++; wcom(0xc3);
wdate(num[st_hour/10]); wcom(0xc4);
wdate(num[st_hour%10]); }
}
if(cd_flog1==1)count_down(); if(cd_flog1==1&&menu==0) {wcom(0xc0);
wdate('~');
}
if(cd_flog==1&&cd_set==0) {
wcom(0xcc);
wdate(num[d_mil/10]); wcom(0xcd);
wdate(num[d_mil%10]); wcom(0xc9);
wdate(num[d_sec/10]); wcom(0xca);
wdate(num[d_sec%10]); if(d_sec<0)
{d_sec=59,d_min--; wcom(0xc6);
wdate(num[d_min/10]); wcom(0xc7);
21
wdate(num[d_min%10]);
}
if(d_min<0)
{ d_min==59,d_hour--;
wcom(0xc3);
wdate(num[d_hour/10]);
wcom(0xc4);
wdate(num[d_hour%10]);
}
}
if(bs==0)
{if(min==59&&sec>=59&&set==0)be(); if(min==0&&sec==0&&set==0)be();
if(min==0&&sec==1&&set==0)be();
if(min==0&&sec==2&&set==0)be();
if(min==0&&sec==3&&set==0)be();
}
if(t==10&&(menu==0||set==1)){
for(i=0;i<8;i++) xss(i);
if(alarm1==1)
{wcom(0xcc);
wdate(0xf4);}
else {wcom(0xcc);
wdate(' ');}
if(alarm2==1)
{wcom(0xcd);
wdate(0xf4);}
else {wcom(0xcd);
wdate(' ');} wcom(0x80+0x48);
wdate(':');
wcom(0x80+0x45);
wdate(':');
wcom(0x80+0x04);
wdate('-');
wcom(0x80+0x07);
wdate('-');
wcom(0x80+0x4f);
wdate(' ');
}
if(t==1&&menu==1&&set==1) wcom(pos[sw[w]]);
if(t==18&&menu==1&&alarm_flog==1) wcom(pos[aw[wa]]);
if(t==2&&menu==2&&cd_flog==1&&cd_set==1) wcom(pos[sw[cd]]); 22
if(alarm1==1&&f_hour==hour&&f_min==min) be(); if(alarm2==1&&s_hour==hour&&s_min==min) be(); if(t==4&&bs==0&&menu==0)
{ wcom(0xcf);
wdate('~');
}
if(t==4&&bs==1) {wcom(0xcf);
wdate(' ');}
}
void main()
{ init();
TMOD=0x11;
EA=1;
TH1=(65536-50000)/256;
TL1=(65536-50000)%256;
ET1=1;
TR1=1; //keyd=0;
key1=key2=key3=key4=1;
while(1)
{ key();
xs();
}
}
void time0(void) interrupt 3
{
t++;
if(t==20)
{t=0,sec++;
if(sec==60) sec=0,min++;}
TH1=(65536-50000)/256;
//显示 //基准时钟23
TL1=(65536-50000)%256;
ET1=1;
TR1=1;
}
void stopwatch(void) interrupt 1
{ if(cd_flog1==1)d_mil--;
if(d_mil<0)
{ d_mil=99,d_sec--;
}
if(stopwatch_flog==1)mil++;
if(mil==100)
{ mil=0,st_sec++;
}
TH0=(65536-10000)/256;
TL0=(65536-10000)%256;
ET0=1;
TR0=1;
} //时钟 //秒表
第四章 : 实验设计结果分析 此时钟设计是利用protues仿真软件进行仿真,基本上实现了设计要求实现的功能。
硬件部分设置了的4个按键。当按键1按下时,进入模式选择显示状态,按键2、3、4分别是万年历、闹钟、秒表功能,再按1,2选择选训练表功能。
万年历可以通过按键1选择日期,3、4加减查询。
秒表功能、闹钟、训练表功能均正常。
调试阶段,出现一些问题。有时按键会出现空操作、2月28不能锁存。
另外,闹铃电路有音乐闹钟的扩展的功能(可以将蜂鸣器换成扬声器再加一段音乐程序即可实现)。但时间有限,部分扩展功能不能及时实现。
24
第五章 :总结 几经波折的单片机综合实验设计,已基本完成课题要求。功能上基本达标:万年历时钟的显示,秒表显示,闹钟功能,训练表功能。时钟显示功能,精确度完全可以满足日常生活显示时间的需要;秒表功能,可以满足比赛计时的需要;训练表功能,方便快捷;闹钟功能准确可靠,还有扩展成音乐闹钟的余地。硬件设施合乎要求,软件设计可以配合硬件实现要求功能。但是由于自身素质所限,出现部分不足:2月份日期未能正常显示。经老师、同学讨论交流是软件部分还不完善。
以前看别人的一个电子表卖十几块钱,心里面有点愤愤不平,现在,自己做过一个万年历,才发现,其中的不容易,还有艰辛。其实做其他的事情也是一样,都会经过很多的困难,才能成功。正如“不经历风雨,怎么见彩虹”。
其实想想,这段时间,也留下了很多美好的回忆。
还记得那天废寝忘食打孔和焊板,还记得显示屏终于亮起来那一刻的激动。
通过这次实验设计让我真正体会到了,有付出,才会有收获。
另外,在本次设计的过程中,发现单片机设计重点就在于软件算法的设计,需要有很巧妙的程序算法,虽然以前写过几次程序,但我们觉的写好一个程序并不是一件简单的事,比如写一个程序看其功能很少认为编写程序简单,但到编的时候才发现一些细微的知识或低级错误经常犯做不到最后常常失败,所以有些东西只有学精弄懂并且要细心才行,只学习理论有些东西是很难理解的,更谈不上掌握。
第六章: 问题解决
2月日期不能正常显示问题,试解决方案,将第9页中红色部分改为:
uint day=29;
uchar mon=2; int year=2012;
-------------------------------------------------------------------------------
{
case 1:case 3:case 5:case 7:case 8:case 10:case 12:
if(day==0) day=31; break; { if(day==0) day=29; } case 2: if(year%4==0||year%400==0) else { 25
if(day==0) day=28; }break;
case 4:case 6:case 9:case 11: if(day==0) day=30; break;
}
[1]张毅刚 单片机原理及应用 高等教育出版社
[2]丁峻岭 C语言程序设计.中国铁道出版社
26