|
/*************************************************************************************
* 實驗:萬年歷(DS1302、LCD1602、AT24C04的綜合應用)
* 步驟及現象:程序下載前,stc-isp選擇IRC頻率:12MHz,程序下載后,LCD1602顯示時間‘第一
* 行:“12:00:00 2”,第二行:"2019.01.01 0" ’。第一行最右側的2是周二
* (有效范圍2000~2100年);第二行最右側0是關閉鬧鐘,若是1,則開啟鬧鐘,若是2,則
* 第一行顯示鬧鐘時間,而不是時鐘時間。鬧鐘開關及鬧鐘時間顯示的位選鍵是按鍵5。
* (1)若設置時分秒(按鍵1是位選,按鍵2是加,按鍵3是減)。按按鍵1,小時的那兩位每0.5s
* 閃爍一次,表示可以對時的值按按鍵2一次加1或按按鍵3一次減1;再按按鍵1,分鐘的那兩
* 位每0.5s閃爍一次,表示可以對分的值進行加或減;再按按鍵1,秒的那兩位每0.5s閃爍一
* 次,表示可以對秒進行加或減。再按按鍵1或按按鍵0,退出設置模式。
* (2)若設置年月日(按鍵0是位選,按鍵2是加,按鍵3是減)。按按鍵0,年的前兩位每0.5s閃爍
* 一次,表示可以對年前兩位的值進行加或減;再按按鍵0,年的后兩位每0.5s閃爍一次,表示
* 可以對年后兩位的值進行加或減;再按按鍵0,月的兩位每0.5s閃爍一次,表示可以對月的
* 值進行加或減;再按按鍵0,日的兩位每0.5s閃爍一次,表示可以對日的值進行加或減。再
* 按按鍵0或按按鍵1,退出設置模式。
* (3)若設置鬧鐘(按鍵4是位選鍵,按鍵2是加,按鍵3是減)。現象和(1)一樣。(若開啟鬧鐘
* 后,到達鬧鐘時間,鬧鐘鳴叫,而無人去關閉鬧鐘,則鬧鐘從響應時間開始,鳴叫5s后,自
* 動關閉,下次時間到達后仍會提醒。)鬧鐘初始化時間"12:01:00"
*************************************************************************************/
- #include <stc8.h>
- #include "ds1302.h"
- #include "display.h"
- #include "key.h"
- #include "settime.h"
- #include "timer0.h"
- #include "1602.h"
- #include "i2c.h"
- #include "delay.h"
- sbit speaker = P1^3; // 蜂鳴器
- char TIMED[7]; // 用于接收ds1302中的數據,轉化為有符號類型,便于界限判定
- unsigned char alarm[3]={0,1,12}; // 存放鬧鐘時間(12:01:00鬧鐘初始化時間)
- unsigned int num2=0; // 用于無人關鬧鐘時,計數,當達到5s后,把鬧鐘響應標志置0
- unsigned char Aflag = 0; // 鬧鐘開關及鬧鐘時間顯示標志
- bit Hflag=0, Tflag=0, Sflag=0; // Hflag閃爍標志,Tflag鬧鐘響應標志,Sflag清鬧鐘響應標志標志
- void main()
- {
- unsigned char keys, i;
- P1M1=0x00;P1M0=0x08; // 蜂鳴器配置為強推挽輸出
- speaker = 1; // 關閉蜂鳴器
- Ds1302Init(); // ds1302初始化
- LCD_Init(); // LCD1602初始化
- Timer0Init(); // 定時器0初始化
- for(i=0;i<3;i++) // 實驗板第一次下載或復位后,往AT24C04中寫入鬧鐘初始化時間
- {
- write_24c04(0x00+i,alarm[i]);
- Delay_ms(1);
- }
- while(1)
- {
- keys = key_scan(); // 獲取按鍵按鍵值
- for(i=0;i<3;i++) // 工作后,讀出已存入AT24C04中的鬧鐘時間
- {
- alarm[i] = read_24c04(0x00+i);
- Delay_ms(1);
- }
- settime(keys); // 設置時間及鬧鐘時間函數,keys=0,設置年月日,keys=1,設置時分秒,keys=4,設置鬧鐘時間
- Display(); // 工作狀態下1602顯示函數
- if(keys == 5) // 通過按鍵5設置是否開啟鬧鐘,Aflag=1開啟,Aflag=0關閉,Aflag=2查看鬧鐘時間
- {
- Aflag++;
- if(Aflag==3) // Aflag累加到3后,歸零
- Aflag = 0;
- }
- if((Aflag==1)&&(TIME[0]==alarm[0])&&(TIME[1]==alarm[1])&&(TIME[2]==alarm[2]))
- { // 判斷是否滿足鬧鐘鳴叫條件
- Tflag = 1; // 鬧鐘鳴叫標志置1
- num2 = 0; // 鳴叫計數歸零
- Sflag = 0; // 清鬧鐘鳴叫標志置0
- }
- if((Tflag == 1)&&(Aflag == 1))// 鳴叫需同時滿足鳴叫標志為1、鬧鐘開啟
- {
- speaker = ~speaker;
- if(Sflag == 1) // 判斷鳴叫時間是否到5s了
- Tflag = 0; // 5s后,鳴叫標志清0
- }
- else
- {
- speaker = 0; // 關閉蜂鳴器
- Tflag = 0;
- }
- }
- }
- void TM0_Isr() interrupt 1 using 1
- {
- static unsigned char num1=0;
- num1++; // 進一次中斷值加1,5ms進一次中斷
- if(Tflag == 1) // 到鬧鐘時間后,num2開始累加
- {
- num2++;
- }
- if(100 == num1) // 選中要調整的時間后,代表這個時間的兩位開始每0.5s閃爍一次
- {
- num1 = 0;
- Hflag = ~Hflag; // 閃爍標志翻轉
- }
- if(1000 == num2) // 鬧鐘無人關時,鳴叫5s后,自動關閉鬧鐘,下次時間到時仍會鳴叫
- {
- num2 = 0;
- Sflag = 1; // 清鬧鐘標志標志置1
- }
- }
復制代碼
[我是在我之前發的貼子的基礎上,加了鬧鐘和星期,同時把調整時間選中位改成了閃爍。這個鏈接是我修改前的模板:(想挑戰自己的就拿這個改,看能不能改成我現在這個版本)ds1302用1602實現時間顯示及調整的單片機代碼
http://www.zg4o1577.cn/bbs/dpj-164635-1.html
(出處: 單片機論壇)
|
|