- #include<reg52.h> //52单片机头文件
- #include"intrins.h" //循环移位函数头文件
- #define uint unsigned int // 宏定义
- #define uchar unsigned char
- #define NOT_Break 25 //任意赋值避开条件
- uchar code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0XBF,0xff}; //共阳极数码管编码0-9和“—”
- uchar val[8]={2,3,10,5,9,10,5,5};
- uchar flag=0;
- sbit key0 = P2^0; //清零
- sbit key1 = P2^1; //时间---年月日转换
- //
- sbit BEEP = P3^5; //蜂鸣器
- void delay(uint z) //1毫秒
- {
- uint x,y;
- for(x=z;x>0;x--)
- for(y=110;y>0;y--);
- }
- void time0init() // 定时器0初始化函数
- {
- TMOD=0x01; //设置定时器0为工作方式1(M1M0为01)
- TH0=(65536-2000)/256; //装初值12M晶振定时2ms数为2000
- TL0=(65536-2000)%256;
- EA=1; //开总中断
- ET0=1; //开定时器0中断
- TR0=1; //启动定时器0
- }
- uint num=0,keytime=0,time;
- uchar wei=0X01,duan=0; //时间更新 1s,20ms扫描一次按键, 控制修改项闪烁
- void time0() interrupt 1
- {
- TH0=(65536-2000)/256; //装初值12M晶振定时2ms数为2000
- TL0=(65536-2000)%256;
- keytime++; //20ms扫描一次按键
- time++; //控制修改项闪烁
- num++; //时间更新 1s
- P1=wei; // 选择要点亮的数码管是哪一个
- P0=table[val[duan]]; // 给改数码管送显示数据
- wei=_crol_(wei,1); // 移位,为点亮下一个数码管做准备
- duan++;
- if(duan>7) duan=0;
- }
- uchar key()
- {
- static uchar kzt=0; //推动循环,每次执行一次case
- uchar sb=NOT_Break; //任意赋值避开条件
- switch(kzt) //按顺序依次执行
- {
- //------------case 0:------------//
- case 0: //第一步
- P3=0xff; //P3做读入状态时,应该要先写1的,才能正确读入数据
- //按照课本原文 作输入时:必须先将1写入口锁存器,使场效应管截止,该口线同时被内部上拉电阻拉成高电平,同时也能被外部输入源拉成低电平,即外部输入1时,该口线为高电平,输入0时,该口线为低电平
- if(P3!=0xff) //如果有按键按下
- {
- kzt=1; //向下执行第二步
- return NOT_Break; //返回一个无关的值,用来跳出此次循环
- }
- break; //如果没有按键按下,直接跳出
- //------------case 1:------------//
- case 1: //第二步
- P3=0xff; //P3做读入状态时,应该要先写1的,才能正确读入数据
- //按照课本原文 作输入时:必须先将1写入口锁存器,使场效应管截止,该口线同时被内部上拉电阻拉成高电平,同时也能被外部输入源拉成低电平,即外部输入1时,该口线为高电平,输入0时,该口线为低电平
- if(P3!=0xff) //有按键按下
- {
- switch(P3)
- {
- case 0xfe: //第一个按键按下
- sb=0;
- break; //直接跳出
- case 0xfd: //第二个按键按下
- sb=1;
- break; //直接跳出
- case 0xfb: //第三个按键按下
- sb=2;
- break; //直接跳出
- case 0xf7: //第四个按键按下
- sb=3;
- break; //直接跳出
- }
- kzt=2; //如果无按键按下 向下执行第三步
- return sb; //返回sb的值
- }
- else //如果无按键按下 回到第一步
- {
- kzt=0;
- return NOT_Break; //返回一个无关的值,用来跳出此次循环
- }
- break;
- //------------case 2:------------//
- case 2: //第三步
- P3=0xff; //P3做读入状态时,应该要先写1的,才能正确读入数据
- //按照课本原文 作输入时:必须先将1写入口锁存器,使场效应管截止,该口线同时被内部上拉电阻拉成高电平,同时也能被外部输入源拉成低电平,即外部输入1时,该口线为高电平,输入0时,该口线为低电平
- if(P3==0xff) //如果没有按键按下
- {
- kzt=0; //如果无按键按下 回到第一步
- return NOT_Break;
- }
- break; //如果有按键按下 直接跳出
- }
- return NOT_Break;
- }
- void main()
- {
- char shi=23,fen=59,miao=55,qh=0; //初始化时分秒 状态标志位(0:正常,1:改变秒钟,2:改变分钟,3:改变时钟)
- char year=21,month=06,day=22;
- char flag=0; //标志位---年月日&&时分秒
- char keycode=NOT_Break; //键值
- P0=0xff;
- P1=0xff;
- P2=0xff;
- P3=0xff;
- delay(10); //保证上面三条指令顺利完成
- time0init(); //定时器0初始化函数
- while(1)
- {
- if(key0==0) //清零按键按下
- {
- shi=0;fen=0;miao=0; //时分秒清零
- qh=0; //开始显示
- }
- if(key1==0) //年月日&&时分秒按键按下
- {
- while(!key1); //等待放开按键
- if(flag==0) {flag=1;} //年月日&&时分秒
- else flag=0;
- qh=0; //开始显示
- }
-
- if(keytime>9) //2ms*10=20ms
- {
- keytime=0; //计数清零
- keycode=key(); //检测是否有按键按下
- }
- //////////////////////////////---时间更新---//////////////////////////////
- if((num>=500)&&(qh==0)) //时间更新 2ms*500=1s
- {
-
- num=0; //计数清零
- miao++; //秒数加1
- if(miao>59) //如果miao等于60
- {
- miao=0; //miao赋值为0
- fen++; //分钟加1
- if(fen>59) //如果fen等于60
- {
- fen=0; //fen赋值为0
- shi++; //小时加1
- if(shi>23) shi=0;//如果shi等于24 shi赋值为0
- }
- }
- }
-
-
- ///////////////////////////////////////////////////////////////////////////
- //////////////////////////////---按键检测---///////////////////////////////
- ///////////////////////////---第一个按键按下---///////////////////////////////
- if(flag==0)
- {
- if(keycode==0) //第一个按键按下 选择
- {
- qh++; //状态标志位(0:正常,1:改变秒钟,2:改变分钟,3:改变时钟)
- if(qh>3) qh=1; //如果qh等于4,qh赋值为1
- keycode=NOT_Break; //任意赋值避开条件
- }
- ///////////////////////////---第二个按键按下---///////////////////////////////
- if(keycode==1) //第二个按键按下 加
- {
- if(qh==1)
- {
- miao++;
- if(miao>59) {miao=0;fen++;}//如果miao等于60 miao赋值为0
-
- }
- if(qh==2)
- {
- fen++;
- if(fen>59) {fen=0;shi++;} //如果fen等于60 fen赋值为0
-
- }
- if(qh==3)
- {
- shi++;
- if(shi>23){shi=0;day++;} //如果shi等于24 shi赋值为0
- }
- keycode=NOT_Break; //任意赋值避开条件
- }
- ///////////////////////////---第三个按键按下---///////////////////////////////
- if(keycode==2) //第三个按键按下 减
- {
- if(qh==1)
- {
- miao--;
- if(miao<0) {miao=59;fen--;}//如果miao等于-1 miao赋值为59
- }
- if(qh==2)
- {
- fen--;
- if(fen<0) {fen=59;shi--;} //如果fen等于-1 fen赋值为59
- }
- if(qh==3)
- {
- shi--;
- if(shi<0) {shi=23;day--;} //如果shi等于-1 shi赋值为23
- }
- keycode=NOT_Break; //任意赋值避开条件
- }
- ///////////////////////////---第四个按键按下---///////////////////////////////
- if(keycode==3) //第四个按键按下 确定
- {
- qh=0;
- keycode=NOT_Break; //任意赋值避开条件
- }
- }
- else if(flag==1)
- {
- if(keycode==0) //第一个按键按下 选择
- {
- qh++; //状态标志位(0:正常,1:改变秒钟,2:改变分钟,3:改变时钟)
- if(qh>3) qh=1; //如果qh等于4,qh赋值为1
- keycode=NOT_Break; //任意赋值避开条件
- }
- ///---第二个按键按下:调加---///
- if(keycode==1)
- {
- if(qh==1)
- {
- day++;
- if(day==29&&month==2&&(year%4!=0)){ day=1;month++;} //不是闰年
- if(day==30&&month==2&&year%100==0&&year%400!=0){day=1;month++;}
- if(day==30&&month==2&&((year%100==0&&year%400==0)||(year%100!=0&&year%4==0))){day=1;month++;}
- if(day==31&&(month==4||month==6||month==9||month==11)) { day=1;month++;}
- if(day==33&(month==1||month==3||month==5||month==7||month==8||month==10||month==12)){ day=1; month++;}
-
- }
-
- if(qh==2)
- {
- month++;
- if(month>12) {month=1;year++;} //如果月等于13 分赋值为1
- }
- if(qh==3)
- {
- year++;
- if(year>99) year=1; //如果年等于100 时赋值为1
- }
- keycode=NOT_Break; //任意赋值避开条件
- }
- ///---第三个按键按下:调减---///
- if(keycode==2)
- {
- if(qh==1)
- {
- day--;
-
- if(day==0&&month==3&&(year%4!=0))
- {day=28; month--;}
- if(day==0&&month==3&&year%100==0&&year%400!=0)
- {day=28; month--;}
- if(day==0&&month==3&&((year%100==0&&year%400==0)||(year%100!=0&&year%4==0)))
- {day=29; month--;}
- if(day==0&&(month==4||month==6||month==9||month==11))
- {day=30; month--;}
- if(day==0&&(month==1||month==2||month==5||month==7||month==8||month==10||month==12))
- {day=31; month--;}
-
- }
- if(qh==2)
- {
- month--;
- if(month<1) {month=12;year--;} //如果月等于0 分赋值为12
- }
- if(qh==3)
- {
- year--;
- if(year<1) year=99; //如果年等于0 时赋值为12
- }
- keycode=NOT_Break; //任意赋值避开条件
- }
- ///---第四个按键按下---///
- if(keycode==3) //第四个按键按下 确定
- {
- qh=0;
- keycode=NOT_Break; //任意赋值避开条件
- }
- }
-
- ///////////////////////////////////////////////////////////////////////////
-
- ///////////////////////////---显示函数---///////////////////////////////
- switch(qh) //按键按下后立即显示
- {
- //正常显示
- case 0:
- if(flag==1)
- {
- val[0]=2; //年份21开头定死
- val[1]=0;
- val[2]=year/10; //年份十位显示
- val[3]=year%10; //年份个位显示
- val[4]=month/10; //月份十位显示
- val[5]=month%10; //月份个位显示
- val[6]=day/10; //天数十位显示
- val[7]=day%10; //天数个位显示
- }
- /**********显示时分秒***********/
- else if(flag==0)
- {
- val[0]=shi/10; //显示时间 时分秒
- val[1]=shi%10;
- val[2]=10;
- val[3]=fen/10;
- val[4]=fen%10;
- /**********整点报时,蜂鸣器响 **********/
- if(fen==0)
- {
- BEEP=0;
- delay(200);
- BEEP=1;
- }
- val[5]=10;
- val[6]=miao/10;
- val[7]=miao%10;
- }
- //秒钟修改后显示 其中秒钟部分在闪烁
- case 1:
- if(flag==0)
- {
- if(time<250) //2ms*250=0.5s
- {
- val[0]=shi/10;
- val[1]=shi%10;
- val[3]=fen/10;
- val[4]=fen%10;
- val[6]=miao/10;
- val[7]=miao%10;
- }
- else if(time<500) //2ms*500=1s
- {
- val[0]=shi/10;
- val[1]=shi%10;
- val[3]=fen/10;
- val[4]=fen%10;
- val[6]=11;
- val[7]=11;
- }
- else if(time>500) //2ms*500=1s
- {
- time=0;
- }
- }
- else if(flag==1)
- {
- if(time<250) //2ms*250=0.5s
- {
- val[2]=year/10;
- val[3]=year%10;
- val[4]=month/10;
- val[5]=month%10;
- val[6]=day/10;
- val[7]=day%10;
- }
- else if(time<500) //2ms*500=1s
- {
- val[2]=year/10;
- val[3]=year%10;
- val[4]=month/10;
- val[5]=month%10;
- val[6]=11;
- val[7]=11;
- }
- else if(time>500) //2ms*500=1s
- {
- time=0;
- }
- }
-
- case 2:
- if(flag==0)
- {
- if(time<250)
- {
- val[0]=shi/10;
- val[1]=shi%10;
- val[3]=fen/10;
- val[4]=fen%10;
- val[6]=miao/10;
- val[7]=miao%10;
- }
- else if(time<500)
- {
- val[0]=shi/10;
- val[1]=shi%10;
- val[3]=11;
- val[4]=11;
- val[6]=miao/10;
- val[7]=miao%10;
- }
- else if(time>500)
- {
- time=0;
- }
- }
- else if(flag==1)
- {
- if(time<250) //2ms*250=0.5s
- {
- val[2]=year/10; //年的十位部分
- val[3]=year%10; //年的个位部分
- val[4]=month/10; //月的十位部分
- val[5]=month%10; //月的个位部分
- val[6]=day/10; //天的十位部分
- val[7]=day%10; //天的个位部分
- }
- else if(time<500) //2ms*500=1s /数在闪烁
- {
- val[2]=year/10;
- val[3]=year%10;
- val[4]=11;
- val[5]=11;
- val[6]=day/10;
- val[7]=day%10;
- }
- else if(time>500) //2ms*500=1s
- {
- time=0;
- }
- }//if(flag==1)的else的括号
- //时钟修改后显示 其中时钟部分在闪烁
- case 3:
- if(flag==0)
- {
- if(time<250)
- {
- val[0]=shi/10;
- val[1]=shi%10;
- val[3]=fen/10;
- val[4]=fen%10;
- val[6]=miao/10;
- val[7]=miao%10;
- }
- else if(time<500)
- {
- val[0]=11;
- val[1]=11;
- val[3]=fen/10;
- val[4]=fen%10;
- val[6]=miao/10;
- val[7]=miao%10;
- }
- else if(time>500)
- {
- time=0;
- }
- }
- else if(flag==1)
- {
- if(time<250) //2ms*250=0.5s
- {
- val[2]=year/10; //年的十位部分
- val[3]=year%10; //年的个位部分
- val[4]=month/10; //月的十位部分
- val[5]=month%10; //月的个位部分
- val[6]=day/10; //天的十位部分
- val[7]=day%10; //天的个位部分
- }
- else if(time<500) //2ms*500=1s /天数在闪烁
- {
- val[2]=11;
- val[3]=11;
- val[4]=month/10;
- val[5]=month%10;
- val[6]=day/10;
- val[7]=day%10;
- }
- else if(time>500) //2ms*500=1s
- {
- time=0;
- }
- break;
- }
- }
- }
- }
复制代码 |