|
- //********************编译预处理语句*******************************//
- #pragma SMALL
- #include <reg51.h>
- #include <absacc.h>
- #include <intrins.h>
- //************************端口定义*********************************//
- sbit P3_6=P3^6;
- //************************全局变量定义*****************************//
- unsigned char clockbuf[3]={0,0,0}; //存放时钟时、分、秒的十进制数
- unsigned char bellbuf[3]={0,0,0}; //存放闹钟时、分、秒的十进制数
- unsigned char msec1; //10ms中断次数
- unsigned char msec2; //1s循环次数
- unsigned char timdata,rtimdata; //时钟和闹钟修改标志位
- unsigned char count; //闹钟启动后10s计时单元
- unsigned char *dis_p; //显示缓冲区指针
- bit arm; //闹钟标志,arm=0,闹钟没有设定,arm=1闹钟已设定
- bit rtim; //闹钟是否启动标志,rtim=1,闹钟已启动
- bit rhour; //闹钟小时修改标志,rhour=1,正在修改闹钟小时
- bit rmin; //闹钟分修改标志,rmin =1,正在修改闹钟分钟
- bit hour; //时钟小时修改标志,hour=1正在修改时钟小时
- bit min; //时钟分修改标志,min =1正在修改时钟分钟
- bit sec; //时钟秒修改标志,sec=1正在修改时钟秒
- //***************************6位LED显示函数*****************************//
- void display(unsigned char *p)
- {
- unsigned char buffer[]={0,0,0,0,0,0};
- unsigned char i,j,m,temp;
- unsigned char led[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //0-9的显示码
- buffer[0]=p[0]/10; //将缓存区中数据的十位和各位分开
- buffer[1]=p[0]%10;
- buffer[2]=p[1]/10;
- buffer[3]=p[1]%10;
- buffer[4]=p[2]/10;
- buffer[5]=p[2]%10;
- { //没有修改标志,正常显示
- temp=0x01;
- for(i=0;i<6;i++)
- {
- P0=0x00; //关显示
- j=buffer[i];
- P0=led[j]; //P0送段码
- P1=~temp; //P1对应端口低电平选位
- temp<<=1;
- for(m=0;m<200;m++); //每一位显示延时
- }
- }
- }
- //********************************键盘检测函数****************************//
- //函数名:keytest
- //函数功能:测试键盘有无键按下,读出行输入按键状态码,用于测试是否有按键按下
- //形式参数:无
- //返回值:键盘行输入按键状态码,unsigned char类型
- unsigned char keytest()
- {
- unsigned char c;
- P2=0xf0; //检测是否有键按下, 行值全给1
- c=P2; //读取P2的值
- c=c&0xf0; //按键行输入为P2.0~P2.3,屏蔽无关位
- return(c); //返回c的值
- }
- //*********************************查键值函数****************************//
- //函数名:search
- //函数功能:按键识别
- //形式参数:无
- //返回值:行列式按键的键码,unsigned char类型
- unsigned char search()
- {
- unsigned char a,b,c,d,e;
- c=0x7f; //首列扫描字送入变量c
- a=0; //首行号送a
- while(1)
- {
- P2=c; //给P2的赋值
- d=P2; //读取P2的值
- d=d&0x0f; //屏蔽无关位h1-h4
- if(d==0x07){b=0;break;} //b为列号
- else if(d==0x0b){b=1;break;}
- else if(d==0x0d){b=2;break;}
- else if(d==0x0e){b=3;break;}
- a++; //扫描行号加1
- c>>=1; //修改列扫描字,扫描下一列
- if(a==4) {a=0;c=0x7f;} //控制移位到h1
- }
- e=a*4+b; //求键号
- do{display(dis_p);}
- while((d=keytest())!=0xf0);
- //等待释放按键
- return(e);
- }
- //**************************闹钟判断启动函数****************************//
- //函数名:alarm
- //函数功能:启动闹钟10s
- //形式参数:无
- //返回值:无
- void alarm()
- {
- if((clockbuf[0]==bellbuf[0])&&(clockbuf[1]==bellbuf[1]))
- { //判断时钟与闹钟是否相等
- P3_6=0; //启动闹钟
- rtim=1; //设置闹钟计时标志,闹钟将进行10s计时标志
- }
- if(count==10) //判断闹钟保持10s时间到否
- {
- count=0; //清楚闹钟保持10s计时
- P3_6=1; //清除闹钟
- arm=0; //清闹钟标志,否则闹钟设置将继续保持有效
- rtim=0; //闹钟关闭
- }
- }
- //*****************************时钟设置函数******************************//
- //函数名:ftion0
- //函数功能:时钟修改,根据按键次数,修改时、分、秒修改标志全局变量
- //形式参数:无
- //返回值:无
- void ftion0()
- {
- TR0=0; //关定时器
- rhour=0; //禁止闹钟小时参数修改,清闹钟修改标志
- rmin=0; //禁止闹钟分参数修改,清闹钟修改标志
- dis_p=clockbuf; //将时钟缓存区首地址送显示指针
- rtimdata=0; //清闹钟修改位置记录
- timdata++; //将时钟修改记录值加1
- switch(timdata)
- {
- case 0x01:sec=1;break; //记录值为1,则将时钟秒修改标志置1
- case 0x02:sec=0;min=1;break; //记录值为2,则将时钟分修改标志置1
- case 0x03:min=0;hour=1;break; //记录值为3,则将时钟小时修改标志置1
- case 0x04:timdata=0;hour=0;TR0=1;break; //按4次则清时钟单元修改位置
- default:break; //记录,定时器重新启动
- }
- }
- //****************************闹钟设置函数******************************//
- //函数名:ftion1
- //函数功能:闹钟修改,根据按键次数,修改时、分修改标志全局变量
- //形式参数:无
- //返回值:无
- void ftion1()
- {
- sec=0; //禁止时钟秒修改
- min=0; //禁止时钟分修改
- hour=0; //禁止时钟小时修改
- dis_p=bellbuf; //设置闹钟显示标志
- timdata=0; //清时钟修改位置标志记录
- rtimdata++; //将闹钟修改记录值加1
- switch(rtimdata)
- {
- case 0x01:rmin=1;break; //记录值为1,则将闹钟分修改标志置1
- case 0x02:rmin=0;rhour=1;break; //记录值为2,则将闹钟小时修改标志置1
- case 0x03:rtimdata=0;rhour=0;arm=1;dis_p=clockbuf;break;
- //按3次则清闹钟单元修改位置记录
- default:break; //恢复时钟显示标志
- }
- }
- //****************************加1修改功能函数**************************//
- //函数名:cum
- //函数功能:根据标志位对相应的时、分、秒单元加1
- //形式参数:无
- //返回值:无
- void cum()
- {
- if(sec==1) //若时钟秒修改标志位为1,则秒单元内容加1
- {
- if(59==clockbuf[2]) clockbuf[2]=0;
- else clockbuf[2]++;
- }
- else if(min==1) //若时钟分修改标志为1,则分单元内容加1
- {
- if(59==clockbuf[1]) clockbuf[1]=0;
- else clockbuf[1]++;
- }
- else if(hour==1) //若时钟小时修改标志为1,则小时单元内容加1
- {
- if(23==clockbuf[0]) clockbuf[0]=0;
- else clockbuf[0]++;
- }
- else if(rmin==1) //若闹钟分修改标志为1,则分单元内容加1
- {
- if(bellbuf[1]==59) bellbuf[1]=0;
- else bellbuf[1]++;
- }
- else if(rhour==1) //若闹钟小时修改标志为1,则小时单元内容加1
- {
- if(bellbuf[0]==23) bellbuf[0]=0;
- else bellbuf[0]++;
- }
- }
- //***************************加1修改功能函数************************//
- //函数名:jian
- //函数功能:根据标志位对相应的时、分、秒单元减1
- //形式参数:无
- //返回值:无
- void jian()
- {
- if(sec==1) //若时钟秒修改标志位为1,则秒单元内容减1
- {
- if(0==clockbuf[2]) clockbuf[2]=59;
- else clockbuf[2]--;
- }
- else if(min==1) //若时钟分修改标志为1,则分单元内容减1
- {
- if(0==clockbuf[1]) clockbuf[1]=59;
- else clockbuf[1]--;
- }
- else if(hour==1) //若时钟小时修改标志为1,则小时单元内容减1
- {
- if(0==clockbuf[0]) clockbuf[0]=23;
- else clockbuf[0]--;
- }
- else if(rmin==1) //若闹钟分修改标志为1,则分单元内容减1
- {
- if(bellbuf[1]==0) bellbuf[1]=59;
- else bellbuf[1]--;
- }
- else if(rhour==1) //若闹钟小时修改标志为1,则小时单元内容减1
- {
- if(bellbuf[0]==0) bellbuf[0]=23;
- else bellbuf[0]--;
- }
- }
- //***************************定时器中断函数******************************//
- //函数名:clock
- //函数功能:定时器T0定时中断,interrupt 1
- //形式参数:无
- //返回值:无
- void clock() interrupt 1
- {
- EA=0; //关中断
- if(msec1!=0x28) msec1++; //6MHz晶振,到10ms否,不到则msec1加1
- else
- {
- msec1=0;
- if(msec2!=100) msec2++; //到1s否,不到则msec2加1
- else
- {
- if(rtim==1) count++; //闹钟启动标志计时10s
- msec2=0;
- if(clockbuf[2]!=59) clockbuf[2]++; //到1min否,不到则clockbuf[2]加1
- else
- {
- clockbuf[2]=0;
- if(clockbuf[1]!=59) clockbuf[1]++; //到1h否,不到则clockbuf[1]加1
- else
- {
- clockbuf[1]=0;
- if(clockbuf[0]!=23) clockbuf[0]++; //到24h否,不到则clockbuf[0]加1
- else clockbuf[0]=0;
- }
- }
- }
- }
- EA=1; //开中断
- }
- void main()
- {
- unsigned char a;
- arm=0;
- //清零闹钟标志位
- P3_6=1; //P3_6置初值1
- msec1=0; //设置10ms中断次数初值
- msec2=0; //设置1s中断次数初值
- timdata=0; //时钟内容修改位置记忆单元清零
- rtimdata=0; //闹钟内容修改位置记忆单元清零
- count=0; //闹钟启动后保持10s计时单元清零
- TMOD=0x02; //初始化定时器,定时器T0位工作方式2
- TL0=0x06; //定时250us初始化
- TH0=0x06;
- EA=1; //中断允许控制
- ET0=1; //定时器0开中断
- TR0=1; //启动定时器0
- dis_p=clockbuf; //将时钟值所在地址送人显示指针
- while(1)
- {
- a=keytest(); //调用键盘检测子程序
- if(a==0xf0) //判断是否有键按下
- {
- display(dis_p); //无键输入调用显示程序
- if(arm==1) alarm(); //判断闹钟设定否,若已设定则调用闹钟启动子程序
- }
- else
- {
- display(dis_p); //调用显示子程序作为延时去抖
- a=keytest();
- if(a!=0xf0) //没有抖动,则表示有键按下
- {
- a=search(); //调用查键值子程序
- switch(a)
- {
- case 0x04:ftion0();break; //是时钟参数修改功能键,调用时钟设置子程序
- case 0x05:ftion1();break; //是闹钟参数修改功能键,调用闹钟设置子程序
- case 0x06:cum();break; //是加1功能键,则调用加1修改功能子程序
- case 0x07:jian();break; //是减1功能键,则调用减1修改功能子程序
- default:break;
- }
- }
- }
- }
- }
复制代码
|
|