万年历单片机电路及程序
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
单片机源程序如下:
- #include<reg52.h>
- #include<intrins.h>
- #define uchar unsigned char
- #define uint unsigned int
- uchar code digit[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
- unsigned char data year,month,day,hour,min,sec,sec100,n;//年、月、日、时、分、秒、百分之一秒
- sbit TS = P2^4; //调整键调时
- sbit SS = P2^5; //调整键上升
- sbit XJ = P2^6; //调整键下降
- sbit TW = P2^7; //调整键调位
- void delay1ms( uint x); //延时程序
- void pro_timedate();//时间和日期处理程序
- bit leap_year();//闰年的计算
- void display_Year(year); //显示年
- void display_Month(month);//显示月
- void display_Day(day);//显示日
- void display_Hour(hour);//显示时
- void display_Min(min);//显示分
- void display_Sec(sec);//显示秒
- void dispaly_time();//时间显示
- void TSkeypros(); //调时按键扫描
- void pro_key(); // 设置按键处理程序
- void year_adjust(); // 年调整程序
- void month_adjust(); // 月调整程序
- void day_adjust(); // 日调整程序
- void hour_adjust(); // 时调整程序
- void min_adjust(); // 分调整程序
-
- // 延时程序
- void delay1ms( uint x)
- {
- uchar i,j;
- for(i=x;i>0;i--)
- for(j=124;j>0;j--);
- }
- //Timer0中断处理程序,秒的产生
- void timer0() interrupt 1
- {
- TH0=0xdc; //Timer0置10ms定时初值dc00H(2^16=65536D,dc00H=56320D)
- TL0=0x00; //定时时间=(65536-56320)*(1/11.0592)*12=10ms (f0=11.0592Mhz)
- sec100++;
- n++;
- if(n>=2) //1秒时间 (100*10ms=1000ms=1s)
- {n = 0;
- dispaly_time();//调用时间显示程序
- }
- if(sec100 >= 100) //1秒时间 (100*10ms=1000ms=1s)
- {sec100 = 0;
-
- pro_timedate();//调用时间和日期处理程序
- }
- }
- //时间和日期处理程序
- void pro_timedate()
- {
- sec++;
- if(sec > 59)
- {sec = 0;
- min++;
- if(min>59)
- {min=0;
- hour++;
- if(hour>23)
- {hour=0;
- day++;
- if (month==1||month==3||month==5||month==7||month==8||month==10||month==12)
- if (day>31) {day=1;month++;} //大月31天
- if (month==4||month==6||month==9||month==11)
- if (day>30) {day=1;month++;} //小月30天
- if (month==2)
- {if( leap_year()) //闰年的条件
- {if (day>29) {day=1;month++;}} //闰年2月为29天
- else
- {if (day>28) {day=1;month++;}} //平年2月为28天
- }
- if (month>12) {month=1;year++;}
- if (year>99) year=0;
- }
- }
- }
- }
- //闰年的计算
- bit leap_year()
- {
- bit leap;
- if((year%4==0&&year%100!=0)||year%400==0)//闰年的条件
- leap=1;
- else
- leap=0;
- return leap;
- }
- //主程序,初始化及初值设定
- void main()
- {
- P0=0;
- P1=0;
- hour=10;min=30;sec=0; //开机时的时,分,秒显示
- year=11; month=5;day=9; //开机时的年,月,日,星期显示
- IE = 0x8f; //CPU开中断,INT0,INT1,Timer0,Timer1开中断
- IP = 0x04; //设置INT0为中断最高优先级
- IT0=0;IT1=0; //外部INT0,INT1设置为电平触发方式(注意,触发不要选边沿方式,易误动)
- TMOD = 0x11; //Timer0,Timer1工作于模式1, 16位定时方式
- TH0 = 0xdc;TL0 = 0x00; //Timer0置10ms定时初值
- TH1 = 0xff;TL1 = 0x00; //Timer1置初值
- TR0 = 1; //Timer0启动
- TR1 = 0;
- while(1)
- {
- TSkeypros();
- }
- }
- void display_Year(year) //显示年
- {
- uchar i,j;
- i=year/10;
- j=year%10;
- P0=digit[2];
- P1=0;
- delay1ms(4);
- P0=0;
- P0=digit[0];
- P1=1;
- delay1ms(4);
- P0=0;
- P0=digit[i];
- P1=2;
- delay1ms(4);
- P0=0;
- P0=digit[j];
- P1=3;
- delay1ms(4);
- P0=0;
- }
- void display_Month(month) //显示月
- {
- uchar i,j;
- i=month/10;
- j=month%10;
- P0=digit[i];
- P1=4;
- delay1ms(4);
- P0=0;
- P0=digit[j];
- P1=5;
- delay1ms(4);
- P0=0;
- }
- void display_Day(day) //显示日
- {
- uchar i,j;
- i=day/10;
- j=day%10;
- P0=digit[i];
- P1=6;
- delay1ms(4);
- P0=0;
- P0=digit[j];
- P1=7;
- delay1ms(4);
- P0=0;
- }
- void display_Hour(hour) //显示时
- {
- uchar i,j;
- i=hour/10;
- j=hour%10;
- P0=digit[i];
- P1=8;
- delay1ms(4);
- P0=0;
- P0=digit[j];
- P1=9;
- delay1ms(4);
- P0=0;
- }
- void display_Min(min) //显示分
- {
- uchar i,j;
- i=min/10;
- j=min%10;
- P0=digit[i];
- P1=10;
- delay1ms(4);
- P0=0;
- P0=digit[j];
- P1=11;
- delay1ms(4);
- P0=0;
- }
- void display_Sec(sec) //显示秒
- {
- uchar i,j;
- i=sec/10;
- j=sec%10;
- P0=digit[i];
- P1=12;
- delay1ms(4);
- P0=0;
- P0=digit[j];
- P1=13;
- delay1ms(4);
- P0=0;
- }
- void dispaly_time()//时间显示
- {
- display_Year(year);
- display_Month(month);
- display_Day(day);
- display_Hour(hour);
- display_Min(min);
- display_Sec(sec);
- P0=0;
- }
- void TSkeypros() //调时按键扫描
- {
- if(TS==0) //检测按键TS是否按下
- {
- delay1ms(10); //消除抖动10ms
- if(TS==0) //再次判断按键是否按下
- {
- while(!TS); //检测按键是否松开
- }
- pro_key(); // 调用设置按键处理程序
- }
- }
- void pro_key() // 设置按键处理程序
- {
- year_adjust();
-
- }
- void year_adjust() // 年调整程序
- {
- if (SS==0)
- {
- delay1ms(10); //消除抖动10ms
- if(SS==0) //再次判断按键是否按下
- {
- while(!SS); //检测按键是否松开
- }
- year++;
- if (year> 99) year= 0;
- }
- else
- {if (XJ==0)
- {
- delay1ms(10); //消除抖动10ms
- if(XJ==0) //再次判断按键是否按下
- {
- while(!XJ); //检测按键是否松开
- }
- year--;
- if (year>100) year= 99;
- }
- }
- if (TW==0)
- {
- delay1ms(10); //消除抖动10ms
- if(TW==0) //再次判断按键是否按下
- {
- while(!TW); //检测按键是否松开
- }
- month_adjust();
- }
- year_adjust();
- }
- void month_adjust() // 月调整程序
- {
- if (SS==0)
- {
- delay1ms(10); //消除抖动10ms
- if(SS==0) //再次判断按键是否按下
- {
- while(!SS); //检测按键是否松开
- }
- month++;
- if (month> 12) month= 1;
- }
- else
- {if (XJ==0)
- {
- delay1ms(10); //消除抖动10ms
- if(XJ==0) //再次判断按键是否按下
- {
- while(!XJ); //检测按键是否松开
- }
- month--;
- if (month<1) month= 12;
- }
- }
- if (TW==0)
- {
- delay1ms(10); //消除抖动10ms
- if(TW==0) //再次判断按键是否按下
- {
- while(!TW); //检测按键是否松开
- }
- day_adjust();
- }
- month_adjust();
- }
- void day_adjust() // 日调整程序
- {
- if (SS==0)
- {
- delay1ms(10); //消除抖动10ms
- if(SS==0) //再次判断按键是否按下
- {
- while(!SS); //检测按键是否松开
- }
- day++;
- if (month==1||month==3||month==5||month==7||month==8||month==10||month==12)
- if (day>31) day=1; //大月31
- if (month==4||month==6||month==9||month==11)
- if (day>30) day=1; //小月30
- if (month==2)
- {
- if(leap_year()) // 闰年条件
- {
- if (day>29) day=1; // 闰年29
- }
- else
- {
- if (day>28) day=1; //平年28
- }
- }
- }
- else
- {if (XJ==0)
- {
- delay1ms(10); //消除抖动10ms
- if(XJ==0) //再次判断按键是否按下
- {
- while(!XJ); //检测按键是否松开
- }
- day--;
- if (month==1||month==3||month==5||month==7||month==8||month==10||month==12)
- if (day<1) day=31; //大月31
- if (month==4||month==6||month==9||month==11)
- if (day<1) day=30; //小月30
- if (month==2)
- {
- if(leap_year()) // 闰年条件
- {
- if (day<1) day=29; // 闰年29
- }
- else
- {
- if (day<1) day=28; //平年28
- }
- }
- }
- }
- if (TW==0)
- {
- delay1ms(10); //消除抖动10ms
- if(TW==0) //再次判断按键是否按下
- {
- while(!TW); //检测按键是否松开
- }
- hour_adjust();
- }
- day_adjust();
- }
- void hour_adjust() // 时调整程序
- {
- if (SS==0)
- {
- delay1ms(10); //消除抖动10ms
- if(SS==0) //再次判断按键是否按下
- {
- while(!SS); //检测按键是否松开
- }
- hour++;
- if (hour> 23) hour= 0;
- }
- else
- {if (XJ==0)
- {
- delay1ms(10); //消除抖动10ms
- if(XJ==0) //再次判断按键是否按下
- {
- while(!XJ); //检测按键是否松开
- }
- hour--;
- if (hour>100) hour= 23;
- }
- }
- if (TW==0)
- {
- ……………………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei提供下载:
wnl.rar
(147.53 KB, 下载次数: 49)
|