单片机万年历仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
单片机源码:
- #include<reg52.h>
- #include"LCD12864.h"
- #include"ds1302.h"
- #include"temp.h"
- sbit K1=P3^4;
- sbit K2=P3^5;
- sbit K3=P3^6;
- sbit K4=P3^7;
- sbit beep=P1^6;
- void LCD12864_Delay1ms(uint c); // 延时
- void Delay10ms();
- uchar LCD12864_Busy(void); //LCD忙检测
- void LCD12864_WriteCmd(uchar cmd);
- void LCD12864_WriteData(uchar dat);
- void LCD12864_Init();
- void LCD12864_ClearScreen();
- void hanzi(uchar ye,uchar lie,uchar *daima); //LCD显示汉字
- void shuzi(uchar ye,uchar lie,uchar *daima); //LCD显示数字
- void hanzif(uchar ye,uchar lie,uchar *daima); //LCD显示汉字反白
- void shuzif(uchar ye,uchar lie,uchar *daima); //LCD显示数字反白
- void tupiandisplay(); //图片显示
- void display(); //LCD显示
- void IntConfiguration(); //外部中断配置
- void zhuanhuan(int temp); //18B20 BCD码转换
- //void beepsound(); //蜂鸣器响
- void clockdisplay(); //闹钟界面显示
- unsigned char SetState,SetState1,flag; //标志变量
- char SetPlace=-1,SetPlace1=-1; //设置参数,因为中断的时候就会先加1,所以开始设为-1
- unsigned char datas[]={0,0,0}; //温度值存储参数
- extern char TIME[7]; // 1302时间值存储参数,存储顺序是秒分时日月周年,存储格式是用BCD码
- char TIME1[4] = {0,0,12,0}; //闹钟时间值存储参数
- void main()
- {
- unsigned char s;
- LCD12864_Init(); //LCD12864初始化
- LCD12864_ClearScreen(); //清屏
- // tupiandisplay(); //开机图片显示
- // LCD12864_Delay1ms(1000);
- // LCD12864_ClearScreen();
- Ds1302Init(); //Ds1302初始化
- IntConfiguration(); //外部中断设置
- while(1)
- {
- if((SetState==0)&&(flag==0))
- {
- Ds1302ReadTime();
- display();
- }
- if((SetState==1)&&(flag==0)) //调时,SetState是调时标志,SetState=1表示处于调时状态
- {
-
- switch(SetPlace) //反白显示处于的位置
- {
-
- case(0):
-
- Right(); //秒数反白,调秒
- shuzif(4,0,num[TIME[0]/16]);
- shuzif(4,8,num[TIME[0]%16]);
- break;
-
-
- case(1):
-
- Left(); //分数反白
- shuzif(4,32,num[TIME[1]/16]);
- shuzif(4,40,num[TIME[1]%16]);
- break;
- case(2):
-
- Left(); //小时反白
- shuzif(4,0,num[TIME[2]/16]);
- shuzif(4,8,num[TIME[2]%16]);
- break;
- case(3):
-
- Right(); //日期反白
- shuzif(0,16,num[TIME[3]/16]);
- shuzif(0,24,num[TIME[3]%16]);
- break;
- case(4):
-
- Left(); //月反白
- shuzif(0,48,num[TIME[4]/16]);
- shuzif(0,56,num[TIME[4]%16]);
- break;
- case(5):
- Left(); //星期反白
- hanzif(2,32,num1[TIME[5]%16]);
- break;
- case(6):
- Left(); //年反白
- shuzif(0,16,num[TIME[6]/16]);
- shuzif(0,24,num[TIME[6]%16]);
- break;
- }
-
-
- if(K2==0) //检测按键K2是否按下
- {
- Delay10ms(); //消除抖动
- if(K2==0)
- {
- TIME[SetPlace]++;
- if((TIME[SetPlace]&0x0f)>9) // TIME[]是BCD码格式的,BCD码低四位最多到9,即00001001(0x09BCD),当再进一位时,变为00010000(0x10BCD)而不是00001010
- { //00001010十进制数实际为10,而00010000实际为16,相差了6。下面的情况同理
- TIME[SetPlace]=TIME[SetPlace]+6;
- }
- if((TIME[SetPlace]>=0x60)&&(SetPlace<2)) //秒只能到59
- {
- TIME[SetPlace]=0;
- }
-
- if((TIME[SetPlace]>=0x24)&&(SetPlace==2)) //小时只能到23
- {
- TIME[SetPlace]=0;
- }
- if((TIME[SetPlace]>=0x32)&&(SetPlace==3)) //日只能到31
- {
- TIME[SetPlace]=0;
- }
- if((TIME[SetPlace]>=0x13)&&(SetPlace==4)) //月只能到12
- {
- TIME[SetPlace]=0;
- }
- if((TIME[SetPlace]>0x6)&&(SetPlace==5)) //周只能到7
- {
- TIME[SetPlace]=0;
- }
- if((TIME[SetPlace]>=0x99)&&(SetPlace==6)) //这里的年位数最多到99
- {
- TIME[SetPlace]=0x99;
- }
-
- }
-
- while((K2==0)); //检测按键是否松开
-
- }
-
- if(K3==0) //检测按键K3是否按下
- {
- Delay10ms(); //消除抖动
- if(K3==0)
- {
-
- TIME[SetPlace]--;
- if((TIME[SetPlace]&0x0f)==0x0f) // 比如BCD码为10的数二进制为0001 0000。再减1,则为0000 1111。此时BCD码应为09,但实际的为15,差了6.
- {
- TIME[SetPlace]=TIME[SetPlace]-6;
- }
- if((TIME[SetPlace]<0x00)&&(SetPlace<2)) //分秒只能到59
- {
- TIME[SetPlace]=89; //59BCD的十进制为89.
- }
- if((TIME[SetPlace]<0x00)&&(SetPlace==2)) //小时只能到23
- {
- TIME[SetPlace]=35; //23BCD的十进制为35
- }
- if((TIME[SetPlace]==0x00)&&(SetPlace==3)) //日只能到31
- {
- TIME[SetPlace]=49; //32BCD的十进制为49
- }
- if((TIME[SetPlace]==0x00)&&(SetPlace==4)) //月只能到12
- {
- TIME[SetPlace]=18; //12BCD的十进制为18
- }
- if((TIME[SetPlace]<0x00)&&(SetPlace==5)) //周只能到7
- {
- TIME[SetPlace]=6; //7BCD的十进制为7
- }
-
- if((TIME[SetPlace]<=0x00)&&(SetPlace==6)) //年只能到0-99
- {
- TIME[SetPlace]=0x00;
- }
-
- }
-
- while((K3==0)); //检测按键是否松开
- }
-
- display();
- }
-
- if(flag==1) //调闹钟,flag是闹钟标志,当flag=1表示进入闹钟界面
- {
- LCD12864_ClearScreen();
- while(flag==1)
- {
- switch(SetPlace1) //反白显示位置,与调时类似
-
- {
- case(0):
-
- Right(); //秒数反白
- shuzif(2,16,num[TIME1[0]/10]);
- shuzif(2,24,num[TIME1[0]%10]);
- break;
- case(1):
-
- Left(); //分数反白
- shuzif(2,48,num[TIME1[1]/10]);
- shuzif(2,56,num[TIME1[1]%10]);
- break;
- case(2):
-
- Left(); //小时反白
- shuzif(2,16,num[TIME1[2]/10]);
- shuzif(2,24,num[TIME1[2]%10]);
- break;
-
- case(3):
- Right();
- hanzif(0,0,num2[TIME1[6]]);
- break;
- }
- if(K2==0)
- {
- Delay10ms(); //消除抖动
- if(K2==0)
- {
- TIME1[SetPlace1]++;
- if((TIME1[SetPlace1]==60)&&(-1<SetPlace1<2)) //秒分最多到59
- {
- TIME1[SetPlace1]=0;
- }
-
- if((TIME1[SetPlace1]==24)&&(SetPlace1==2))
- {
- TIME1[SetPlace1]=0; //小时最多到23
- }
- if((TIME1[SetPlace1]==2)&&(SetPlace1==3)) //关和开,0表示关,1表示开
- {
- TIME1[SetPlace1]=0;
- LCD12864_Delay1ms(1);
- }
- }
- while((K2==0)); //检测按键是否松开
- }
-
- if(K3==0)
- {
- Delay10ms(); //消除抖动
- if(K3==0)
- {
- TIME1[SetPlace1]--;
- if((TIME1[SetPlace1]<0)&&(SetPlace1==0)) //秒减到0后变为59
- {
- TIME1[SetPlace1]=59;
- }
- if((TIME1[SetPlace1]<0)&&(SetPlace1==1)) //分
- {
- TIME1[SetPlace1]=59;
- }
- if((TIME1[SetPlace1]<0)&&(SetPlace1==2)) //小时
- {
- TIME1[SetPlace1]=23;
- }
- if((TIME1[SetPlace1]<0)&&(SetPlace1==3)) //关和开
- {
- TIME1[SetPlace1]=1;
- LCD12864_Delay1ms(1);
- }
- }
- while((K3==0)); //检测按键是否松开
- }
- clockdisplay(); //闹钟界面显示
-
- }
- LCD12864_ClearScreen(); //清屏
- }
- for(s=1;s<3;s++)
- if((TIME[s]==TIME1[s])&&(TIME1[3]==1))
- {
- beep=0;
- LCD12864_Delay1ms(500);
- beep=1;
- LCD12864_Delay1ms(500);
- }
- else{
- beep=1;
- }
- /* for(s=1;s<3;s++)
- {
- if((TIME[s]==TIME1[s])&&(TIME1[3]==1)) //闹钟到时,即小时和分相等时,显闹钟在开状态
- {
- beepsound(); //响蜂鸣器,响1分钟,当分钟不相等时,自动退出
- // LCD12864_Delay1ms(10000);
- }
- else;
-
- }*/
- }
- }
- /*******************************************************************************
- * 函数名 : LcdDisplay()
- * 函数功能 : 显示函数
- * 输入 : 无
- * 输出 : 无
- *******************************************************************************/
- void display()
- {
-
- Left(); //左半屏
- shuzi(0,0,num[2]);
- shuzi(0,8,num[0]); //年
- shuzi(0,16,num[TIME[6]/16]);
- shuzi(0,24,num[TIME[6]%16]);
- hanzi(0,32,nian);
- shuzi(0,48,num[TIME[4]/16]); //月
- shuzi(0,56,num[TIME[4]%16]);
-
- hanzi(2,0,xing);
- hanzi(2,16,qi);
- hanzi(2,32,num1[TIME[5]%16]); //星期
- shuzi(4,0,num[TIME[2]/16]);
- shuzi(4,8,num[TIME[2]%16]); //时
- hanzi(4,16,shi);
- shuzi(4,32,num[TIME[1]/16]); //分
- shuzi(4,40,num[TIME[1]%16]);
- hanzi(4,48,fen);
- zhuanhuan(Ds18b20ReadTemp()); //显示温度
- shuzi(6,0,num[datas[0]]);
- shuzi(6,8,num[datas[1]]);
- shuzi(6,16,dian); //小数点
- shuzi(6,24,num[datas[2]]);
- hanzi(6,32,fuhao); //℃
- Right(); //右半屏
- hanzi(0,0,yue);
- shuzi(0,16,num[TIME[3]/16]); //日期
- shuzi(0,24,num[TIME[3]%16]);
- hanzi(0,32,ri);
- shuzi(4,0,num[TIME[0]/16]); //秒
- shuzi(4,8,num[TIME[0]%16]);
- hanzi(4,16,miao);
- }
- /*******************************************************************************
- * 函数名 : IntConfiguration()
- * 函数功能 : 配置外部中断0和中断1
- * 输入 : 无
- * 输出 : 无
- *******************************************************************************/
- void IntConfiguration()
- {
- //设置INT0
- IT0=1;//跳变沿出发方式(下降沿)
- EX0=1;//打开INT0的中断允许。
- //设置INT1
- IT1=1;
- EX1=1;
- EA=1;//打开总中断
- }
- /*******************************************************************************
- * 函数名 : Int0()
- * 函数功能 : 外部中断0 中断函数
- * 输入 : 无
- * 输出 : 无
- *******************************************************************************/
- void Int0() interrupt 0
- {
- // Delay10ms();
- if((K1==0)&&(flag==0)) // 调时
- {
- Delay10ms(); //消除抖动
- if((K1==0)&&(flag==0))
- {
- SetState=1;
- Ds1302Init();
-
- SetPlace++;
- if(SetPlace==7) //时间选择键,按一次移一位,从0-7最多8位
- {
- SetPlace=0;
- }
- }
- while(K1==0); //检测按键是否松开
- }
-
- }
- /*******************************************************************************
- * 函数名 : Int1()
- * 函数功能 : 外部中断1 中断函数
- * 输入 : 无
- * 输出 : 无
- *******************************************************************************/
- void Int1() interrupt 2
- {
-
- if((K4==0)&&(SetState==1)) //确定
- {
- Delay10ms(); //消除抖动
- if((K4==0)&&(SetState==1))
- {
- SetState=0;
- Ds1302Init();
- }
-
- while(K4==0); //检测按键是否松开
- }
- if((K4==0)&&(SetState==0)) //调闹钟
- {
- Delay10ms();
- if((K4==0)&&(SetState==0))
- {
- flag=1; //闹钟标志
- SetPlace1++;
- if(SetPlace1==4)
- ……………………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei提供下载:
不带字库.zip
(100.61 KB, 下载次数: 138)
|