51單片機主控,ds1302、dht11模塊,按鍵控制調制時間,實時顯示時間的溫度
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
單片機源程序如下:
- #include <REG52.H>
- #include "lcd1602.h"
- #include <string.h>
- #include <intrins.h>
- #include "KEY.H"
- #include <ds18b20.h>
- #include "1302.h"
- #include "config.h"
- /*********定義變量*********/
- uchar buff[16];
- uint Y=0,M=0,D=0,H=0,F=0,S=0,W=0;
- uchar T18B20=0;
- uchar ADDR=0;
- bit SetState=0;
- sbit led = P2^7;
- /*=====1602顯示======*/
- void LCD_DISPLAY()
- {
- T18B20=(retemp()); //18B20溫度采集數值
-
- Y = (TIME[6]/16*10)+(TIME[6]&0X0F);
- M = (TIME[4]/16*10)+(TIME[4]&0X0F);
- D = (TIME[3]/16*10)+(TIME[3]&0X0F);
-
- W = ((TIME[5]/16*10)+(TIME[5]&0X0F)%7);
-
- H = (TIME[2]/16*10)+(TIME[2]&0X0F);
- F = (TIME[1]/16*10)+(TIME[1]&0X0F);
- S = (TIME[0]/16*10)+(TIME[0]&0X0F);
-
-
- sprintf(buff,"20%02d-%02d-%02d",(int)Y,(int)M,(int)D);
- print(1,1,buff);
-
- sprintf(buff,"%02d:%02d:%02d",(int)H,(int)F,(int)S);
- print(2,1,buff);
-
- sprintf(buff,"T:%02dC",(int)T18B20);
- print(2,12,buff);
-
- switch(W)
- {
- case 0:print(1,12,"SUM");break;
- case 1:print(1,12,"MON");break;
- case 2:print(1,12,"TUE");break;
- case 3:print(1,12,"WED");break;
- case 4:print(1,12,"THU");break;
- case 5:print(1,12,"RFI");break;
- case 6:print(1,12,"STA");break;
-
- default :break;
- }
-
- }
- void Int0Configuration()
- {
- //設置INT0
- IT0=1;//跳變沿出發方式(下降沿)
- EX0=1;//打開INT0的中斷允許。
- }
- /*******************************************************************************
- * 函數名 : Int0()
- * 函數功能 : 外部中斷0 中斷函數
- * 輸入 : 無
- * 輸出 : 無
- *******************************************************************************/
- void Int0() interrupt 0
- {
- if(K6_F==1)
- {
- K6_F=0;
- SetState=~SetState;
- Ds1302Init();
- }
- }
- /*========時間更改==========*/
- void TIMER_CHANGE()
- {
-
- if(K4_F==1) //檢測按鍵K4是否按下
- {
- K4_F = 0;
- ADDR++;
- if(ADDR>=7)
- ADDR=0;
- }
- else if(K3_F==1) //檢測按鍵K3是否按下
- {
- K3_F = 0;
- ADDR--;
- if(ADDR<0)
- ADDR=7;
- }
-
- if((K2_F==1)||(K1_F==1)) //檢測按鍵K2或者k1是否按下
- {
- if(K2_F==1)
- {
- K2_F=0;
- TIME[ADDR]++;
- if((TIME[ADDR]&0X0F)>9)
- {
- TIME[ADDR] = TIME[ADDR]+6;
- }
- }
- else if(K1_F==1)
- {
- K1_F=0;
- TIME[ADDR]--;
- if((TIME[ADDR]&0X0F)>9)
- {
- TIME[ADDR] = TIME[ADDR]-6;
- }
-
- }
- }
-
- if((ADDR<2)&&(TIME[ADDR]>=0x60)) //分不能超60
- {
- TIME[ADDR] = 0;
- }
- else if(ADDR==2&&TIME[ADDR]>=0x24) //小時不能超24
- {
- TIME[ADDR] = 0;
- }
- else if(ADDR==3&&TIME[ADDR]>=0x32) //day不能超31
- {
- TIME[ADDR] = 1;
- }
- else if(ADDR==4&&TIME[ADDR]>=0x13) //月分<=12
- {
- TIME[ADDR] = 1;
- }
- else if(ADDR==0&&TIME[ADDR]>=0x07) //星期<=7
- {
- TIME[ADDR] = 1;
- }
-
- Ds1302Write(ADDR,TIME[ADDR]);
-
-
- switch(ADDR)
- {
- case 0:print(2,10,"S ");break; //second
- case 1:print(2,10,"F ");break; //Minute
- case 2:print(2,10,"H ");break; //Hour
- case 3:print(2,10,"D ");break; //DAY
- case 4:print(2,10,"M ");break; //MONTH
- case 5:print(2,10,"W ");break; //WEEK
- case 6:print(2,10,"Y ");break; //YEAR
- default :break;
- }
- }
- /*******主函數*******/
- void main() //int a
- {
- uchar kkk = 55;
- Int0Configuration();
- lcd_init();
- lcd_clear();
- EA=1; //總中斷
-
- while(1)
- {
-
- KEY_SCAN();
-
- if(SetState==0)
- {
- Ds1302ReadTime();
- print(2,10," ");
- }
- else
- {
- TIMER_CHANGE();
- }
- LCD_DISPLAY();
-
- if(K5_F==1)
- {
- K5_F=0;
- led = ~led;
-
- }
- }
-
- }
復制代碼
Keil代碼與Proteus仿真下載(注意要雙擊單片機芯片,重新選擇hex文件的路徑才行):
萬年歷好使.zip
(153.66 KB, 下載次數: 52)
2023-4-22 22:37 上傳
點擊文件名下載附件
|