- #include <reg52.h>
- #include <intrins.h>
- #define uchar unsigned char // 以后unsigned char就可以用uchar代替
- #define uint unsigned int // 以后unsigned int 就可以用uint 代替
- sfr ISP_DATA = 0xe2; // 數據寄存器
- sfr ISP_ADDRH = 0xe3; // 地址寄存器高八位
- sfr ISP_ADDRL = 0xe4; // 地址寄存器低八位
- sfr ISP_CMD = 0xe5; // 命令寄存器
- sfr ISP_TRIG = 0xe6; // 命令觸發寄存器
- sfr ISP_CONTR = 0xe7; // 命令寄存器
- sbit LcdRs_P = P2^7; // 1602液晶的RS管腳
- sbit LcdRw_P = P2^6; // 1602液晶的RW管腳
- sbit LcdEn_P = P2^5; // 1602液晶的EN管腳
- sbit RST_P = P1^3; // 時鐘芯片DS1302的RST管腳
- sbit SDA_P = P1^2; // 時鐘芯片DS1302的SDA管腳
- sbit SCK_P = P1^1; // 時鐘芯片DS1302的SCK管腳
- sbit KeySet_P = P3^2; // 設置時間按鍵
- sbit KeyClock_P = P3^3; // 設置鬧鐘按鍵
- sbit KeyDown_P = P3^4; // 減按鍵
- sbit KeyUp_P = P3^5; // 加按鍵
- sbit Buzzer_P = P2^0; // 蜂鳴器
- sbit DQ = P1^0; // DS18B20傳感器的引腳定義
- uchar TimeBuff[7]={17,9,1,6,18,30,40}; // 時間數組,默認2017年9月1日,星期五,18:30:40
- // TimeBuff[0] 代表年份,范圍00-99
- // TimeBuff[1] 代表月份,范圍1-12
- // TimeBuff[2] 代表日期,范圍1-31
- // TimeBuff[3] 代表星期,范圍1-7,1是星期天,2是星期一... ...
- // TimeBuff[4] 代表小時,范圍00-23
- // TimeBuff[5] 代表分鐘,范圍00-59
- // TimeBuff[6] 代表秒鐘,范圍00-59
- uchar Clock_Hour; // 鬧鐘的小時
- uchar Clock_Minute; // 鬧鐘的分鐘
- uchar Clock_Swt; // 鬧鐘的開關
- uchar Buzzer_Flag=0; // 蜂鳴器工作標志
- /*********************************************************/
- // 單片機內部EEPROM不使能
- /*********************************************************/
- void ISP_Disable()
- {
- ISP_CONTR = 0;
- ISP_ADDRH = 0;
- ISP_ADDRL = 0;
- }
- /*********************************************************/
- // 從單片機內部EEPROM讀一個字節,從0x2000地址開始
- /*********************************************************/
- unsigned char EEPROM_Read(unsigned int add)
- {
- ISP_DATA = 0x00;
- ISP_CONTR = 0x83;
- ISP_CMD = 0x01;
- ISP_ADDRH = (unsigned char)(add>>8);
- ISP_ADDRL = (unsigned char)(add&0xff);
- // 對STC89C51系列來說,每次要寫入0x46,再寫入0xB9,ISP/IAP才會生效
- ISP_TRIG = 0x46;
- ISP_TRIG = 0xB9;
- _nop_();
- ISP_Disable();
- return (ISP_DATA);
- }
- /*********************************************************/
- // 往單片機內部EEPROM寫一個字節,從0x2000地址開始
- /*********************************************************/
- void EEPROM_Write(unsigned int add,unsigned char ch)
- {
- ISP_CONTR = 0x83;
- ISP_CMD = 0x02;
- ISP_ADDRH = (unsigned char)(add>>8);
- ISP_ADDRL = (unsigned char)(add&0xff);
- ISP_DATA = ch;
- ISP_TRIG = 0x46;
- ISP_TRIG = 0xB9;
- _nop_();
- ISP_Disable();
- }
- /*********************************************************/
- // 擦除單片機內部EEPROM的一個扇區
- // 寫8個扇區中隨便一個的地址,便擦除該扇區,寫入前要先擦除
- /*********************************************************/
- void Sector_Erase(unsigned int add)
- {
- ISP_CONTR = 0x83;
- ISP_CMD = 0x03;
- ISP_ADDRH = (unsigned char)(add>>8);
- ISP_ADDRL = (unsigned char)(add&0xff);
- ISP_TRIG = 0x46;
- ISP_TRIG = 0xB9;
- _nop_();
- ISP_Disable();
- }
- /*********************************************************/
- // 毫秒級的延時函數,time是要延時的毫秒數
- /*********************************************************/
- void DelayMs(uint time)
- {
- uint i,j;
- for(i=0;i<time;i++)
- for(j=0;j<112;j++);
- }
- /*********************************************************/
- // 延時15微秒
- /*********************************************************/
- void Delay15us(void)
- {
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- }
- /*********************************************************/
- // 復位DS18B20(初始化)
- /*********************************************************/
- void DS18B20_ReSet(void)
- {
- uchar i;
- DQ=0;
- i=240;
- while(--i);
- DQ=1;
- i=30;
- while(--i);
- while(~DQ);
- i=4;
- while(--i);
- }
- /*********************************************************/
- // 向DS18B20寫入一個字節
- /*********************************************************/
- void DS18B20_WriteByte(uchar dat)
- {
- uchar j;
- uchar btmp;
-
- for(j=0;j<8;j++)
- {
- btmp=0x01;
- btmp=btmp<<j;
- btmp=btmp&dat;
- if(btmp>0) // 寫1
- {
- DQ=0;
- Delay15us();
- DQ=1;
- Delay15us();
- Delay15us();
- Delay15us();
- Delay15us();
- }
- else // 寫0
- {
- DQ=0;
- Delay15us();
- Delay15us();
- Delay15us();
- Delay15us();
- DQ=1;
- Delay15us();
- }
- }
- }
- /*********************************************************/
- // 讀取溫度值
- /*********************************************************/
- int DS18B20_ReadTemp(void)
- {
- uchar j;
- int b,temp=0;
- DS18B20_ReSet(); // 產生復位脈
- DS18B20_WriteByte(0xcc); // 忽略ROM指令
- DS18B20_WriteByte(0x44); // 啟動溫度轉換指令
- DS18B20_ReSet(); // 產生復位脈
- DS18B20_WriteByte(0xcc); // 忽略ROM指令
- DS18B20_WriteByte(0xbe); // 讀取溫度指令
- for(j=0;j<16;j++) // 讀取溫度數量
- {
- DQ=0;
- _nop_();
- _nop_();
- DQ=1;
- Delay15us();
- b=DQ;
- Delay15us();
- Delay15us();
- Delay15us();
- b=b<<j;
- temp=temp|b;
- }
-
- temp=temp*0.0625*10; // 合成溫度值并放大10倍
- return (temp); // 返回檢測到的溫度值
- }
- /*********************************************************/
- // 1602液晶寫命令函數,cmd就是要寫入的命令
- /*********************************************************/
- void LcdWriteCmd(uchar cmd)
- {
- LcdRs_P = 0;
- LcdRw_P = 0;
- LcdEn_P = 0;
- P0=cmd;
- DelayMs(2);
- LcdEn_P = 1;
- DelayMs(2);
- LcdEn_P = 0;
- }
- /*********************************************************/
- // 1602液晶寫數據函數,dat就是要寫入的數據
- /*********************************************************/
- void LcdWriteData(uchar dat)
- {
- LcdRs_P = 1;
- LcdRw_P = 0;
- LcdEn_P = 0;
- P0=dat;
- DelayMs(2);
- LcdEn_P = 1;
- DelayMs(2);
- LcdEn_P = 0;
- }
- /*********************************************************/
- // 1602液晶初始化函數
- /*********************************************************/
- void LcdInit()
- {
- LcdWriteCmd(0x38); // 16*2顯示,5*7點陣,8位數據口
- LcdWriteCmd(0x0C); // 開顯示,不顯示光標
- LcdWriteCmd(0x06); // 地址加1,當寫入數據后光標右移
- LcdWriteCmd(0x01); // 清屏
- }
- /*********************************************************/
- // 液晶光標定位函數
- /*********************************************************/
- void LcdGotoXY(uchar line,uchar column)
- {
- // 第一行
- if(line==0)
- LcdWriteCmd(0x80+column);
- // 第二行
- if(line==1)
- LcdWriteCmd(0x80+0x40+column);
- }
- /*********************************************************/
- // 液晶輸出字符串函數
- /*********************************************************/
- void LcdPrintStr(uchar *str)
- {
- while(*str!='\0')
- LcdWriteData(*str++);
- }
- /*********************************************************/
- // 液晶顯示內容的初始化
- /*********************************************************/
- void LcdShowInit()
- {
- LcdGotoXY(0,0);
- LcdPrintStr("20 - - ");
- LcdGotoXY(1,0);
- LcdPrintStr(" : : C");
- LcdGotoXY(1,14); // 溫度單位攝氏度上面的圓圈符號
- LcdWriteData(0xdf);
- }
- /*********************************************************/
- // 液晶輸出數字
- /*********************************************************/
- void LcdPrintNum(uchar num)
- {
- LcdWriteData(num/10+48); // 十位
- LcdWriteData(num%10+48); // 個位
- }
- /*********************************************************/
- // 液晶顯示星期
- /*********************************************************/
- void LcdPrintWeek(uchar week)
- {
- switch(week)
- {
- case 1: LcdPrintStr(" Sun"); break;
- case 2: LcdPrintStr(" Mon"); break;
- case 3: LcdPrintStr("Tues"); break;
- case 4: LcdPrintStr(" Wed"); break;
- case 5: LcdPrintStr("Thur"); break;
- case 6: LcdPrintStr(" Fri"); break;
- case 7: LcdPrintStr(" Sat"); break;
- default: break;
- }
- }
- /*********************************************************/
- // 刷新時間顯示
- /*********************************************************/
- void FlashTime()
- {
- LcdGotoXY(0,2); // 年份
- LcdPrintNum(TimeBuff[0]);
- LcdGotoXY(0,5); // 月份
- LcdPrintNum(TimeBuff[1]);
- LcdGotoXY(0,8); // 日期
- LcdPrintNum(TimeBuff[2]);
- LcdGotoXY(1,0); // 小時
- LcdPrintNum(TimeBuff[4]);
- LcdGotoXY(1,3); // 分鐘
- LcdPrintNum(TimeBuff[5]);
- LcdGotoXY(1,6); // 秒鐘
- LcdPrintNum(TimeBuff[6]);
- LcdGotoXY(0,12); // 星期
- LcdPrintWeek(TimeBuff[3]);
- }
- /*********************************************************/
- // 溫度值的顯示
- /*********************************************************/
- void LcdPrintTemp(int temp)
- {
- if(temp<0)
- {
- LcdWriteData('-'); // 顯示負號
- temp=0-temp; // 負數轉為正數
- }
- else if(temp>999) // 顯示百位
- {
- LcdWriteData(temp/1000+0x30);
- }
- else
- {
- LcdWriteData(' ');
- }
- LcdWriteData(temp%1000/100+0x30); // 顯示十位
- LcdWriteData(temp%100/10+0x30); // 顯示個位
- LcdWriteData('.'); // 顯示小數點
- LcdWriteData(temp%10+0x30); // 顯示小數后一位小數
- }
- /*********************************************************/
- // 初始化DS1302
- /*********************************************************/
- void DS1302_Init(void)
- {
- RST_P=0; // RST腳置低
- SCK_P=0; // SCK腳置低
- SDA_P=0; // SDA腳置低
- }
- /*********************************************************/
- // 從DS1302讀出一字節數據
- /*********************************************************/
- uchar DS1302_Read_Byte(uchar addr)
- {
- uchar i;
- uchar temp;
- RST_P=1;
- /* 寫入目標地址:addr*/
- for(i=0;i<8;i++)
- {
- if(addr&0x01)
- SDA_P=1;
- else
- SDA_P=0;
- SCK_P=1;
- _nop_();
- SCK_P=0;
- _nop_();
- addr=addr>> 1;
- }
- /* 讀出該地址的數據 */
- for(i=0;i<8;i++)
- {
- temp=temp>>1;
- if(SDA_P)
- temp|= 0x80;
- else
- temp&=0x7F;
- SCK_P=1;
- _nop_();
- SCK_P=0;
- _nop_();
- }
- RST_P=0;
- return temp;
- }
- /*********************************************************/
- // 向DS1302寫入一字節數據
- /*********************************************************/
- void DS1302_Write_Byte(uchar addr, uchar dat)
- {
- uchar i;
- RST_P = 1;
- /* 寫入目標地址:addr*/
- for(i=0;i<8;i++)
- {
- if(addr&0x01)
- SDA_P=1;
- else
- SDA_P=0;
- SCK_P=1;
- _nop_();
- SCK_P=0;
- _nop_();
- addr=addr>>1;
- }
- /* 寫入數據:dat*/
- for(i=0;i<8;i++)
- {
- if(dat&0x01)
- SDA_P=1;
- else
- SDA_P=0;
- SCK_P=1;
- _nop_();
- SCK_P=0;
- _nop_();
- dat=dat>>1;
- }
- RST_P=0;
- }
- /*********************************************************/
- // 向DS1302寫入時間數據
- /*********************************************************/
- void DS1302_Write_Time()
- {
- uchar i;
- uchar temp1;
- uchar temp2;
- for(i=0;i<7;i++) // 十進制轉BCD碼
- {
- temp1=(TimeBuff[i]/10)<<4;
- temp2=TimeBuff[i]%10;
- TimeBuff[i]=temp1+temp2;
- }
-
- DS1302_Write_Byte(0x8E,0x00); // 關閉寫保護
- DS1302_Write_Byte(0x80,0x80); // 暫停時鐘
- DS1302_Write_Byte(0x8C,TimeBuff[0]); // 年
- DS1302_Write_Byte(0x88,TimeBuff[1]); // 月
- DS1302_Write_Byte(0x86,TimeBuff[2]); // 日
- DS1302_Write_Byte(0x8A,TimeBuff[3]); // 星期
- DS1302_Write_Byte(0x84,TimeBuff[4]); // 時
- DS1302_Write_Byte(0x82,TimeBuff[5]); // 分
- DS1302_Write_Byte(0x80,TimeBuff[6]); // 秒
- DS1302_Write_Byte(0x80,TimeBuff[6]&0x7F); // 運行時鐘
- DS1302_Write_Byte(0x8E,0x80); // 打開寫保護
- }
- /*********************************************************/
- // 從DS1302讀出時間數據
- /*********************************************************/
- void DS1302_Read_Time()
- {
- uchar i;
- TimeBuff[0]=DS1302_Read_Byte(0x8D); // 年
- TimeBuff[1]=DS1302_Read_Byte(0x89); // 月
- TimeBuff[2]=DS1302_Read_Byte(0x87); // 日
- TimeBuff[3]=DS1302_Read_Byte(0x8B); // 星期
- TimeBuff[4]=DS1302_Read_Byte(0x85); // 時
- TimeBuff[5]=DS1302_Read_Byte(0x83); // 分
- TimeBuff[6]=(DS1302_Read_Byte(0x81))&0x7F; // 秒
- for(i=0;i<7;i++) // BCD轉十進制
- {
- TimeBuff[i]=(TimeBuff[i]/16)*10+TimeBuff[i]%16;
- }
- }
- }
- /*********************************************************/
- // 按鍵掃描(設置時間)
- /*********************************************************/
- void KeyScanf1()
- {
- if(KeySet_P==0)
- {
- LcdWriteCmd(0x0f); // 啟動光標閃爍
- LcdGotoXY(0,3); // 定位光標到年份閃爍
- DelayMs(10); // 延時等待,消除按鍵按下的抖動
- while(!KeySet_P); // 等待按鍵釋放
- DelayMs(10); // 延時等待,消除按鍵松開的抖動
-
- /* 調整年份 */
- while(1)
- {
- if(KeyDown_P==0) // 如果減按鍵被下去
- {
- if(TimeBuff[0]>0) // 判斷年份是否大于0
- TimeBuff[0]--; // 是的話就減去1
- LcdGotoXY(0,2); // 光標定位到年份的位置
- LcdPrintNum(TimeBuff[0]); // 刷新顯示改變后的年份
- LcdGotoXY(0,3); // 定位光標到年份閃爍
- DelayMs(300); // 延時0.3秒左右
- }
-
- if(KeyUp_P==0) // 如果加按鍵被下去
- {
- if(TimeBuff[0]<99) // 判斷年份是否小于99
- TimeBuff[0]++; // 是的話就加上1
- LcdGotoXY(0,2); // 光標定位到年份的位置
- LcdPrintNum(TimeBuff[0]); // 刷新顯示改變后的年份
- LcdGotoXY(0,3); // 定位光標到年份閃爍
- DelayMs(300); // 延時0.3秒左右
- }
-
- if(KeySet_P==0)
- {
- break;
- }
- }
-
- LcdGotoXY(0,6); // 定位光標到月份閃爍
- DelayMs(10); // 延時等待,消除按鍵按下的抖動
- while(!KeySet_P); // 等待按鍵釋放
- DelayMs(10); // 延時等待,消除按鍵松開的抖動
-
- /* 調整月份 */
- while(1)
- {
- if(KeyDown_P==0) // 如果減按鍵被下去
- {
- if(TimeBuff[1]>1) // 判斷月份是否大于1
- TimeBuff[1]--; // 是的話就減去1
- LcdGotoXY(0,5); // 光標定位到月份的位置
- LcdPrintNum(TimeBuff[1]); // 刷新顯示改變后的月份
- LcdGotoXY(0,6); // 定位光標到月份閃爍
- DelayMs(300); // 延時0.3秒左右
- }
-
- if(KeyUp_P==0) // 如果加按鍵被下去
- {
- if(TimeBuff[1]<12) // 判斷月份是否小于12
- TimeBuff[1]++; // 是的話就加上1
- LcdGotoXY(0,5); // 光標定位到月份的位置
- LcdPrintNum(TimeBuff[1]); // 刷新顯示改變后的月份
- LcdGotoXY(0,6); // 定位光標到月份閃爍
- DelayMs(300); // 延時0.3秒左右
- }
-
- if(KeySet_P==0)
- {
- break;
- }
- }
-
- LcdGotoXY(0,9); // 定位光標到日期閃爍
- DelayMs(10); // 延時等待,消除按鍵按下的抖動
- while(!KeySet_P); // 等待按鍵釋放
- DelayMs(10); // 延時等待,消除按鍵松開的抖動
-
- /* 調整日期 */
- while(1)
- {
- if(KeyDown_P==0) // 如果減按鍵被下去
- {
- if(TimeBuff[2]>1) // 判斷日期是否大于1
- TimeBuff[2]--; // 是的話就減去1
- LcdGotoXY(0,8); // 光標定位到日期的位置
- LcdPrintNum(TimeBuff[2]); // 刷新顯示改變后的日期
- LcdGotoXY(0,9); // 定位光標到日期閃爍
- DelayMs(300); // 延時0.3秒左右
- }
-
- if(KeyUp_P==0) // 如果加按鍵被下去
- {
- if(TimeBuff[2]<31) // 判斷日期是否小于31
- TimeBuff[2]++; // 是的話就加上1
- LcdGotoXY(0,8); // 光標定位到日期的位置
- LcdPrintNum(TimeBuff[2]); // 刷新顯示改變后的日期
- LcdGotoXY(0,9); // 定位光標到日期閃爍
- DelayMs(300); // 延時0.3秒左右
- }
-
- if(KeySet_P==0)
- {
- break;
- }
- }
-
- LcdGotoXY(0,15); // 定位光標到星期閃爍
- DelayMs(10); // 延時等待,消除按鍵按下的抖動
- while(!KeySet_P); // 等待按鍵釋放
- DelayMs(10); // 延時等待,消除按鍵松開的抖動
-
- /* 調整星期 */
- while(1)
- {
- if(KeyDown_P==0) // 如果減按鍵被下去
- {
- if(TimeBuff[3]>1) // 判斷星期是否大于1
- TimeBuff[3]--; // 是的話就減去1
- LcdGotoXY(0,12); // 光標定位到星期的位置
- LcdPrintWeek(TimeBuff[3]); // 刷新顯示改變后的星期
- LcdGotoXY(0,15); // 定位光標到星期閃爍
- DelayMs(300); // 延時0.3秒左右
- }
-
- if(KeyUp_P==0) // 如果加按鍵被下去
- {
- if(TimeBuff[3]<7) // 判斷星期是否小于7
- TimeBuff[3]++; // 是的話就加上1
- LcdGotoXY(0,12); // 光標定位到星期的位置
- LcdPrintWeek(TimeBuff[3]); // 刷新顯示改變后的星期
- LcdGotoXY(0,15); // 定位光標到星期閃爍
- DelayMs(300); // 延時0.3秒左右
- }
-
- if(KeySet_P==0)
- {
- break;
- }
- }
- LcdGotoXY(1,1); // 定位光標到小時閃爍
- DelayMs(10); // 延時等待,消除按鍵按下的抖動
- while(!KeySet_P); // 等待按鍵釋放
- DelayMs(10); // 延時等待,消除按鍵松開的抖動
-
- /* 調整小時 */
- while(1)
- {
- if(KeyDown_P==0) // 如果減按鍵被下去
- {
- if(TimeBuff[4]>0) // 判斷小時是否大于0
- TimeBuff[4]--; // 是的話就減去1
- LcdGotoXY(1,0); // 光標定位到小時的位置
- LcdPrintNum(TimeBuff[4]); // 刷新顯示改變后的小時
- LcdGotoXY(1,1); // 定位光標到小時閃爍
- DelayMs(300); // 延時0.3秒左右
- }
-
- if(KeyUp_P==0) // 如果加按鍵被下去
- {
- if(TimeBuff[4]<23) // 判斷小時是否小于23
- TimeBuff[4]++; // 是的話就加上1
- LcdGotoXY(1,0); // 光標定位到小時的位置
- LcdPrintNum(TimeBuff[4]); // 刷新顯示改變后的小時
- LcdGotoXY(1,1); // 定位光標到小時閃爍
- DelayMs(300); // 延時0.3秒左右
- }
-
- if(KeySet_P==0)
- {
- break;
- }
- }
-
- LcdGotoXY(1,4); // 定位光標到分鐘閃爍
- DelayMs(10); // 延時等待,消除按鍵按下的抖動
- while(!KeySet_P); // 等待按鍵釋放
- DelayMs(10); // 延時等待,消除按鍵松開的抖動
-
- /* 調整分鐘 */
- while(1)
- {
- if(KeyDown_P==0) // 如果減按鍵被下去
- {
- if(TimeBuff[5]>0) // 判斷分鐘是否大于0
- TimeBuff[5]--; // 是的話就減去1
- LcdGotoXY(1,3); // 光標定位到分鐘的位置
- LcdPrintNum(TimeBuff[5]); // 刷新顯示改變后的分鐘
- LcdGotoXY(1,4); // 定位光標到分鐘閃爍
- DelayMs(300); // 延時0.3秒左右
- }
-
- if(KeyUp_P==0) // 如果加按鍵被下去
- {
- if(TimeBuff[5]<59) // 判斷分鐘是否小于59
- TimeBuff[5]++; // 是的話就加上1
- LcdGotoXY(1,3); // 光標定位到分鐘的位置
- LcdPrintNum(TimeBuff[5]); // 刷新顯示改變后的分鐘
- LcdGotoXY(1,4); // 定位光標到分鐘閃爍
- DelayMs(300); // 延時0.3秒左右
- }
-
- if(KeySet_P==0)
- {
- break;
- }
- }
-
- LcdGotoXY(1,7); // 定位光標到秒鐘閃爍
- DelayMs(10); // 延時等待,消除按鍵按下的抖動
- while(!KeySet_P); // 等待按鍵釋放
- DelayMs(10); // 延時等待,消除按鍵松開的抖動
-
- /* 調整秒鐘 */
- while(1)
- {
- if(KeyDown_P==0) // 如果減按鍵被下去
- {
- if(TimeBuff[6]>0) // 判斷秒鐘是否大于0
- TimeBuff[6]--; // 是的話就減去1
- LcdGotoXY(1,6); // 光標定位到秒鐘的位置
- LcdPrintNum(TimeBuff[6]); // 刷新顯示改變后的秒鐘
- LcdGotoXY(1,7); // 定位光標到秒鐘閃爍
- DelayMs(300); // 延時0.3秒左右
- }
-
- if(KeyUp_P==0) // 如果加按鍵被下去
- {
- if(TimeBuff[6]<59) // 判斷秒鐘是否小于59
- TimeBuff[6]++; // 是的話就加上1
- LcdGotoXY(1,6); // 光標定位到秒鐘的位置
- LcdPrintNum(TimeBuff[6]); // 刷新顯示改變后的秒鐘
- LcdGotoXY(1,7); // 定位光標到秒鐘閃爍
- DelayMs(300); // 延時0.3秒左右
- }
-
- if(KeySet_P==0)
- {
- break;
- }
- }
-
- /* 退出前的設置 */
- LcdWriteCmd(0x0C); // 關閉光標閃爍
- DS1302_Write_Time(); // 把新設置的時間值存入DS1302芯片
- DelayMs(10); // 延時等待,消除按鍵按下的抖動
- while(!KeySet_P); // 等待按鍵釋放
- DelayMs(10); // 延時等待,消除按鍵松開的抖動
- }
- }
- /*********************************************************/
- // 按鍵掃描(設置鬧鐘)
- /*********************************************************/
- void KeyScanf2()
- {
- if(KeyClock_P==0)
- {
- LcdGotoXY(0,0); // 液晶顯示為鬧鐘設置的界面
- LcdPrintStr("Alarm Clock Set ");
- LcdGotoXY(1,0);
- LcdPrintStr(" : ");
- LcdGotoXY(1,3); // 顯示鬧鐘的小時
- LcdPrintNum(Clock_Hour);
- LcdGotoXY(1,6); // 顯示鬧鐘的分鐘
- LcdPrintNum(Clock_Minute);
- LcdGotoXY(1,10); // 顯示鬧鐘狀態
- if(Clock_Swt==0)
- {
- LcdPrintStr("OFF");
- }
- else
- {
- LcdPrintStr(" ON");
- }
- LcdGotoXY(1,4); // 光標定位
- LcdWriteCmd(0x0f); // 光標閃爍
- DelayMs(10); // 延時等待,消除按鍵按下的抖動
- while(!KeyClock_P); // 等待按鍵釋放
- DelayMs(10); // 延時等待,消除按鍵松開的抖動
-
- /* 調整鬧鐘小時 */
- while(1)
- {
- if(KeyDown_P==0) // 如果減按鍵被下去
- {
- if(Clock_Hour>0) // 判斷鬧鐘小時是否大于0
- Clock_Hour--; // 是的話就減去1
- LcdGotoXY(1,3); // 光標定位到鬧鐘小時的位置
- LcdPrintNum(Clock_Hour); // 刷新顯示改變后的鬧鐘小時
- LcdGotoXY(1,4); // 定位光標到鬧鐘小時閃爍
- DelayMs(300); // 延時0.3秒左右
- }
-
- if(KeyUp_P==0) // 如果加按鍵被下去
- {
- if(Clock_Hour<23) // 判斷鬧鐘小時是否小于23
- Clock_Hour++; // 是的話就加上1
- LcdGotoXY(1,3); // 光標定位到鬧鐘小時的位置
- LcdPrintNum(Clock_Hour); // 刷新顯示改變后的鬧鐘小時
- LcdGotoXY(1,4); // 定位光標到鬧鐘小時閃爍
- DelayMs(300); // 延時0.3秒左右
- }
-
- if(KeyClock_P==0)
- {
- break;
- }
- }
-
- LcdGotoXY(1,7); // 定位光標到鬧鐘分鐘的閃爍
- DelayMs(10); // 延時等待,消除按鍵按下的抖動
- while(!KeyClock_P); // 等待按鍵釋放
- DelayMs(10); // 延時等待,消除按鍵松開的抖動
-
- /* 調整分鐘 */
- while(1)
- {
- if(KeyDown_P==0) // 如果減按鍵被下去
- {
- if(Clock_Minute>0) // 判斷鬧鐘分鐘是否大于0
- Clock_Minute--; // 是的話就減去1
- LcdGotoXY(1,6); // 光標定位到鬧鐘分鐘的位置
- LcdPrintNum(Clock_Minute); // 刷新顯示改變后的鬧鐘分鐘
- LcdGotoXY(1,7); // 定位光標到鬧鐘分鐘閃爍
- DelayMs(300); // 延時0.3秒左右
- }
-
- if(KeyUp_P==0) // 如果加按鍵被下去
- {
- if(Clock_Minute<59) // 判斷鬧鐘分鐘是否小于59
- Clock_Minute++; // 是的話就加上1
- LcdGotoXY(1,6); // 光標定位到鬧鐘分鐘的位置
- LcdPrintNum(Clock_Minute); // 刷新顯示改變后的鬧鐘分鐘
- LcdGotoXY(1,7); // 定位光標到鬧鐘分鐘閃爍
- DelayMs(300); // 延時0.3秒左右
- }
-
- if(KeyClock_P==0)
- {
- break;
- }
- }
-
- LcdGotoXY(1,12); // 定位光標到鬧鐘開關的位置閃爍
- DelayMs(10); // 延時等待,消除按鍵按下的抖動
- while(!KeyClock_P); // 等待按鍵釋放
- DelayMs(10); // 延時等待,消除按鍵松開的抖動
-
- /* 鬧鐘開關 */
- while(1)
- {
- if(KeyDown_P==0) // 如果減按鍵被下去
- {
- if(Clock_Swt==1) // 判斷鬧鐘是否開啟
- Clock_Swt=0; // 關閉鬧鐘
- LcdGotoXY(1,10); // 光標定位到秒鐘開關的位置
- LcdPrintStr("OFF"); // 液晶顯示“OFF”
- LcdGotoXY(1,12); // 定位光標到鬧鐘開關的位置閃爍
- DelayMs(300); // 延時0.3秒左右
- }
-
- if(KeyUp_P==0) // 如果加按鍵被下去
- {
- if(Clock_Swt==0) // 判斷鬧鐘是否關閉
- Clock_Swt=1; // 啟動鬧鐘
- LcdGotoXY(1,10); // 光標定位到秒鐘開關的位置
- LcdPrintStr(" ON"); // 液晶顯示“ ON”
- LcdGotoXY(1,12); // 定位光標到鬧鐘開關的位置閃爍
- DelayMs(300); // 延時0.3秒左右
- }
-
- if(KeyClock_P==0)
- {
- break;
- }
- }
-
- /* 退出前的設置 */
- LcdWriteCmd(0x0C); // 關閉光標閃爍
- LcdShowInit(); // 液晶顯示內容恢復為檢測界面的
- DelayMs(10); // 延時等待,消除按鍵按下的抖動
- while(!KeyClock_P); // 等待按鍵釋放
- DelayMs(10); // 延時等待,消除按鍵松開的抖動
- Sector_Erase(0x2000);
- EEPROM_Write(0x2000,Clock_Hour); // 往0x2000這個地址寫入鬧鐘的小時
- EEPROM_Write(0x2001,Clock_Minute); // 往0x2001這個地址寫入鬧鐘的分鐘
- EEPROM_Write(0x2002,Clock_Swt); // 往0x2002這個地址寫入鬧鐘的開關
- }
- }
- /*********************************************************/
- // 鬧鐘判斷
- /*********************************************************/
- void ClockJudge()
- {
- if(Clock_Swt==1) // 判斷鬧鐘的開關是否開啟
- {
- // 當前小時和分鐘,和鬧鐘的小時和分鐘是否一致
- if((Clock_Hour==TimeBuff[4])&&(Clock_Minute==TimeBuff[5])) {
- if(TimeBuff[6]==0) // 秒數是否等于0
- {
- Buzzer_Flag=1; // 開啟蜂鳴器報警標志
- }
- }
- }
-
- if(TimeBuff[6]==59) // 如果當前秒數為59秒
- {
- Buzzer_Flag=0; // 關閉蜂鳴器報警標志
- }
-
- if((KeyDown_P==0)||(KeyUp_P==0)) // 如果加按鍵或減按鍵被按下
- {
- Buzzer_Flag=0; // 關閉蜂鳴器報警標志
- }
-
- if(Buzzer_Flag==1) // 如果蜂鳴器報警標志為啟動
- {
- Buzzer_P=0; // 啟動蜂鳴器
- DelayMs(100); // 延時0.1秒
- Buzzer_P=1; // 關閉蜂鳴器
- DelayMs(100); // 延時0.1秒
- }
- }
- /*********************************************************/
- // 主函數
- /*********************************************************/
- void main()
- {
- int temp; // 保存溫度值
- LcdInit(); // 執行液晶初始化
- DS1302_Init(); // 時鐘芯片的初始化
- LcdShowInit(); // 液晶顯示內容的初始化
- if(DS1302_Read_Byte(0x81)>=128) // 判斷時鐘芯片是否正在運行
- {
- DS1302_Write_Time(); // 如果沒有,則初始化一個時間
- }
- Clock_Hour=EEPROM_Read(0x2000); // 讀取0x2000這個地址的值賦給鬧鐘的小時變量
- if(Clock_Hour>23) // 如果讀取到的鬧鐘小時值不正常,則重新賦值
- {
- Clock_Hour=12;
- }
- Clock_Minute=EEPROM_Read(0x2001);// 讀取0x2001這個地址的值賦給鬧鐘的分鐘變量
- if(Clock_Minute>59) // 如果讀取到的鬧鐘分鐘值不正常,則重新賦值
- {
- Clock_Minute=30;
- }
- Clock_Swt=EEPROM_Read(0x2002); // 讀取0x2002這個地址的值賦給鬧鐘的開關變量
- if(Clock_Swt>1) // 如果讀取到的鬧鐘開關值不正常,則重新賦值
- {
- Clock_Swt=0;
- }
- while(DS18B20_ReadTemp()==850) // 等待溫度傳感器初始化完成
- {
- DelayMs(10);
- }
- while(1)
- {
- DS1302_Read_Time(); // 獲取當前時鐘芯片的時間,存在數組time_buf中
- FlashTime(); // 刷新時間顯示
- ClockJudge(); // 鬧鐘工作的判斷
-
- temp=DS18B20_ReadTemp(); // 讀取溫度
- LcdGotoXY(1,9); // 定位到顯示溫度的地方
- LcdPrintTemp(temp); // 顯示溫度
- KeyScanf1(); // 按鍵掃描(時間的設置)
- KeyScanf2(); // 按鍵掃描(鬧鐘的設置)
-
- DelayMs(100); // 延時0.1秒
- }
- }
復制代碼
|