该万年历具备闹钟时间设置,程序和原理图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)
|