|
- #include<reg52.h>//52單片機(jī)頭文件,規(guī)定了52單片機(jī)的寄存器和IO口等
- #include<intrins.h>//_nop_空指令及左右循環(huán)移位子函數(shù)庫
- #define uchar unsigned char//宏定義
- #define uint unsigned int//宏定義
-
- sbit lcd_rs=P2^0;//定義選數(shù)據(jù)寄存器選指令寄存器控制端
- sbit lcd_rw=P2^1;//定義下面通過lcd_rw來操作P2^5口,1602讀寫選擇端
- sbit lcd_en=P2^2;//定義下面通過lcd_en來操作P2^7口,1602液晶使能控制端
- sbit DS_rst=P3^4;//DS1302復(fù)位
- sbit DS_sck=P3^5;//定義時(shí)鐘總線
- sbit DS_io=P3^6;//定義DS1302數(shù)據(jù)總線
- sbit s1=P1^0;//定義設(shè)置按鈕
- sbit s2=P1^1;//定義調(diào)時(shí)按鈕
- sbit s3=P1^2;//定義確定按鈕
- sbit s4=P1^3;//定義鬧鐘調(diào)整按鈕
- sbit ACC0=ACC^0;//累加器
- sbit ACC7=ACC^7;
- sbit BELL=P1^6; //喇叭
- char fen,shi,miao,ri,yue,nian,zhou,s1num,s2num,s4num,flag1,flag2,lshi,lfen;
- uchar code table[]={" 2022- - W "};//要寫入1602液晶的數(shù)據(jù)
- uchar code table1[]={" : : T : "};//字庫中的字可直接以外加""號(hào)的形式直接寫入
- uchar code table2[]={" Welcome To Lcd!"};//歡迎界面
- uchar code table3[]={"Happy Every Day!"}; //歡迎界面
- /*******************************************************************************
- 時(shí)函數(shù),z的取值為這個(gè)函數(shù)的延時(shí)ms數(shù),delay(200);大約延時(shí)200ms. delay(500);大約延時(shí)500ms
- *******************************************************************************/
- void delay(uint z)
- {
- uint x,y;
- for(x=z;x>0;x--)
- for(y=110;y>0;y--);
- }
- /*********************蜂鳴器函數(shù)************************************************/
- void didi()
- {
- uchar i;
- for(i=0;i<60;i++)
- {
- BELL = 0;
- delay(1);
- BELL = 1;
- delay(1);
- }
- }
- /*******************向1602液晶中寫一個(gè)指令**************************************/
- void write_com(uchar com)
- {
- lcd_rw=0; //lcd_rw為讀寫控制端,lcd_rw=0,這里可不寫
- lcd_rs=0; //液晶rs接口為0時(shí),寫指令,rs為1時(shí)寫數(shù)據(jù)
- P0=com; //將要寫的指令賦給P0口,
- delay(5); //由1602讀寫操作時(shí)序圖,先將指令賦給P0口,延時(shí)后將使能
- lcd_en=1; // 端lcd_en置高,再延時(shí)一段時(shí)間,然后將lcd_en置低,這樣指令
- delay(5); // 就寫入到LCD了
- lcd_en=0;
- }
- /****************************向液晶寫數(shù)據(jù)***************************************/
- void write_data(uchar date)//與寫指令類似,這里lcd_rs設(shè)為1
- {
-
- lcd_rs=1;
- lcd_rw=0;
- P0=date;
- delay(5);
- lcd_en=1;
- delay(5);
- lcd_en=0;
- }
- /*****************************初使化1602液晶************************************/
- void init_1602()
- {
- lcd_en=0;
- nian=22;
- yue=6;
- ri=21;
- zhou=5;
- shi=13;
- fen=59;
- miao=59;
- s1num=0;
- s2num=0;
- s4num=0;
- lshi=7;
- lfen=59;
- write_com(0x38);//設(shè)置LCD為16*2顯示、5*7點(diǎn)陣、8位數(shù)據(jù)接口模式
- write_com(0x0c);//開顯示、不顯示光標(biāo)
- write_com(0x06);//寫一個(gè)字符后,地址指針加1
- write_com(0x01);//顯示清0
- }
- /*******************************************************************************/
- void gudingtime_1602()
- {
- uchar num;
- write_com(0x80);//將指針指向初始位置
- for(num=0;num<16;num++)//循環(huán)函數(shù),用于將" 2022- - "寫入液晶
- write_data(table[num]);
- write_com(0x80+0x40);//將指針指向1602液晶的第二行
- for(num=0;num<16;num++)//功能與上同,用于將" : : T : "寫入
- write_data(table1[num]);
- }
- /**************************顯示歡迎界面函數(shù)*************************************/
- void displaystar(void)
- {
- uchar i;
- write_com(0x80);
- for(i=0;i<16;i++)
- write_data(table2[i]);
- write_com(0x80+0x40);
- for(i=0;i<16;i++)
- write_data(table3[i]);
- }
- /***************************顯示時(shí)間、日期子函數(shù)*********************************/
- void write_sfm(uchar add,uchar time)//用于在1602上顯示年、月、日、時(shí)、分、秒。Add為顯示位置,time為要顯示的內(nèi)容
- {
- uchar shiwei,gewei;
- shiwei=time/16; //將從DS1302中讀取的BCD碼數(shù)據(jù)轉(zhuǎn)化成10進(jìn)制個(gè)位和10
- gewei=time%16; //進(jìn)制十位
- write_com(add+0x80);//定義顯示在液晶的什么位置
- write_data(0x30+shiwei);//由1602液晶字庫可知,0~9的數(shù)據(jù)碼分別對(duì)應(yīng)0x30~0x39
- write_data(0x30+gewei); //初使化中設(shè)定了寫一個(gè)字符后,地址指針加1,因此這里
- } // 不用重新光標(biāo)寫位
- /**************************顯示周子函數(shù)*****************************************/
- void write_zhou(uchar time1)//用于在1602上顯示周信息,與顯示
- { //時(shí)間日期子函數(shù)類似
- uchar gewei;
- gewei=time1%16;//一周七天,因此只需個(gè)位
- write_com(0x80+14);//初始位置加13個(gè)
- write_data(0x30+gewei);
- }
- /***************************寫數(shù)據(jù)字節(jié)子函數(shù)************************************/
- void Input_1byte(uchar TD)//寫一字節(jié)數(shù)據(jù)
- {
- uchar i;
- ACC=TD;
- for(i=8;i>0;i--)
- {
- DS_io=ACC0;
- DS_sck=1;
- DS_sck=0;
- ACC=ACC>>1; //右移一位
- }
- }
- /*************************讀數(shù)據(jù)字節(jié)子函數(shù)**************************************/
- uchar Output_1byte(void)//讀一字節(jié)數(shù)據(jù)
- {
- uchar i;
- for(i=8;i>0;i--)
- {
- ACC=ACC>>1;
- ACC7=DS_io;
- DS_sck=1;
- DS_sck=0;
- }
- return(ACC);
- }
- /***************************寫DS1302數(shù)據(jù)函數(shù)***********************************/
- void write_1302(uchar DS_ADD,uchar DS_DAT)//寫操作
- {
- DS_rst=0;
- DS_sck=0;
- DS_rst=1;
- Input_1byte(DS_ADD);
- Input_1byte(DS_DAT);
- DS_sck=1;
- DS_rst=0;
- }
- /***************************讀DS1302數(shù)據(jù)函數(shù)***********************************/
- uchar read_1302(uchar DS_ADD)//讀操作
- {
- uchar DS_INF;
- DS_rst=0;
- DS_sck=0;
- DS_rst=1;
- Input_1byte(DS_ADD);
- DS_INF=Output_1byte();
- DS_sck=1;
- DS_rst=0;
- return(DS_INF);
- }
- /*************************初始化DS1302子函數(shù)***********************************/
- void inital_1302()
- {
- write_1302(0x8e,0x00);//禁止寫保護(hù)
- write_1302(0x90,0xaa);//定義充電
- write_1302(0x80,0x53);//秒
- write_1302(0x84,0x13);//時(shí)
- write_1302(0x82,0x43);//分
- write_1302(0x8c,0x12);//年
- write_1302(0x88,0x06);//月
- write_1302(0x86,0x03);//日
- write_1302(0x8a,0x06);//星期
- write_1302(0xc0,0x08);//鬧鐘小時(shí)初始化
- write_1302(0xfc,0x00);//鬧鐘分鐘初始化
- write_1302(0x8e,0x80);//開保護(hù)
- }
- /********************************************************************************
- 掃描函數(shù)
- ********************************************************************************/
- void keyscan()
- {
- if(s1==0&&s4num==0) //按鍵1按下且s4再次之前未曾按過
- {
- delay(5);
- if(s1==0&&s4num==0)
- {
- flag1=1;
- s1num++;
- while(!s1);didi();
- if(s1num==1)
- {
- write_com(0x80+0x40+8);//光標(biāo)移動(dòng)到**位置
- write_com(0x0f);//顯示光標(biāo)
- }
- if(s1num==2)
- {
- write_1302(0x8e,0x00);//禁止寫保護(hù)
- write_1302(0x80,miao);//寫入秒信息
- write_1302(0x8e,0x80);//開寫保護(hù)
- write_com(0x80+0x40+5);
- }
- if(s1num==3)
- {
- write_1302(0x8e,0x00);
- write_1302(0x82,fen);
- write_1302(0x8e,0x80);
- write_com(0x80+0x40+2);
- }
- if(s1num==4)
- {
- write_1302(0x8e,0x00);
- write_1302(0x88,yue);
- write_1302(0x8e,0x80);
- write_com(0x80+13);
- }
- if(s1num==5)
- {
- write_1302(0x8e,0x00);
- write_1302(0x84,shi);
- write_1302(0x8e,0x80);
- write_com(0x80+10);
- }
- if(s1num==6)
- {
- write_1302(0x8e,0x00);
- write_1302(0x86,ri);
- write_1302(0x8e,0x80);
- write_com(0x80+7);
- }
- if(s1num==7)
- {
- write_1302(0x8e,0x00);
- write_1302(0x8c,nian);
- write_1302(0x8e,0x80);
- write_com(0x80+4);
- }
- if(s1num==8)
- {
- flag1=0;
- s1num=0;
- write_1302(0x8e,0x00);
- write_1302(0x8a,zhou);
- write_1302(0x8e,0x80);
- write_com(0x0c);//不顯示光標(biāo)
- }
- }
- }
- /*******************************************************************************/
- if(s1num!=0&&s4num==0)//按鍵1按下*次且s4再次之前未曾按過
- {
- if(s2==0)
- {
- delay(5);
- if(s2==0)
- {
- while(!s2);didi();
- if(s1num==1)
- {
- int x1,x2;
- x1=miao%16;
- x2=miao/16;
- x1++;
- if(x1==10)
- {
- x1=0;
- x2++;
- if(x2>=6)
- x2=0;
- }
- miao=x1+x2*16;
- write_sfm(7+0x40,miao);//將修改的數(shù)送到1602顯示
- write_com(0x80+0x40+8);//挪回光標(biāo)
- }
- if(s1num==2)
- {
- int x3,x4;
- x3=fen%16;
- x4=fen/16;
- x3++;
- if(x3==10)
- {
- x3=0;
- x4++;
- if(x4>=6)
- x4=0;
- }
- fen=x3+x4*16;
- write_sfm(4+0x40,fen);
- write_com(0x80+0x40+5);
- }
- if(s1num==3)
- {
- int x5,x6;
- x5=shi%16;
- x6=shi/16;
- x5++;
- if(x6>=2&&x5>=4)
- {
- x5=0;
- x6=0;
- }
- if(x5==10)
- {
- x5=0;
- x6++;
- }
- shi=x5+x6*16;
- write_sfm(1+0x40,shi);
- write_com(0x80+0x40+2);
- }
- if(s1num==4)
- {
- zhou++;
- if(zhou==8)
- zhou=1;
- write_zhou(zhou);
- write_com(0x80+13);
-
- }
- if(s1num==5)
- {
- int x5,x6;
- x5=ri%16;
- x6=ri/16;
- x5++;
- if(x6>=3&&x5>=1)
- {
- x5=1;
- x6=0;
- }
- if(x5==10)
- {
- x5=0;
- x6++;
- }
- ri=x5+x6*16;
- write_sfm(9,ri);
- write_com(0x80+10);
- }
- if(s1num==6)
- {
- int x5,x6;
- x5=yue%16;
- x6=yue/16;
- x5++;
- if(x6>=1&&x5>=3)
- {
- x5=1;
- x6=0;
- }
- if(x5==10)
- {
- x5=0;
- x6++;
- }
- yue=x5+x6*16;
- write_sfm(6,yue);
- write_com(0x80+7);
- }
- if(s1num==7)
- {
- int x5,x6;
- x5=nian%16;
- x6=nian/16;
- x5++;
- if(x6>=2&&x5>=1)
- {
- x5=1;
- x6=0;
- }
- if(x5==10)
- {
- x5=0;
- x6++;
- }
- nian=x5+x6*16;
- write_sfm(3,nian);
- write_com(0x80+4);
- }
- }
- }
- }
- /*******************************************************************************/
- if(s1num!=0||s4num!=0)// 在調(diào)整模式下
- {
- if(s3==0)//如果確定鍵按下
- {
- delay(5);
- if(s3==0) //延時(shí)并重新檢測(cè)S3是否按下,用于差小誤差
- {
- if(s1num!=0)
- {
- while(!s3);didi();//在松手時(shí)將調(diào)整后的時(shí)間、日期及周信息寫入DS1302,退出調(diào)整模式并隱藏光標(biāo),按鍵次數(shù)清0
- write_1302(0x8e,0x00);
- write_1302(0x80,miao);
- write_1302(0x84,shi);
- write_1302(0x82,fen);
- write_1302(0x8a,zhou);
- write_1302(0x8c,nian);//年
- write_1302(0x88,yue);//月
- write_1302(0x86,ri);
- write_1302(0x8e,0x80);
- flag1=0;
- write_com(0x0c);
- s1num=0;
- }
- if(s4num!=0)
- {
- while(!s3);didi();//在松手時(shí)將調(diào)整后的時(shí)間、日期及周信息寫入DS1302,退出調(diào)整模式并隱藏光標(biāo),按鍵次數(shù)清0
- write_1302(0x8e,0x00);
- write_1302(0xc0,lshi);
- write_1302(0xfc,lfen);
- write_1302(0x8e,0x80);
- flag2=0;
- s4num=0;
- write_com(0x0c);
- }
- }
- }
- }
- if(s4==0&&s1num==0)//按鍵4按下*次且s1再次之前未曾按過
- {
-
- delay(5);
- if(s4==0&&s1num==0)
- {
- s4num++;
- flag2=1;
- while(!s4);didi();
- if(s4num==1)
- {
-
- write_com(0x80+0x40+14);
- write_com(0x0f);
- }
-
- if(s4num==2)
- {
- write_1302(0x8e,0x00);//禁止寫保護(hù)
- write_1302(0xfc,lfen);//鬧鐘初始化
- write_1302(0x8e,0x80);//開寫保護(hù)
- write_com(0x80+0x40+11);
- }
- if(s4num==3)
- {
- s4num=0;
- flag2=0;
- write_1302(0x8e,0x00);//禁止寫保護(hù)
- write_1302(0xc0,lshi);//鬧鐘初始化
- write_1302(0x8e,0x80);//開寫保護(hù)
- write_com(0x0c);//不顯示光標(biāo)
- }
- }
- }
-
- if(s4num!=0&&s1num==0)
- {
- if(s2==0)
- {
- delay(5);
- if(s2==0)
- {
- while(!s2);didi();
- if(s4num==1)
- {
- int x1,x2;
- x1=lfen%16;
- x2=lfen/16;
- x1++;
- if(x1==10)
- {
- x1=0;
- x2++;
- if(x2>=6)
- x2=0;
- }
- lfen=x1+x2*16;
- write_sfm(13+0x40,lfen);
- write_com(0x80+0x40+14);
- }
- if(s4num==2)
- {
- int x5,x6;
- x5=lshi%16;
- x6=lshi/16;
- x5++;
- if(x6>=2&&x5>=4)
- {
- x5=0;
- x6=0;
- }
- if(x5==10)
- {
- x5=0;
- x6++;
- }
- lshi=x5+x6*16;
- write_sfm(10+0x40,lshi);
- write_com(0x80+0x40+11);
- }
- }
- }
- }
- }
- void laba()
- {
- if((shi==lshi)&&(fen==lfen)&&(miao<=10&&miao>=0))//當(dāng)鬧鐘的時(shí)和分分別與時(shí)鐘的時(shí)和分相等時(shí),鬧鐘時(shí)間到,蜂鳴器鳴響,鳴響10s
- {
- didi();
- }
- }
- void main()
- {
- init_1602();
- delay(5);
- displaystar();//初始化1602后馬上顯示歡迎語句
- delay(5000);//讓歡迎界面停留一段時(shí)間
- gudingtime_1602();//顯示液晶固定不變部分
- inital_1302();
- lshi=read_1302(0xc1);//從ds1302里面的RAM讀取鬧鐘時(shí),此處不放在while(1)大循環(huán)里面是因?yàn)閐s1302里面的RAM里的數(shù)據(jù)是不變的只需讀取一次
- lfen=read_1302(0xfd);//從ds1302里面的RAM讀取鬧鐘分
- write_sfm(0x40+11,lshi);//將鬧鐘時(shí)送到1602顯示
- write_sfm(0x40+14,lfen);//將鬧鐘分送到1602顯示
- while(1)
- {
- keyscan();
- laba();
- if(flag1==0&&flag2==0)//只有當(dāng)不在調(diào)整的時(shí)候才從DS1302里面讀取數(shù)據(jù)并且送到1602上顯示
- {
- miao=read_1302(0x81);//先讀出,再送到1602顯示,不斷循環(huán)操作,使1602動(dòng)態(tài)顯示時(shí)間的走動(dòng)
- fen=read_1302(0x83);
- shi=read_1302(0x85);
- ri=read_1302(0x87);
- yue=read_1302(0x89);
- zhou=read_1302(0x8b);
- nian=read_1302(0x8d);
-
- write_sfm(6+0x40,miao);
- write_sfm(3+0x40,fen);
- write_sfm(0+0x40,shi);
- write_sfm(9,ri);
- write_sfm(6,yue);
- write_sfm(3,nian);
- write_zhou(zhou);
- }
- }
- }
復(fù)制代碼
|
|