?? 51mcu.txt
字號:
51單片機(jī)電子日歷課程設(shè)計
程序代碼:
/****************************************************************************/
/* 電子日歷,有時間顯示、鬧鈴、日期、秒表及鍵盤設(shè)置功能 */
/* 功能鍵A: 設(shè)置位數(shù)字+1 鬧鐘模式下為鬧鐘開關(guān) 秒表模式下為記時開關(guān) */
/* 功能鍵B: 設(shè)置位數(shù)字-1 鬧鐘模式下為鬧鐘開關(guān) */
/* 功能鍵C:設(shè)置模式及設(shè)置位選擇 秒表模式下為清零鍵 */
/* 功能鍵D:在四種工作模式下切換 設(shè)置鬧鐘開關(guān) */
/* 曹宇 03電子 0201029 */
/* 2006.6.3 更新 */
/****************************************************************************/
#include
#include
/***************這里設(shè)置程序初始化時顯示的時間****************/
#define SET_HOUR 12 /*設(shè)置初始化小時*/
#define SET_MINUTE 00 /*設(shè)置初始化分鐘*/
#define SET_SECOND 00 /*設(shè)置初始化秒數(shù)*/
/*************************系統(tǒng)地址****************************/
#define BASE_PORT 0x8000 /*選通基地址*/
#define KEY_LINE BASE_PORT+1 /*鍵盤行線地址*/
#define KEY_COLUMN BASE_PORT+2 /*鍵盤列線地址*/
#define LED_SEG BASE_PORT+4 /*數(shù)碼管段選地址*/
#define LED_BIT BASE_PORT+2 /*數(shù)碼管位選地址*/
#define LED_ON(x) XBYTE[LED_BIT]=(0x01<#define LED_OFF XBYTE[LED_SEG]=0x00 /*LED顯示空*/
/**************在設(shè)置模式下對秒分時的宏定義*****************/
#define SECOND 0 /*對應(yīng)數(shù)碼管右邊兩位*/
#define MINUTE 1 /*對應(yīng)數(shù)碼管中間兩位*/
#define HOUR 2 /*對應(yīng)數(shù)碼管左邊兩位*/
/********************定義四種工作模式***********************/
#define CLOCK clockstr /*時鐘模式*/
#define ALART alartstr /*鬧鐘模式*/
#define DATE datestr /*日期模式*/
#define TIMER timerstr /*秒表模式*/
/****************以下是所有子函數(shù)的聲明*********************/
void sys_init(void); /*系統(tǒng)的初始化程序*/
void display(void); /*動態(tài)刷新一次數(shù)碼管子程序*/
void clockplus(void); /*時間加1S的子程序*/
void update_clockstr(void); /*更新時間顯示編碼*/
void update_alartstr(void); /*更新鬧鐘時間的顯示編碼*/
void update_datestr(void); /*更新日期顯示編碼*/
void update_timerstr(void); /*更新秒表時間的顯示編碼*/
void deley(int); /*延時子程序*/
void update_dispbuf(unsigned char *); /*更新顯示緩沖區(qū)*/
unsigned char getkeycode(void); /*獲取鍵值子程序*/
void keyprocess(unsigned char); /*鍵值處理子程序*/
unsigned char getmonthdays(unsigned int,unsigned char);/*計算某月的天數(shù)子程序*/
/*功能鍵功能子函數(shù)*/
void Akey(void); /*當(dāng)前設(shè)置位+1 開關(guān)鬧鐘 開關(guān)秒表*/
void Bkey(void); /*當(dāng)前設(shè)置位-1 開關(guān)鬧鐘 */
void Ckey(void); /*設(shè)置位選擇 秒表清零*/
void Dkey(void); /*切換四種工作模式*/
/**********************全局變量聲明部分*********************/
unsigned char led[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};/*從0~9的LED編碼*/
unsigned char ledchar[3]={0x5c,0x54,0x71};/*o n f*/
//unsigned char key[24]={ /* 鍵值代碼數(shù)組 對應(yīng)鍵位:*/
// 0x70,0x71,0x72,0x73,0x74,0x75, /* 7 8 9 A TRACE RESET*/
// 0xb0,0xb1,0xb2,0xb3,0xb4,0xb5, /* 4 5 6 B STEP MON */
// 0xd0,0xd1,0xd2,0xd3,0xd4,0xd5, /* 1 2 3 C HERE LAST */
// 0xe0,0xe1,0xe2,0xe3,0xe4,0xe5}; /* 0 F E D EXEC NEXT */
struct{ /*時間結(jié)構(gòu)體變量*/
unsigned char s;
unsigned char m;
unsigned char h;
}clock={SET_SECOND,SET_MINUTE,SET_HOUR};
struct{ /*鬧鈴時間結(jié)構(gòu)體變量*/
unsigned char m;
unsigned char h;
}alart={SET_MINUTE,SET_HOUR};
struct{ /*日期結(jié)構(gòu)體變量*/
unsigned int year;
unsigned char month;
unsigned char day;
}date={6,1,1};
struct{ /*秒表時間結(jié)構(gòu)體變量*/
unsigned char ms;
unsigned char s;
unsigned char m;
}timer={0,0,0};
unsigned char dispbuf[6]; /*顯示緩沖區(qū)數(shù)組*/
unsigned char clockstr[6]; /*時間顯示的數(shù)碼管編碼數(shù)組*/
unsigned char alartstr[6]; /*鬧鐘顯示的數(shù)碼管編碼數(shù)組*/
unsigned char datestr[6]; /*日期顯示的數(shù)碼管編碼數(shù)組*/
unsigned char timerstr[6]; /*秒表顯示的數(shù)碼管編碼數(shù)組*/
unsigned int itime=0,idot; /*定時器0中斷計數(shù)*/
unsigned char itime1=0; /*定時器1中斷計數(shù)*/
sbit P3_1=P3^1; /*外接蜂鳴器的管腳*/
bdata bit IsSet=0; /*設(shè)置模式標(biāo)志位 0:正常走時 1:設(shè)置模式*/
bdata bit Alart_EN=0; /*鬧鈴功能允許位 0:禁止鬧鈴 1:允許鬧鈴*/
bdata bit IsBeep=0; /*響鈴標(biāo)志位 0:未響鈴 1:正在響鈴*/
unsigned char SetSelect=0; /*在設(shè)置模式IsSet=1時,正在被設(shè)置的位,對應(yīng)上面的宏*/
unsigned char *CurrentMode; /*標(biāo)志當(dāng)前正設(shè)置的功能,如CurrentMode=CLOCK或CurrentMode=ALART等*/
void timerplus(void);
/**************************函數(shù)部分*************************/
void main(void)
{
sys_init();
while(1)
{
XBYTE[KEY_COLUMN,0x00]; /*給鍵盤列線賦全零掃描碼,判斷是否有鍵按下 */
while((XBYTE[KEY_LINE]&0x0f)==0x0f) /*檢測是否有鍵按下,無則一直進(jìn)行LED的刷新顯示*/
{
if(Alart_EN&&(clock.h==alart.h)&&(clock.m==alart.m)) {IsBeep=1;}
else
{ IsBeep=0;
P3_1=0;}
display();
}
keyprocess(getkeycode()); /*有鍵按下時得到鍵值,并送入鍵值處理程序*/
display(); /*可要可不要*/
}
}
void sys_init(void)
{
TMOD=0x22; /*定時器0和1都設(shè)置為工作方式2,基準(zhǔn)定時250×2=500us=0.5ms*/
TH0=6; /*定時器0中斷服務(wù)用來產(chǎn)生1秒時鐘定時及鬧鐘蜂鳴器蜂鳴脈沖*/
TL0=6; /*定時器1中斷服務(wù)留給秒表使用,產(chǎn)生1/100秒定時*/
TH1=6;
TL1=6;
ET0=1;
ET1=1;
EA=1;
TR0=1;
update_clockstr(); /*初始化時鐘顯示編碼數(shù)組*/
update_alartstr(); /*初始化鬧鐘顯示編碼數(shù)組*/
update_datestr(); /*初始化日期顯示編碼數(shù)組*/
update_timerstr(); /*初始化秒表顯示編碼數(shù)組*/
update_dispbuf(clockstr);/*初始化顯示緩沖數(shù)組*/
CurrentMode=CLOCK; /*默認(rèn)的顯示摸式為時鐘*/
P3_1=0; /*蜂鳴器接線引腳復(fù)位*/
}
void timer0(void) interrupt 1 using 1 /*定時器0中斷服務(wù)器,用來產(chǎn)生1秒定時*/
{
itime++;
if(itime==1000)
{
if(IsSet) /*在設(shè)置模式下,對正在設(shè)置的位閃爍顯示*/
{
dispbuf[SetSelect*2]=0; /*對正在設(shè)置的位所對應(yīng)的顯示緩沖區(qū)元素賦0,使LED滅*/
dispbuf[SetSelect*2+1]=0;
}
if(IsBeep) P3_1=!P3_1; /*鬧鐘模式時,產(chǎn)生峰鳴器響脈沖*/
if(CurrentMode==CLOCK)
{
dispbuf[2]=dispbuf[2]&0x7f;
dispbuf[4]=dispbuf[4]&0x7f;
}
}
if(itime==2000) /*兩千次計數(shù)為1S 2000×0.5ms=1s*/
{
itime=0; /*定時1s時間到,軟計數(shù)清零*/
clockplus(); /*時間結(jié)構(gòu)體變量秒數(shù)加1 */
update_clockstr(); /* 更新時間顯示編碼數(shù)組 */
if(CurrentMode!=TIMER) update_dispbuf(CurrentMode); /* 用時間編碼數(shù)組更新顯示緩沖區(qū) */
}
}
void timer1(void) interrupt 3 using 2 /*定時器1中斷服務(wù)器,用來產(chǎn)生1/100秒定時*/
{
idot++;
if(++itime1==20) /*20*0.5ms=10ms*/
{
itime1=0;
timerplus();
update_timerstr();
if(CurrentMode==TIMER)
{
update_dispbuf(timerstr);
dispbuf[2]=dispbuf[2]&0x7f; /*關(guān)閉小數(shù)點的顯示*/
dispbuf[4]=dispbuf[4]&0x7f;
if(idot<1000) /*閃爍顯示小數(shù)點*/
{
dispbuf[2]=dispbuf[2]|0x80;
dispbuf[4]=dispbuf[4]|0x80;
}else{
dispbuf[2]=dispbuf[2]&0x7f;
dispbuf[4]=dispbuf[4]&0x7f;
}
}
}
if(idot==2000) idot=0;
}
/*功能模塊子函數(shù)*/
void clockplus(void) /*時間加1s判斷分,時子函數(shù)*/
{
if(++clock.s==60) /*秒位判斷*/
{
clock.s=0;
if(++clock.m==60) /*分位判斷*/
{
clock.m=0;
if(++clock.h==24) /*時位判斷*/
{
clock.h=0;
if(++date.day==(getmonthdays(date.year,date.month)+1))
{
date.day=1;
if(++date.month==13) date.month=1;
}
}
}
}
}
void timerplus() /*秒表1/100秒位加1,判斷秒、分子程序*/
{
if(++timer.ms==100)
{
timer.ms=0;
if(++timer.s==60)
{
timer.s=0;
if(++timer.m==60)
{
timer.m=0;
}
}
}
}
void update_clockstr(void) /*更新時鐘顯示代碼數(shù)組clockstr*/
{
clockstr[0]=led[clock.s%10]; /*給元素0賦相應(yīng)數(shù)碼管顯示編碼,編碼序號是秒數(shù)的個位*/
clockstr[1]=led[(int)(clock.s/10)]; /*給元素1賦相應(yīng)數(shù)碼管顯示編碼,編碼序號是秒數(shù)的十位*/
clockstr[2]=led[clock.m%10]; /*以下類推*/
clockstr[3]=led[(int)(clock.m/10)];
clockstr[4]=led[clock.h%10];
clockstr[5]=led[(int)(clock.h/10)];
}
void update_alartstr(void) /*更新鬧鐘顯示代碼數(shù)組alartstr*/
{ /*右邊兩位顯示on:鬧鐘開啟 of:鬧鐘關(guān)閉*/
if(Alart_EN) alartstr[0]=ledchar[1];/*顯示字母n*/
else alartstr[0]=ledchar[2]; /*顯示字母f*/
alartstr[1]=ledchar[0]; /*顯示字母o*/
alartstr[2]=led[alart.m%10];
alartstr[3]=led[(int)(alart.m/10)];
alartstr[4]=led[alart.h%10];
alartstr[5]=led[(int)(alart.h/10)];
}
void update_datestr(void) /*更新日期顯示代碼數(shù)組datestr*/
{
datestr[0]=led[date.day%10];
datestr[1]=led[(int)(date.day/10)];
datestr[2]=led[date.month%10];
datestr[3]=led[(int)(date.month/10)];
datestr[4]=led[date.year%10];
datestr[5]=led[(int)(date.year/10)];
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -