0.png (14.16 KB, 下載次數: 36)
下載附件
2018-7-23 02:27 上傳
單片機萬年歷仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
0.png (20.33 KB, 下載次數: 46)
下載附件
2018-7-23 02:28 上傳
0.png (9.73 KB, 下載次數: 46)
下載附件
2018-7-23 02:29 上傳
單片機源碼:
- #include<reg52.h>
- #include"LCD12864.h"
- #include"ds1302.h"
- #include"temp.h"
- sbit K1=P3^4;
- sbit K2=P3^5;
- sbit K3=P3^6;
- sbit K4=P3^7;
- sbit beep=P1^6;
- void LCD12864_Delay1ms(uint c); // 延時
- void Delay10ms();
- uchar LCD12864_Busy(void); //LCD忙檢測
- void LCD12864_WriteCmd(uchar cmd);
- void LCD12864_WriteData(uchar dat);
- void LCD12864_Init();
- void LCD12864_ClearScreen();
- void hanzi(uchar ye,uchar lie,uchar *daima); //LCD顯示漢字
- void shuzi(uchar ye,uchar lie,uchar *daima); //LCD顯示數字
- void hanzif(uchar ye,uchar lie,uchar *daima); //LCD顯示漢字反白
- void shuzif(uchar ye,uchar lie,uchar *daima); //LCD顯示數字反白
- void tupiandisplay(); //圖片顯示
- void display(); //LCD顯示
- void IntConfiguration(); //外部中斷配置
- void zhuanhuan(int temp); //18B20 BCD碼轉換
- //void beepsound(); //蜂鳴器響
- void clockdisplay(); //鬧鐘界面顯示
- unsigned char SetState,SetState1,flag; //標志變量
- char SetPlace=-1,SetPlace1=-1; //設置參數,因為中斷的時候就會先加1,所以開始設為-1
- unsigned char datas[]={0,0,0}; //溫度值存儲參數
- extern char TIME[7]; // 1302時間值存儲參數,存儲順序是秒分時日月周年,存儲格式是用BCD碼
- char TIME1[4] = {0,0,12,0}; //鬧鐘時間值存儲參數
- void main()
- {
- unsigned char s;
- LCD12864_Init(); //LCD12864初始化
- LCD12864_ClearScreen(); //清屏
- // tupiandisplay(); //開機圖片顯示
- // LCD12864_Delay1ms(1000);
- // LCD12864_ClearScreen();
- Ds1302Init(); //Ds1302初始化
- IntConfiguration(); //外部中斷設置
- while(1)
- {
- if((SetState==0)&&(flag==0))
- {
- Ds1302ReadTime();
- display();
- }
- if((SetState==1)&&(flag==0)) //調時,SetState是調時標志,SetState=1表示處于調時狀態
- {
-
- switch(SetPlace) //反白顯示處于的位置
- {
-
- case(0):
-
- Right(); //秒數反白,調秒
- shuzif(4,0,num[TIME[0]/16]);
- shuzif(4,8,num[TIME[0]%16]);
- break;
-
-
- case(1):
-
- Left(); //分數反白
- shuzif(4,32,num[TIME[1]/16]);
- shuzif(4,40,num[TIME[1]%16]);
- break;
- case(2):
-
- Left(); //小時反白
- shuzif(4,0,num[TIME[2]/16]);
- shuzif(4,8,num[TIME[2]%16]);
- break;
- case(3):
-
- Right(); //日期反白
- shuzif(0,16,num[TIME[3]/16]);
- shuzif(0,24,num[TIME[3]%16]);
- break;
- case(4):
-
- Left(); //月反白
- shuzif(0,48,num[TIME[4]/16]);
- shuzif(0,56,num[TIME[4]%16]);
- break;
- case(5):
- Left(); //星期反白
- hanzif(2,32,num1[TIME[5]%16]);
- break;
- case(6):
- Left(); //年反白
- shuzif(0,16,num[TIME[6]/16]);
- shuzif(0,24,num[TIME[6]%16]);
- break;
- }
-
-
- if(K2==0) //檢測按鍵K2是否按下
- {
- Delay10ms(); //消除抖動
- if(K2==0)
- {
- TIME[SetPlace]++;
- if((TIME[SetPlace]&0x0f)>9) // TIME[]是BCD碼格式的,BCD碼低四位最多到9,即00001001(0x09BCD),當再進一位時,變為00010000(0x10BCD)而不是00001010
- { //00001010十進制數實際為10,而00010000實際為16,相差了6。下面的情況同理
- TIME[SetPlace]=TIME[SetPlace]+6;
- }
- if((TIME[SetPlace]>=0x60)&&(SetPlace<2)) //秒只能到59
- {
- TIME[SetPlace]=0;
- }
-
- if((TIME[SetPlace]>=0x24)&&(SetPlace==2)) //小時只能到23
- {
- TIME[SetPlace]=0;
- }
- if((TIME[SetPlace]>=0x32)&&(SetPlace==3)) //日只能到31
- {
- TIME[SetPlace]=0;
- }
- if((TIME[SetPlace]>=0x13)&&(SetPlace==4)) //月只能到12
- {
- TIME[SetPlace]=0;
- }
- if((TIME[SetPlace]>0x6)&&(SetPlace==5)) //周只能到7
- {
- TIME[SetPlace]=0;
- }
- if((TIME[SetPlace]>=0x99)&&(SetPlace==6)) //這里的年位數最多到99
- {
- TIME[SetPlace]=0x99;
- }
-
- }
-
- while((K2==0)); //檢測按鍵是否松開
-
- }
-
- if(K3==0) //檢測按鍵K3是否按下
- {
- Delay10ms(); //消除抖動
- if(K3==0)
- {
-
- TIME[SetPlace]--;
- if((TIME[SetPlace]&0x0f)==0x0f) // 比如BCD碼為10的數二進制為0001 0000。再減1,則為0000 1111。此時BCD碼應為09,但實際的為15,差了6.
- {
- TIME[SetPlace]=TIME[SetPlace]-6;
- }
- if((TIME[SetPlace]<0x00)&&(SetPlace<2)) //分秒只能到59
- {
- TIME[SetPlace]=89; //59BCD的十進制為89.
- }
- if((TIME[SetPlace]<0x00)&&(SetPlace==2)) //小時只能到23
- {
- TIME[SetPlace]=35; //23BCD的十進制為35
- }
- if((TIME[SetPlace]==0x00)&&(SetPlace==3)) //日只能到31
- {
- TIME[SetPlace]=49; //32BCD的十進制為49
- }
- if((TIME[SetPlace]==0x00)&&(SetPlace==4)) //月只能到12
- {
- TIME[SetPlace]=18; //12BCD的十進制為18
- }
- if((TIME[SetPlace]<0x00)&&(SetPlace==5)) //周只能到7
- {
- TIME[SetPlace]=6; //7BCD的十進制為7
- }
-
- if((TIME[SetPlace]<=0x00)&&(SetPlace==6)) //年只能到0-99
- {
- TIME[SetPlace]=0x00;
- }
-
- }
-
- while((K3==0)); //檢測按鍵是否松開
- }
-
- display();
- }
-
- if(flag==1) //調鬧鐘,flag是鬧鐘標志,當flag=1表示進入鬧鐘界面
- {
- LCD12864_ClearScreen();
- while(flag==1)
- {
- switch(SetPlace1) //反白顯示位置,與調時類似
-
- {
- case(0):
-
- Right(); //秒數反白
- shuzif(2,16,num[TIME1[0]/10]);
- shuzif(2,24,num[TIME1[0]%10]);
- break;
- case(1):
-
- Left(); //分數反白
- shuzif(2,48,num[TIME1[1]/10]);
- shuzif(2,56,num[TIME1[1]%10]);
- break;
- case(2):
-
- Left(); //小時反白
- shuzif(2,16,num[TIME1[2]/10]);
- shuzif(2,24,num[TIME1[2]%10]);
- break;
-
- case(3):
- Right();
- hanzif(0,0,num2[TIME1[6]]);
- break;
- }
- if(K2==0)
- {
- Delay10ms(); //消除抖動
- if(K2==0)
- {
- TIME1[SetPlace1]++;
- if((TIME1[SetPlace1]==60)&&(-1<SetPlace1<2)) //秒分最多到59
- {
- TIME1[SetPlace1]=0;
- }
-
- if((TIME1[SetPlace1]==24)&&(SetPlace1==2))
- {
- TIME1[SetPlace1]=0; //小時最多到23
- }
- if((TIME1[SetPlace1]==2)&&(SetPlace1==3)) //關和開,0表示關,1表示開
- {
- TIME1[SetPlace1]=0;
- LCD12864_Delay1ms(1);
- }
- }
- while((K2==0)); //檢測按鍵是否松開
- }
-
- if(K3==0)
- {
- Delay10ms(); //消除抖動
- if(K3==0)
- {
- TIME1[SetPlace1]--;
- if((TIME1[SetPlace1]<0)&&(SetPlace1==0)) //秒減到0后變為59
- {
- TIME1[SetPlace1]=59;
- }
- if((TIME1[SetPlace1]<0)&&(SetPlace1==1)) //分
- {
- TIME1[SetPlace1]=59;
- }
- if((TIME1[SetPlace1]<0)&&(SetPlace1==2)) //小時
- {
- TIME1[SetPlace1]=23;
- }
- if((TIME1[SetPlace1]<0)&&(SetPlace1==3)) //關和開
- {
- TIME1[SetPlace1]=1;
- LCD12864_Delay1ms(1);
- }
- }
- while((K3==0)); //檢測按鍵是否松開
- }
- clockdisplay(); //鬧鐘界面顯示
-
- }
- LCD12864_ClearScreen(); //清屏
- }
- for(s=1;s<3;s++)
- if((TIME[s]==TIME1[s])&&(TIME1[3]==1))
- {
- beep=0;
- LCD12864_Delay1ms(500);
- beep=1;
- LCD12864_Delay1ms(500);
- }
- else{
- beep=1;
- }
- /* for(s=1;s<3;s++)
- {
- if((TIME[s]==TIME1[s])&&(TIME1[3]==1)) //鬧鐘到時,即小時和分相等時,顯鬧鐘在開狀態
- {
- beepsound(); //響蜂鳴器,響1分鐘,當分鐘不相等時,自動退出
- // LCD12864_Delay1ms(10000);
- }
- else;
-
- }*/
- }
- }
- /*******************************************************************************
- * 函數名 : LcdDisplay()
- * 函數功能 : 顯示函數
- * 輸入 : 無
- * 輸出 : 無
- *******************************************************************************/
- void display()
- {
-
- Left(); //左半屏
- shuzi(0,0,num[2]);
- shuzi(0,8,num[0]); //年
- shuzi(0,16,num[TIME[6]/16]);
- shuzi(0,24,num[TIME[6]%16]);
- hanzi(0,32,nian);
- shuzi(0,48,num[TIME[4]/16]); //月
- shuzi(0,56,num[TIME[4]%16]);
-
- hanzi(2,0,xing);
- hanzi(2,16,qi);
- hanzi(2,32,num1[TIME[5]%16]); //星期
- shuzi(4,0,num[TIME[2]/16]);
- shuzi(4,8,num[TIME[2]%16]); //時
- hanzi(4,16,shi);
- shuzi(4,32,num[TIME[1]/16]); //分
- shuzi(4,40,num[TIME[1]%16]);
- hanzi(4,48,fen);
- zhuanhuan(Ds18b20ReadTemp()); //顯示溫度
- shuzi(6,0,num[datas[0]]);
- shuzi(6,8,num[datas[1]]);
- shuzi(6,16,dian); //小數點
- shuzi(6,24,num[datas[2]]);
- hanzi(6,32,fuhao); //℃
- Right(); //右半屏
- hanzi(0,0,yue);
- shuzi(0,16,num[TIME[3]/16]); //日期
- shuzi(0,24,num[TIME[3]%16]);
- hanzi(0,32,ri);
- shuzi(4,0,num[TIME[0]/16]); //秒
- shuzi(4,8,num[TIME[0]%16]);
- hanzi(4,16,miao);
- }
- /*******************************************************************************
- * 函數名 : IntConfiguration()
- * 函數功能 : 配置外部中斷0和中斷1
- * 輸入 : 無
- * 輸出 : 無
- *******************************************************************************/
- void IntConfiguration()
- {
- //設置INT0
- IT0=1;//跳變沿出發方式(下降沿)
- EX0=1;//打開INT0的中斷允許。
- //設置INT1
- IT1=1;
- EX1=1;
- EA=1;//打開總中斷
- }
- /*******************************************************************************
- * 函數名 : Int0()
- * 函數功能 : 外部中斷0 中斷函數
- * 輸入 : 無
- * 輸出 : 無
- *******************************************************************************/
- void Int0() interrupt 0
- {
- // Delay10ms();
- if((K1==0)&&(flag==0)) // 調時
- {
- Delay10ms(); //消除抖動
- if((K1==0)&&(flag==0))
- {
- SetState=1;
- Ds1302Init();
-
- SetPlace++;
- if(SetPlace==7) //時間選擇鍵,按一次移一位,從0-7最多8位
- {
- SetPlace=0;
- }
- }
- while(K1==0); //檢測按鍵是否松開
- }
-
- }
- /*******************************************************************************
- * 函數名 : Int1()
- * 函數功能 : 外部中斷1 中斷函數
- * 輸入 : 無
- * 輸出 : 無
- *******************************************************************************/
- void Int1() interrupt 2
- {
-
- if((K4==0)&&(SetState==1)) //確定
- {
- Delay10ms(); //消除抖動
- if((K4==0)&&(SetState==1))
- {
- SetState=0;
- Ds1302Init();
- }
-
- while(K4==0); //檢測按鍵是否松開
- }
- if((K4==0)&&(SetState==0)) //調鬧鐘
- {
- Delay10ms();
- if((K4==0)&&(SetState==0))
- {
- flag=1; //鬧鐘標志
- SetPlace1++;
- if(SetPlace1==4)
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
所有資料51hei提供下載:
不帶字庫.zip
(100.61 KB, 下載次數: 138)
2018-7-22 16:55 上傳
點擊文件名下載附件
基于STC89C52RC單片機控制LCD12864實現萬年歷 下載積分: 黑幣 -5
|