該萬年歷具備鬧鐘時間設置,程序和原理圖PCB圖都放在附件里
Altium Designer畫的原理圖和PCB圖如下:(51hei附件中可下載工程文件)
單片機源程序如下:
- #include <reg52.h>
- #include <intrins.h>
- #include "ds1302.h"
- #define uchar unsigned char
- #define uint unsigned int
- //變量定義
- uint count;
- SYSTEMTIME CurrentTime;
- uchar count1=0,count2=0,s1num=0;
- uchar flag=1,flag_rd=0;
- uchar miao,fen,shi,week,day,month,year;
- uchar miao1=0,fen1=0,shi1=0;
- /*12864端口定義*/
- #define LCD_data P1 //數據口
- sbit LCD_RS = P2^7; //寄存器選擇輸入
- sbit LCD_RW = P2^6; //液晶讀/寫控制
- sbit LCD_EN = P2^5; //液晶使能控制
- sbit LCD_PSB = P2^4; //串/并方式控制
- sbit LCD_RST = P2^3; //復位
- //按鍵
- sbit s1=P0^0;
- sbit s2=P0^1;
- sbit s3=P0^2;
- sbit rd=P0^3;
- //蜂鳴器
- sbit beep=P3^7;
- uchar code dis1[] = {"20 年 月 日"};
- uchar code dis2[] = {"當前"};
- uchar code dis3[] = {" 時 分 秒"};
- uchar code dis4[] = {"----萬年歷----"};
- uchar code dis5[] = {"鬧鐘"};
- uchar code day0[] = {"星期日"};
- uchar code day1[] = {"星期一"};
- uchar code day2[] = {"星期二"};
- uchar code day3[] = {"星期三"};
- uchar code day4[] = {"星期四"};
- uchar code day5[] = {"星期五"};
- uchar code day6[] = {"星期六"};
- #define delayNOP(); {_nop_();_nop_();_nop_();_nop_();};
- //uchar IRDIS[2];
- //uchar IRCOM[4];
- void delay(int ms); //延時函數
- bit lcd_busy(); //忙檢測
- void lcd_wcmd(uchar cmd); //寫命令
- void lcd_wdat(uchar dat); //寫數據
- void lcd_init(); //12864初始化
- void DS1302_Getdate(); //獲取當前1302時間
- void keyscan(); //按鍵掃描
- void rd_set(); //鬧鐘設置界面
- void di(); //按鍵提示聲
- void menu_timer(); //時間顯示界面
- void DS1302_Setdate(); //設置1302時間
- void menu(void); //主界面
- void lcd_pos(uchar X,uchar Y); //確定顯示位置
- void time_init(void); //定時器初始化
- void lcd_write_char(uchar x_temp,uchar y_temp,uchar date); //任一位置顯示數字函數
- unsigned char GetWeekFromDay(unsigned char year,unsigned char month,unsigned char day);//計算星期函數
- /*********************************************************/
- /* */
- /* 主程序 */
- /* */
- /*********************************************************/
- void main(void)
- {
- lcd_init(); //初始化LCD
- time_init(); //初始化定時器
- delay(10); //延時
- menu(); //界面
- DS1302_Getdate(); //上電獲取時間
- if(day==0&&month==0);//如果數據錯誤復位為2017年11月2日10時10分10秒
- {
- year=17;
- month=11;
- day=2;
- week=4;
- shi=10;
- fen=10;
- miao=10;
- DS1302_Setdate();
- }
- while(1)
- {
- keyscan();
- if(miao1==CurrentTime.Second&&fen1==CurrentTime.Minute&&shi1==CurrentTime.Hour&&flag_rd==2)
- { //判斷鬧鐘時間,相同則蜂鳴器響5下
- int i;
- for(i=0;i<5;i++)
- {
- delay(200);
- di();
- }
- }
- }
- }
- /*******************************************************************/
- /* */
- /* 延時函數 */
- /* */
- /*******************************************************************/
- void delay(int ms)
- {
- while(ms--)
- {
- uchar i;
- for(i=0;i<250;i++)
- {
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- }
- }
- }
- /*******************************************************************/
- /* */
- /*檢查LCD忙狀態 */
- /*lcd_busy為1時,忙,等待。lcd-busy為0時,閑,可寫指令與數據。 */
- /* */
- /*******************************************************************/
- bit lcd_busy()
- {
- bit result;
- LCD_RS = 0;
- LCD_RW = 1;
- LCD_EN = 1;
- delayNOP();
- result = (bit)(P1&0x80);
- LCD_EN = 0;
- return(result);
- }
- /*******************************************************************/
- /* */
- /*寫指令數據到LCD */
- /*RS=L,RW=L,E=高脈沖,D0-D7=指令碼。 */
- /* */
- /*******************************************************************/
- void lcd_wcmd(uchar cmd)
- {
- while(lcd_busy());
- LCD_RS = 0;
- LCD_RW = 0;
- LCD_EN = 0;
- _nop_();
- _nop_();
- P1 = cmd;
- delayNOP();
- LCD_EN = 1;
- delayNOP();
- LCD_EN = 0;
- }
- /*******************************************************************/
- /* */
- /*寫顯示數據到LCD */
- /*RS=H,RW=L,E=高脈沖,D0-D7=數據。 */
- /* */
- /*******************************************************************/
- void lcd_wdat(uchar dat)
- {
- while(lcd_busy());
- LCD_RS = 1;
- LCD_RW = 0;
- LCD_EN = 0;
- P1 = dat;
- delayNOP();
- LCD_EN = 1;
- delayNOP();
- LCD_EN = 0;
- }
- /*******************************************************************/
- /* */
- /* LCD初始化設定 */
- /* */
- /*******************************************************************/
- void lcd_init()
- {
- LCD_PSB = 1; //并口方式
- LCD_RST = 1;
- lcd_wcmd(0x34); //擴充指令操作
- delay(5);
- lcd_wcmd(0x30); //基本指令操作
- delay(5);
- lcd_wcmd(0x0C); //顯示開,關光標
- delay(5);
- lcd_wcmd(0x01); //清除LCD的顯示內容
- delay(5);
- }
- /*********
- 從ds1302中讀取當前時間
- *********/
- void DS1302_Getdate()
- {
- miao=CurrentTime.Second;
- fen=CurrentTime.Minute;
- shi=CurrentTime.Hour;
- week=CurrentTime.Week;
- day=CurrentTime.Day;
- month=CurrentTime.Month;
- year=CurrentTime.Year;
- }
- /********
- 按鍵檢測
- 邏輯過于復雜,不解釋
- ********/
- void keyscan()
- {
- if(s1==0)
- {
- delay(5);
- if(s1==0)
- {
- s1num++;
- while(!s1);
- di();
- if(s1num==1)
- {
- flag=0;
- DS1302_Getdate();
- DS1302_TimeStop(1); // 是否將時鐘停止 1為停止 0為繼續
- lcd_pos(2,6);
- lcd_wcmd(0x0F); //顯示開,開光標
- }
- if(s1num==2)
- {
- lcd_pos(2,4);
- }
- if(s1num==3)
- {
- lcd_pos(2,2);
- }
- if(s1num==4)
- {
- lcd_pos(0,5);
- }
- if(s1num==5)
- {
- lcd_pos(0,3);
- }
- if(s1num==6)
- {
- lcd_pos(0,1);
- }
- if(s1num==7)
- {
- s1num=0;
- flag=1;
- Initial_DS1302();
- week=GetWeekFromDay(year,month,day);
- DS1302_Setdate();
- DS1302_TimeStop(0); // 是否將時鐘停止 1為停止 0為繼續
- lcd_wcmd(0x0C); //顯示開,關光標
- }
- }
- }
- if(s1num!=0)
- {
- if(s2==0)
- {
- delay(5);
- if(s2==0)
- {
- while(!s2);
- di();
- if(s1num==1)
- {
- miao++;
- if(miao==60)
- miao=0;
- lcd_write_char(2,6,miao);
- lcd_pos(2,6);
- }
- if(s1num==2)
- {
- fen++;
- if(fen==60)
- fen=0;
- lcd_write_char(2,4,fen);
- lcd_pos(2,4);
- }
- if(s1num==3)
- {
- shi++;
- if(shi==24)
- shi=0;
- lcd_write_char(2,2,shi);
- lcd_pos(2,2);
- }
- if(s1num==4)
- {
- day++;
- if(day==32)
- day=1;
- lcd_write_char(0,5,day);
- lcd_pos(0,5);
- }
- if(s1num==5)
- {
- month++;
- if(month==13)
- month=1;
- lcd_write_char(0,3,month);
- lcd_pos(0,3);
- }
- if(s1num==6)
- {
- year++;
- if(year==99)
- year=0;
- lcd_write_char(0,1,year);
- lcd_pos(0,1);
- }
- }
- }
- if(s3==0)
- {
- delay(5);
- if(s3==0)
- {
- while(!s3);
- di();
- if(s1num==1)
- {
- miao--;
- if(miao==-1)
- miao=59;
- lcd_write_char(2,6,miao);
- lcd_pos(2,6);
- }
- if(s1num==2)
- {
- fen--;
- if(fen==-1)
- fen=59;
- lcd_write_char(2,4,fen);
- lcd_pos(2,4);
- }
- if(s1num==3)
- {
- shi--;
- if(shi==-1)
- shi=23;
- lcd_write_char(2,2,shi);
- lcd_pos(2,2);
- }
- if(s1num==4)
- {
- day--;
- if(day==0)
-
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
所有資料51hei提供下載:
程序及原理圖和pcb圖.zip
(117.49 KB, 下載次數: 295)
2017-12-11 21:22 上傳
點擊文件名下載附件
|