|
給51黑電子論壇的朋友們分享一個(gè)帶鬧鐘 帶紅外遙控的大數(shù)字時(shí)鐘程序:
單片機(jī)大數(shù)字lcd12864時(shí)鐘的主程序:
- /*---------------------------------------------------------------------------
- 黃歷電子智能時(shí)鐘程序
- 單 片 機(jī):STC89C52RC
- 晶 振:12MHz
- 時(shí)鐘芯片:DS1302
- 液 晶 屏:LCM-12864-ST7920
- 功能描述: 大數(shù)字顯示時(shí)間;能顯示農(nóng)歷、溫度和設(shè)置鬧鈴;有整點(diǎn)報(bào)時(shí)功能
- 紅外遙控和按鍵都能設(shè)置時(shí)間和鬧鈴
- 時(shí) 間:2月2日修改完成,今天大年三十,算是給自己的禮物吧!呵呵...
- 說(shuō) 明:LCM12864使用并口連接方式,PSB、RST接高電平
- 修改日志:
- ------------------------------------------------------------------------------*/
- /*-------------------------------頭文件---------------------------------------*/
- #include <reg52.h>
- #include <intrins.h>
- #include "LCD12864.h"
- #include "DS1302.h"
- #include "DS18B20.h"
- #include "nongli.h"
- #include "displaytime.h"
- #include "zk.h"
- #include "bell.h"
- #include "HW.H"
- #include "delay.h"
- #define uint unsigned int
- #define uchar unsigned char
- /*--------------------定義按鍵-----------------------------------------------*/
- sbit K1 = P1^0; //K1-設(shè)置
- sbit K2 = P1^1; //K2-確認(rèn)、返回
- sbit K3 = P1^2; //K3-加
- sbit K4 = P1^3; //K4-減
- //K5=P1^4,K5-控制鬧鐘的打開(kāi)與關(guān)閉,在"hw.h"中定義
- /*---------------------函數(shù)聲明------------------------------*/
- void ds_w0(void);
- void ds_w(void);
- void Conver_week(bit c,uchar year,uchar month,uchar day);
- /*-----------------------------定義全局變量------------------------------*/
- bit w=0; //調(diào)時(shí)標(biāo)志位
- unsigned char yy,mo,dd,xq,hh,mm,ss,month_moon,day_moon,week,tiangan,dizhi,moontemp1,moontemp2;//定義時(shí)間映射全局變量(專(zhuān)用寄存器)
- signed char address,item,item0,max,mini;
- unsigned char clk_ala[2]={0x00,0x00};//鬧鐘數(shù)據(jù)存放初,始值為00:00
- unsigned char hour,minute,time;//用于鬧鈴的設(shè)置
- /*-----------------------------日期、時(shí)間設(shè)置函數(shù)-----------------------------*/
- void tiaozheng(void){
- yy = read_clock(0x8d);//調(diào)用1302時(shí)鐘數(shù)據(jù)中的年數(shù)據(jù),從地址0x8d中
- mo = read_clock(0x89);//調(diào)用1302時(shí)鐘數(shù)據(jù)中的月數(shù)據(jù),從地址0x89中
- dd = read_clock(0x87);//從1302芯片中讀取日數(shù)據(jù),從地址0x87中
- week = read_clock(0x8b);//從1302芯片中讀取星期數(shù)據(jù),從地址0x8b中
- //----------------------------------
- lcm_w_test(0,0x80);
- lcm_w_word("20");//顯示內(nèi)容字符20
- lcm_w_test(1,(yy/16)+0x30);//函數(shù)參數(shù)1,代表本行寫(xiě)數(shù)據(jù),YY/16+0X30得出年十位數(shù)字的顯示碼地址,送顯示
- lcm_w_test(1,yy%16+0x30);//函數(shù)
- lcm_w_word("年");
- //----------------------------------
- lcm_w_test(1,(mo/16)+0x30);
- lcm_w_test(1,mo%16+0x30);//與16取余數(shù),得到月份的個(gè)位數(shù),加0x30得到該數(shù)字的液晶內(nèi)定顯示碼送顯示
- lcm_w_word("月");//調(diào)用字符顯示函數(shù),顯示文字 月
- //----------------------------------
- /*
- lcm_w_test(0,0x88);//第一個(gè)參數(shù)0,表示本行寫(xiě)入LCM的是指令,指定顯示位置88H(第三行左端)
- lcm_w_word("星期");//調(diào)用字符顯示函數(shù),顯示文字 星期
- lcm_w_test(1,mo%16+0x30);//與16取余數(shù),得到月份的個(gè)位數(shù),加0x30得到該數(shù)字的液晶內(nèi)定顯示碼送顯示
- */
- //----------------------------------
- lcm_w_test(1,(dd/16)+0x30);
- lcm_w_test(1,dd%16+0x30);//第一個(gè)1參數(shù),表示本行寫(xiě)數(shù)據(jù),日數(shù)據(jù)與16取余得個(gè)位數(shù),加0x30得到顯示碼
- lcm_w_word("日");//顯示字符 日
- //----------------------------------
- if(read_clock(0x85) != hh){//如果程序中的小時(shí)與1302芯片中的不同,
- hh = read_clock(0x85);//刷新程序中的小時(shí)數(shù)據(jù)
- }
- lcm_w_test(0,0x91);//第一個(gè)參數(shù)0,表示本行寫(xiě)入LCM的是指令,指定顯示位置88H(第三行左端)
- lcm_w_test(1,(hh/16)+0x30);//顯示十位
- lcm_w_test(1,hh%16+0x30);//顯示個(gè)位
- lcm_w_word("時(shí)");
- //----------------------------------
- if(read_clock(0x83) != mm){//如果1302芯片中的分鐘數(shù)據(jù)與程序中的分鐘變量不相等
- mm = read_clock(0x83);//刷新程序中的分鐘數(shù)據(jù)
- }
- lcm_w_test(1,(mm/16)+0x30);//向液晶寫(xiě)數(shù)據(jù),顯示分鐘的十位數(shù)
- lcm_w_test(1,mm%16+0x30);//向液晶寫(xiě)數(shù)據(jù),顯示分鐘的個(gè)位數(shù)
- lcm_w_word("分");
- //----------------------------------
- if(read_clock(0x81) != ss){//如果1302芯片中的分鐘數(shù)據(jù)與程序中的秒鐘變量不相等(0x81為讀秒數(shù)據(jù)0x80為寫(xiě)秒數(shù)據(jù))
- ss = read_clock(0x81);//刷新程序中的秒鐘數(shù)據(jù)
- }
- lcm_w_test(1,(ss/16)+0x30);//向液晶寫(xiě)數(shù)據(jù),顯示分鐘的十位數(shù)
- lcm_w_test(1,ss%16+0x30);//向液晶寫(xiě)數(shù)據(jù),顯示分鐘的個(gè)位數(shù)
- lcm_w_word("秒");
- //////////////////////////////////////////////////////////////////////
- //=========顯示鬧鐘的設(shè)置時(shí)間===================
-
- hour=clk_ala[0]; //取出上一次的鬧鐘小時(shí)值
- minute=clk_ala[1]; //取出上一次的鬧鐘分鐘值
-
- lcm_w_test(0,0x88);
- lcm_w_word("鬧鐘---");
- //----------------------------
- lcm_w_test(1,(hour/10)+0x30);//顯示小時(shí)十位
- lcm_w_test(1,(hour%10)+0x30);//顯示小時(shí)個(gè)位
- //----------------------------
- lcm_w_word(":");
- //----------------------------
- lcm_w_test(1,(minute/10)+0x30);//顯示分鐘的十位
- lcm_w_test(1,(minute%10)+0x30);//顯示分鐘的個(gè)位
- //----------------------------
- lcm_w_word("----");
- /////////////////////////////////////////////////////////////////////////
- }
- /*****************************************************************************/
- //被調(diào)數(shù)據(jù)加一或減一,并檢查數(shù)據(jù)范圍,寫(xiě)入1302指定地址保存
- void ds_w(void)
- {
- item0=time;
- item=((read_clock(address+1))/16)*10 + (read_clock(address+1))%16;//時(shí)間的調(diào)整
- if(K3 == 0||key_add==1){//如果按動(dòng)上調(diào)鍵
- item++;//數(shù)加 1
- }
- if(K4 == 0||key_minish==1){//如果按動(dòng)下調(diào)鍵
- item--;//數(shù)減 1
- }
- if(item>max) item=mini;//查看數(shù)值是否在有效范圍之內(nèi)
- if(item<mini) item=max;//如果數(shù)值小于最小值,則自動(dòng)等于最大值
- write_clock(0x8e,0x00);//允許寫(xiě)1302芯片操作
- write_clock(address,(item/10)*16+item%10);//轉(zhuǎn)換成16進(jìn)制寫(xiě)入1302
- write_clock(0x8e,0x80);//寫(xiě)保護(hù),禁止寫(xiě)操作
- }
- /********************************************************************/
- //===============鬧鐘時(shí)間的加減設(shè)置======================
- void ds_w0(void)
- {
- item0=time;
- if(K3 == 0||key_add==1){//如果按動(dòng)上調(diào)鍵
- item0++;//數(shù)加 1
- }
- if(K4 == 0||key_minish==1){//如果按動(dòng)下調(diào)鍵
- item0--;//數(shù)減 1
- }
- if(item0>max) item0=mini;//查看數(shù)值是否在有效范圍之內(nèi)
- if(item0<mini)item0=max;//如果數(shù)值小于最小值,則自動(dòng)等于最大值
- time=item0;//調(diào)整后的時(shí)間重新賦值給time(time為hour或minute),這步很重要,沒(méi)有將無(wú)法更新鬧鐘數(shù)據(jù)
- }
- /**********************************************************************************************************/
- //調(diào)整時(shí)間子函數(shù),設(shè)置鍵、數(shù)據(jù)范圍、上調(diào)加一,下調(diào)減一功能。
- void Set_time(unsigned char sel){ //根據(jù)選擇調(diào)整的相應(yīng)項(xiàng)目加1并寫(xiě)入DS1302,函數(shù)參數(shù)是按動(dòng)設(shè)置鍵的次數(shù)
-
- write_com(0x30); write_com(0x06);
-
- lcm_w_test(0,0x98);//第一參數(shù)0表示本行寫(xiě)入指令,指定下面行的 調(diào)整 顯示起始位置為9AH
- lcm_w_word(">>調(diào)整>> <<<<");//調(diào)用字符顯示函數(shù),顯示 調(diào)整字樣
-
- /* if(sel==8) {lcm_w_word("星期");address=0x8a; max=7;mini=1;
- tiaozheng();
- ds_w();
- tiaozheng();
- }
- */
- //================================================================
- lcm_w_test(0,0x9c);
- if(sel==7) {lcm_w_word("鬧鐘分"); time=minute;max=59;mini=0;
- tiaozheng();//顯示調(diào)整前的內(nèi)容
- ds_w0();//設(shè)置鬧鐘
- clk_ala[1]=time;//把更新后的分鐘數(shù)據(jù)重新保存
- tiaozheng();//顯示調(diào)整后的內(nèi)容
- }//按動(dòng)8次顯示 調(diào)整鬧鐘的分鐘部分
- if(sel==6) {lcm_w_word("鬧鐘時(shí)");time=hour; max=23;mini=0;
- tiaozheng();
- ds_w0();
- clk_ala[0]=time;//把更新后的小時(shí)數(shù)據(jù)重新保存
- tiaozheng();
- }//按動(dòng)7次顯示 調(diào)整鬧鐘的小時(shí)部分
- //================================================================
- if(sel==5) {lcm_w_word("秒鐘");address=0x80; max=59;mini=0;
- tiaozheng(); //調(diào)用日期、時(shí)間調(diào)整函數(shù)
- ds_w(); //被調(diào)數(shù)據(jù)加一或減一函數(shù)
- tiaozheng();
-
- } //秒6,按動(dòng)6次顯示 調(diào)整秒鐘
- //并指定秒鐘數(shù)據(jù)寫(xiě)入1302芯片的寫(xiě)入地址是0x80,秒鐘數(shù)據(jù)的最大值是59,最小值是0
- if(sel==4) {lcm_w_word("分鐘");address=0x82; max=59;mini=0;
- tiaozheng();
- ds_w();
- tiaozheng();
-
- } //分鐘5,按動(dòng)5次顯示 調(diào)整分鐘
- //并指定分鐘數(shù)據(jù)寫(xiě)入1302芯片的地址是0x82,分鐘數(shù)據(jù)的最大值是59,最小值是0
- if(sel==3) {lcm_w_word("小時(shí)");address=0x84; max=23;mini=0;
-
- tiaozheng();
- ds_w();
- tiaozheng();
-
- } //小時(shí)4,按動(dòng)4次顯示 調(diào)整小時(shí)
- //規(guī)定小時(shí)數(shù)據(jù)寫(xiě)入1302芯片的位置是0x84,小時(shí)數(shù)據(jù)最大值23,最小值是0
-
- if(sel==2) {lcm_w_word("日期");address=0x86;
- mo = read_clock(0x89);//讀月數(shù)據(jù)
- moontemp1=mo/16;
- moontemp2=mo%16;
- mo=moontemp1*10+moontemp2;//轉(zhuǎn)換成10進(jìn)制月份數(shù)據(jù)
- yy = read_clock(0x8d);//讀年數(shù)據(jù)
- moontemp1=yy/16;
- moontemp2=yy%16;
- yy=moontemp1*10+moontemp2;//轉(zhuǎn)換成10進(jìn)制年份數(shù)據(jù)
- if(mo==2&&yy%4!=0){max=28;mini=1;}//平年2月28天
- if(mo==2&&yy%4==0){max=29;mini=1;}//閏年2月29天
- if(mo==1||mo==3||mo==5||mo==7||mo==8||mo==10||mo==12){max=31;mini=1;}//31天的月份
- if(mo==4||mo==6||mo==9||mo==11){max=30;mini=1;}//30天的月份
- tiaozheng();
- ds_w();
- tiaozheng(); //調(diào)用日期、時(shí)間調(diào)整函數(shù)
-
- } //日3,按動(dòng)3次顯示 調(diào)整日期
- //規(guī)定日期數(shù)據(jù)寫(xiě)入1302的位置地址是0x86,日期最大值31,最小值是1
- if(sel==1) {lcm_w_word("月份");address=0x88; max=12;mini=1;
- tiaozheng();
- ds_w();
- tiaozheng();
-
- } //月2,按動(dòng)2次顯示 調(diào)整月份
- //規(guī)定月份寫(xiě)入1302的位置地址是0x88,月份最大值12,最小值1
- if(sel==0) {lcm_w_word("年份");address=0x8c; max=99; mini=0;
- tiaozheng();
- ds_w(); //被調(diào)數(shù)據(jù)加一或減一函數(shù)
- tiaozheng(); //調(diào)用日期、時(shí)間調(diào)整函數(shù)
- } //年1,按動(dòng)1次顯示 調(diào)整年份,
- //規(guī)定年份寫(xiě)入1302的地址是0x8c,年份的最大值99,最小值0
- }
- /*********************************************************************
- **********************************************************************
- ************** 主函數(shù) ****************
- **********************************************************************
- /********************************************************************/
- void main()
- {
- unsigned char e=0,f=0,tmp,i;
-
- IE = 0x81; //允許總中斷中斷,使能 INT0 外部中斷
- TCON = 0x01; //觸發(fā)方式為脈沖負(fù)邊沿觸發(fā)
- IRIN=1; //IO口初始化
- BEEP=1;
- K1=1;K2=1;K3=1;K4=1;
-
-
- Init_1302(); //時(shí)鐘芯片初始化
- lcm_init(); //液晶初始化
- welcome0(); //調(diào)用歡迎信息1
- DelayM(2000);//延時(shí)
- //welcome();DelayM(1000); //調(diào)用歡迎信息2
- lcm_clr(); //清屏
- Clean_12864_GDRAM(); //清屏
- while(1)
- {
-
- if (w == 0) //正常走時(shí)
- {
- displaydate(); //顯示日期
- displaynl(); //顯示農(nóng)歷
- displaytime(); //顯示時(shí)間
- read_temp(); //讀取溫度
- ds1820disp(); //顯示溫度
- displayxq(); //顯示星期
-
- //=================以下是鬧鐘的相關(guān)處理===================
-
- if(ala_flag==1){//鬧鐘標(biāo)志位
- set1616pic(6,1,0,2);} //顯示"鬧鐘圖標(biāo)"
- else{
- set1616pic(6,1,0,3);}//關(guān)閉"鬧鐘圖標(biāo)"顯示
- //----------------------------------------
- tmp=read_clock(0x85);//取出1302小時(shí)
- i = tmp/16;
- tmp = tmp&0x0f;
- tmp = tmp + i*10;
- if(clk_ala[0]==tmp)//與鬧鐘設(shè)定的小時(shí)值相同
- {
- tmp=read_clock(0x83);//取出1302分鐘
- i = tmp/16;
- tmp = tmp&0x0f;
- tmp = tmp + i*10;
- if(clk_ala[1]==tmp)//與鬧鐘設(shè)定的分鐘值相同
- {
- if(ala_flag==1)//鬧鐘打開(kāi)
- {
- alarmbeep();//鬧鈴聲響1分鐘后自動(dòng)關(guān)閉,
- DelayM(200);//控制鬧鐘響的間隔即頻率
- }
- else BEEP=1;//關(guān)閉蜂鳴器
- }
- else BEEP=1;//關(guān)閉蜂鳴器
- }
- //==============鬧鐘處理結(jié)束=======================
- }
- else {} //========否則啟動(dòng)調(diào)時(shí)=========================
-
-
- /*---------------按鍵及紅外遙控設(shè)置時(shí)間------------------------------*/
- if (K1 == 0||key_manue==1)
- {
-
- DelayM(8); //按鍵消抖
- /*當(dāng)是調(diào)時(shí)狀態(tài) 本鍵用于調(diào)整下一項(xiàng)---------------------------------------------------*/
- if((K1 == 0 && w == 1)||(key_manue==1&&w==1)) //
- {
-
- e++;
- if (e >= 8 ) {e = 0;}
- while(! K1 ); //等待鍵松開(kāi)
- key_manue=0;
- Set_time(e); beep(); //調(diào)整
- }
- /*當(dāng)是正常狀態(tài)時(shí)就進(jìn)入調(diào)時(shí)狀態(tài)---------------------------------------------------*/
- if((K1 == 0 && w == 0)||(key_manue==1&&w==0)) //
- {
- key_manue=0;
- lcm_clr();
- Clean_12864_GDRAM(); //清屏
- w=1; //進(jìn)入調(diào)時(shí)
- Set_time(e);beep();
- }
- while(K1 == 0); //等待鍵松開(kāi)
- }
- /*當(dāng)在調(diào)時(shí)狀態(tài)時(shí)就退出調(diào)時(shí)---------------------------------------------------*/
- if (K2 == 0||key_ok==1) //
- { beep();
- DelayM(8);
- if((K2 == 0 && w == 1)||(key_ok==1&&w==1))
- {
- w = 0; //退出調(diào)時(shí)
- e = 0; //"下一項(xiàng)"計(jì)數(shù)器清0
- }
- if((K2 == 0 && w == 0)||(key_ok==1&&w==0))
- {
- lcm_clr(); Clean_12864_GDRAM();
- write_com(0x30); write_com(0x06);
- welcome();
- while(K2 == 0); //按下K2是顯示歡迎信息
- DelayM(500);key_ok=0;//紅外"OK"按鍵按下時(shí)顯示0.5秒鐘的歡迎界面2
- }
- lcm_clr(); Clean_12864_GDRAM();
- // ds_write(0x0a,0x20); //調(diào)時(shí)完畢,開(kāi)啟時(shí)鐘振蕩器
- displaydate();
- displayxq();
- displaynl();
- displaytime();
- read_temp();
- ds1820disp();
- while(K2 == 0);
- }
- /*加調(diào)整--------------------------------------------------------------------*/
- if ((K3 == 0 && w == 1)||(key_add==1&&w==1))
- {
- DelayM(8);
- if((K3 == 0 && w == 1)||(key_add==1&&w==1))
- {
- Set_time(e);
- beep();
- while(!K3);
- key_add=0;
- }
- key_add=0;
- while(! K3 );
- }
- /*減調(diào)整--------------------------------------------------------------------*/
- if ((K4 == 0 && w == 1)||(key_minish==1&&w==1))
- {
- DelayM(10);
- if((K4 == 0 && w == 1)||(key_minish==1&&w==1))
- {
- Set_time(e);
- beep();
- while(! K4 );
- key_minish=0;
- }
- key_minish=0;
- while(! K4 );
- }
- /*----------------------------------------------------------------*/
-
- }
- }
- /*結(jié)束----------------------------------------------------------------------*/
復(fù)制代碼
完整代碼下載:
大數(shù)字12864時(shí)鐘 帶紅外遙控 鬧鐘.rar
(251.28 KB, 下載次數(shù): 368)
2017-3-5 03:29 上傳
點(diǎn)擊文件名下載附件
|
評(píng)分
-
查看全部評(píng)分
|