可程式設計作息時間控制器設計
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);
}
}
}
#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;//beepsbit 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--9uchar 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);}}}