1.基本要求
要求用DS1302设计单片机作息时间控制器,实现以下功能:
1.基本功能
①实时显示当前时间(数码管显示小时.分钟,小数点闪烁作为秒提示);
②能修改当前时钟;
③根据作息时间按时打铃;
④可以修改作息时间。
2. 扩展功能
自行扩展功能,如秒表,音乐铃声,通讯功能等。
2 方案设计
2.1 系统分析
根据系统功能要求,可将系统组成结构分成四大部分:单片机控制中心、键盘接口、时钟显示和声音报时,如下图为系统的组成结构图。其中,单片机控制中心是核心。MCU根据按键输入,可切换不同的显示模式或设置不同的参数。时钟显示完成北京时间或秒表时钟的信息。声音报时可完成闹铃的提示。
2.2 器件选择
2.2.1微处理器
市场上微处理器种类很多。这里,选取微处理器从多方面考:成本低、性能高、能够满足功能要求等等。
这里,选取STC89C51芯片。因为其功能与普通51芯片相同,其价格非常低廉、程序空间大、资源较丰富、在线下载非常方便。同时,使用该芯片,编程上亦可采用所熟悉的KEIL软件,使课程设计非常简单。
2.2.2显示器
常见的显示器件LED数码管和LCD液晶器件。
LED数码管能够显示数字和部分字符,价格便宜,硬件电路、软件编程均非常简单,而且使用动态扫描技术可节省大量硬件成本。
LCD液晶显示器件,显示字迹清晰、能够显示数字、字符和汉字,但价格比LED非常高,编程复杂,软硬件调试都比较花时间。
系统显示主要还是数字,根据这两种显示器件的特性,选取LED数码管器件。由于系统要求显示小时和分钟,采用四位数码管显示即可。
2.2.3按键
按键是用来设置北京时间或闹钟时间或启动秒表等功能的。这里采用普通按键即可,选用原则:以最少的按键,实现尽可能多的功能。所以这里,设置三个按键:模式键、UP键、DOWN键。
2.2.4闹铃
选用最常见,亦最常用的声音提示方式——蜂鸣器。
3、软件设计
3.1 操作功能设计
根据系统功能描述,可以将功能大致分成三类:北京时间功能、闹铃功能、秒表功能。
系统设有四个数码管,三个按键。采用菜单式人机对话,便于操作。所以可分成多种菜单,功能键切换菜单,UP或DOWN键设置时间。
菜单设计如下:
菜单1:北京显示:显示格式为:小时.分钟(如:09.50,为9点50分)
菜单2:修改北京时间的小时:显示格式为:00.小时(如00.14,为北京时间的小时设为14点)
菜单3:修改北京时间的分钟:显示格式为:00.分钟(如00.34,为北京时间的分钟设为34分)
菜单4:修改闹铃时间的小时:显示格式为:00.小时(如00.14,为闹铃时间的小时设为14点)
菜单5:修改闹铃时间的分钟:显示格式为:00.分钟(如00.34,为闹铃时间分钟设为34分)
菜单6:秒表功能:显示格式为:秒百分秒(如1290为当前秒表计时到12秒900毫秒),在此种菜单下,UP键设为用来启动/停止秒表、DOWN键设为用来暂停秒表。
程序参考清单
#include<reg52.h>
#define uchar unsigned char;
#define uint unsigned int;
//四盏灯
sbit P13 = P1^3;
sbit P35 = P3^5;
sbit P36 = P3^6;
sbit P37 = P3^7;
//beep
sbit beep = P1^1;
uchar position;
uchar tt;
static uchar second;
static uchar minute;
static uchar hour;
static uchar set_second;
static uchar set_minute;
static uchar set_hour;
static uchar t_mode;
//-----------------秒表-------------------------------------
void XS(int xs,int xm);
void set_miaobiao();
int n=0,m=0,s=0;
static char d1,d2,d3,d4;
//-------------------------------------------------------
uchar code table[]=
{0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//0--9
uchar beepTimes[23][2]=
{{6,50},{7,0},{7,25},{8,20},{8,30},{9,15},{9,25},{10,10},{10,30},{11,15},{11,25},{12,10},{13,20},{13,30},{14,15},{14,25},{15,10},{16,30},{17,0},{17,50},{18,0},{21,30},{23,0}};
sbit smg_q = P2^4;
sbit smg_b = P2^5;
sbit smg_s = P2^6;
sbit smg_g = P2^7;
sbit mode=P2^0; //按键定义
sbit up=P2^1;
sbit down=P2^2;
sbit ent=P3^2;
//函数声明
void keyscan();
void setMinutes() ;
void setHours();
void display(unsigned char hour,unsigned char minute);
void delay(unsigned int timer);
void init();
void dongtaiTime();
void N_clock();
void MyClock();
void set_clock_m();
void set_clock_h();
void nao();
void setBeepTime();
void setClock();
/***********************************************************
主函数
***********************************************************/
void main()
{
init();
while(1)
{
dongtaiTime();
if(mode==0)
{
delay(1);
if(mode==0)
{
t_mode++;
while(!mode);
if(t_mode>5)
t_mode=0;
}
}
switch(t_mode)
{
case 0: TR1=0;TR0=1; dongtaiTime(); display(hour,minute); N_clock(); nao(); P3=0xff; P13=1; break;
case 1: TR1=0;TR0=1;display(hour,minute);setHours(); P13=0; beep=1; break;
case 2: TR1=0;TR0=1;display(hour,minute);setMinutes(); P13=1; P35=0; beep=1; break;
case 3: TR1=0;TR0=1;setClock(); P13=0; P35=0;beep=1; break;
case 4: TR1=0;TR0=1;set_clock_m(); display(set_hour,set_minute); P13=1; P35=1;P36=0; beep=1; break;
case 5: TR0=1;XS(m,s); set_miaobiao(); P13=0; P35=1; P36=0;beep=1; break;
}
delay(1);
}
}
/***********************************************************
闹钟
***********************************************************/
void N_clock()
{
static unsigned int i;
for(i=0;i<23;i++)
{
if(hour==beepTimes[i][0] && minute==beepTimes[i][1])
{
beep=0;
delay(1);
} else {
beep=1;
}
}
}
void setClock()
{
display(set_hour,set_minute);
set_clock_h();
}
void nao()
{
//响
if(set_hour==hour && set_minute==minute)
{
beep=0;
}else{
beep=1;
}
}
void set_clock_m()
{
if(up==0)
{
TR0=0;
set_minute++;
if(set_minute==60)
set_minute=0;
delay(200);
TR0=1;
}
if(down==0)
{
TR0=0;
set_minute--;
if(set_minute<0)
set_minute=59;
delay(200);
TR0=1;
}
}
void set_clock_h()
{
if(up==0)
{
TR0=0;
set_hour++;
if(set_hour==24)
set_hour=0;
delay(200);
TR0=1;
}
if(down==0)
{
TR0=0;
set_hour--;
if(set_hour<0)
set_hour=23;
delay(200);
TR0=1;
}
}
/***********************************************************
显示时间
***********************************************************/
void dongtaiTime()
{
if(tt==20)
{tt=0;
second++;
if(second==60)
{
second=0;
minute++;
if(minute==60)
{
minute=0;
hour++;
if(hour==24)
hour=0;
}
}
}
}
/***********************************************************
调时
***********************************************************/
void setHours()
{
if(up==0)
{
TR0=0;
hour++;
if(hour==24)
hour=0;
delay(200);
TR0=1;
}
if(down==0)
{
TR0=0;
hour--;
if(hour<0)
hour=23;
delay(200);
TR0=1;
}
}
void setMinutes()
{
if(up==0)
{
TR0=0;
minute++;
if(minute==60)
minute=0;
delay(200);
TR0=1;
}
if(down==0)
{
TR0=0;
minute--;
if(minute<0)
minute=59;
delay(200);
TR0=1;
}
}
/***********************************************************
初始化
***********************************************************/
void init()
{
hour= 9; minute =22; second =58;
tt=0;
t_mode=0;
position=0;
smg_q=1;
smg_b=1;
smg_s=1;
smg_g=1;
mode=1;
up=1;
set_second=0;
set_minute=0;
set_hour=0;
TMOD=0X11;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
TH1=(65536-10000)/256;
TL1=(65536-10000)%256;
EA=1;
ET0=1;
ET1=1;
TR0=1;
TR1=0; //不能开启
}
/***********************************************************
显示
***********************************************************/
void display(unsigned char hour,unsigned char minute)
{
P0=0xFF;
switch(position)
{
case 0:
smg_g=1;
smg_q=0;
P0=table[hour/10];
delay(3);
smg_q=1;
break;
case 1:
smg_q=1;
smg_b=0;
P0=table[hour%10];
if(tt>=10)
P0|=0x80;//小数点以半秒的时间闪烁
delay(3);
smg_b=1;
break;
case 2:
smg_b=1;
smg_s=0;
P0=table[minute/10];
delay(3);
smg_s=1;
break;
case 3:
smg_s=1;
smg_g=0;
P0=table[minute%10];
delay(3);
smg_g=1;
break;
}
position++;
if(position>3)
position=0;
}
/***********************************************************
延时
***********************************************************/
void delay(unsigned int time)
{
unsigned int x,y;
for(x=time;x>0;x--)
for(y=105;y>0;y--);
}
/***********************************************************
定时器TO中断
***********************************************************/
void t0() interrupt 1
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
tt++;
}
/***********************************************************
定时器T1中断
***********************************************************/
void int1() interrupt 3 //?????
{
TH1=(65536-10000)/256; TL1=(65536-10000)%256;
m++;
if(m==100)
{
m=0;
s++;
if(s==100)
{
s=0;
}}}
void XS(int xs,int xm )//?????
{
d1=(xs/1)%10; d2=(xs/10)%10; d3=(xm/1)%10; d4=(xm/10)%10;
P0=table[d1]; smg_g=0; delay(1);smg_g=1;
P0=table[d2]; smg_s=0; delay(1); smg_s=1;
P0=table[d3]|0x80; smg_b=0; delay(1);smg_b=1;
P0=table[d4]; smg_q=0; delay(1);smg_q=1;
}
void set_miaobiao()
{
if(up==0)
{
delay(1);
if(up==0)
{
TR1=~TR1;
while(!up);
}
}
if(down==0)
{
delay(1);
if(down==0)
{
TR1=0;
m=0;s=0;
while(!down);
}
}
}