完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
扫一扫,分享给好友
功能包括:显示时间,修改时间,设置定时,查询法扩展了4个中断,分别是进入自动模式、手动模式、一键关灯、一键开灯,关灯状态进入不了其他模式,只能进入一键开灯,在任意模式下,都可以通过按键进入到其他模式。
能帮的请不要吝啬您的知识啊,先谢谢啦 程序: //*********编译预处理**********// #pragma SMALL #include #include //*********************************************************************************************************************************// #define uchar unsigned char #define COM8155 XBYTE[0x7ff0] //命令/状态口地址 #define PA8155 XBYTE[0x7ff1] //PA口地址 #define PB8155 XBYTE[0x7ff2] //PB口地址 #define PC8155 XBYTE[0x7ff3] //PC口地址 #define IN0 XBYTE[0xfef8] //设置ADC0809的通道0的地址 ***it ad_busy=P3^2; //定义EOC状态 ***it P2_2=P2^2;//可寻址位定义 //**********************************************************全局变量**********************************************************************// void display(unsigned char *p);//6位LED显示函数,指针p为显示数据区首地址 unsigned char keytest();//测试按键有无按下 unsigned char h,t,l,x,y,r;//h=1,定时开灯,h=0,延时关灯,t是adc0809转换结果,l手动模式下设置LED亮的个数,x模式切换前灯亮的个数,y值代表关灯前模式,r代表关灯状态下允许启动的模式 unsigned char search();//按键识别 void alarm();//定时判断启动 void ftion0();//时钟修改 void ftion1();//定时修改 void cum();//加1修改 void moren();//默认模式 void zidong();//自动模式子函数 void dengset();//手动模式灯设置子函数 void shoudong();//手动模式子函数 void kaideng();//一键开灯子函数 void guandeng();//一键关灯子函数 void keypanduan();//键盘判断子函数 void keyset();//键盘设置子函数 void adc0809();//ADC0809转换子函数 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 armbit;//定时标志,armbit=0,定时没有设定,armbit=1,定时已设定 bit rtimbit;//定时是否启动标志,rtimbit=1,定时已启动 bit rhourbit;//定时小时修改标志,rhourbit=1,正在修改定时小时 bit rminbit;//定时分修改标志,rminbit=1,正在修改定时分钟 bit hourbit;//时钟小时修改标志位,hourbit=1,正在修改时钟小时 bit minbit;//时钟分修改标志位,minbit=1,正在修改时钟分钟 bit secbit;//时钟秒修改标志位,secbit=1,正在修改时钟秒 //*************************************************************主函数*****************************************************************// void main() {COM8155=0x03;//PA口、PB口输出 armbit=0;//清零定时标志位 msec1=0;//设置10ms中断次数初值 msec2=0;//设置1s中断次数初值 timdata=0;//时钟内容修改位置记忆单元清零 rtimdata=0;//定时内容修改位置记忆单元清零 count=0;//定时启动后保持10s计时单元清零 TMOD=0x02;//初始化定时器,定时器T0为工作方式2 TL0=0x06;//定时250us初始值 TH0=0x06; EA=1;//开总中断允许位 EX0=1;//开外部中断0中断允许位 IT0=1;//设置外部中断0为下降沿触发 EX1=1;//开外部中断0中断允许位 IT1=1;//设置外部中断1为下降沿触发 ET0=1;//定时器0开中断 TR0=1;//启动定时器0 dis_p=clockbuf;//将时钟值所在地址送入显示指针 moren();//调用默认子函数 } //************************adc转换子程序********************************************// void adc0809() {uchar b; while(1){ P2_2=1; for(b=0;b<50;b++);//延时 P2_2=0;//在P2_2引脚产生下降沿,START和ALE引脚产生上升沿,锁存通道地址,所有内部寄存器清零 for(b=0;b<50;b++);//延时 P2_2=1;//在P2_2上产生上升沿,START上产生下降沿,AD转换开始 while(ad_busy==0);//等待转换完成,EOC=1表示转换完成 P2_2=0;//P2_2=0,则OE=1,允许读数 t=P0;//读AD转换数据 } } //************************************************6位LED显示函数************************************************// void display(unsigned char *p) {unsigned char buffer[]={0,0,0,0,0,0}; unsigned char k,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; for(k=0;k<3;k++){ temp=0x01; for(i=0;i<6;i++){ PB8155=0xff;//关显示 j=buffer; PB8155=led[j];//PB8155送段码 PA8155&=~temp;//PA8155对应端口低电平选位 temp<<=1; for(m=0;m<100;m++);//每一位显示延时 } } } //***********************************************键盘检测函数*****************************************************// unsigned char keytest() {unsigned char c; PA8155=0xf0; c=PC8155; c=c&0x0f;//按键行输入为PC8155.0~PC8155.3,屏蔽无关位 return(c); } //************************************************查询键值函数********************************************************// unsigned char search() {unsigned char a,b,c,d; c=0xfe;//首列扫描字送变量c a=0;//首列号送a while(1){ PA8155=c;//列扫描字送PA8155口 d=PC8155;//读入PC8155口的行状态 if(d&0x01==0) { b=0;break;}//第0行有键按下,第0行行首号送b else if(d&0x02==0) { b=4;break;}//第1行有键按下,第1行行首号送b else if(d&0x04==0) { b=8;break;}//第2行有键按下,第2行行首号送b else if(d&0x08==0) { b=12;break;}//第3行有键按下,第3行行首号送b a++;//扫描列号加1 c<<=1;//修改列扫描字,扫描下一列 } c=a+b;//将行首号与列号相加,求键号 do{display(dis_p);} while((d=keytest())!=0x0f);//等待释放按键,若有问题将0x0f换成0x07 return(c); } //******************************************************定时判断启动函数*****************************************************// void alarm() {if((clockbuf[0]==bellbuf[0])&&(clockbuf[1]==bellbuf[1])) { while(1){ display(dis_p);//调用显示程序 if(h==1) {kaideng(); }//调用开灯子函数 else {guandeng(); }//调用关灯子函数 } } } //*******************************************************时钟设置函数**************************************************************// void ftion0() {TR0=0;//关定时器 rhourbit=0;//禁止定时时间参数修改,清定时修改标志位 rminbit=0; dis_p=clockbuf;//将时钟缓冲区首地址送显示指针 rtimdata=0;//清定时修改位置标志记录 timdata++;//将时钟修改记录值加1 switch(timdata){ case 0x01:secbit=1;break;//记录值为1,则将时钟秒修改标志置1 case 0x02:secbit=0;minbit=1;break;//记录值为2,则将时钟分修改标志置1 case 0x03:minbit=0;hourbit=1;break;//记录值为3,则将时钟时修改标志置1 case 0x04:timdata=0;hourbit=0;TR0=1;break;//按4次则清时钟单元修改位置,记录,定时器重新启动 default:break; } } //****************************************************************定时设置函数******************************************************// void ftion1() {secbit=0;//禁止时钟时间修改 minbit=0; hourbit=0; dis_p=bellbuf;//设置定时显示标志 timdata=0;//清时钟修改位置标志记录 rtimdata++;//将定时修改记录值加1 switch(rtimdata){ case 0x01:rminbit=1;break;//若记录值为1,则将定时分修改标志置1 case 0x02:rminbit=0;rhourbit=1;break;//若记录值为2,则将时钟分修改标志置1 case 0x03:rtimdata=0;rhourbit=0;//若按3次则清定时单元修改位置记录 armbit=1;//设置定时已设定标志位 dis_p=clockbuf;//恢复时钟显示标志 break; default:break; } } //*************************************************************加1修改功能函数*******************************************************// void cum() {if(secbit==1)//若时钟秒修改标志为1,则秒单元内容加1 { if(clockbuf[2]==59) clockbuf[2]=0; else clockbuf[2]++; } else if(minbit==1)//若时钟分修改标志为1,则分单元内容加1 {if(clockbuf[1]==59) clockbuf[1]=0; else clockbuf[1]++; } else if(hourbit==1)//若时钟时修改标志为1,则时单元内容加1 {if(clockbuf[0]==23) clockbuf[0]=0; else clockbuf[0]++; } else if(rminbit==1)//若定时分修改标志为1,则分单元内容加1 {if(bellbuf[1]==59) bellbuf[1]=0; else bellbuf[1]++; } else if(rhourbit==1)//若定时小时修改标志为1,则小时单元内容加1 {if(bellbuf[0]==23) bellbuf[0]=0; else bellbuf[0]++; } } //****************************************************************定时器中断函数****************************************************// void clock() interrupt 1 {EA=0;//关中断 if(msec1!=0x28) msec1++;//到10ms否,不到则msec1加1 else {msec1=0; if(msec2!=100) msec2++;//到1s否,不到则msec2加1 else {if(rtimbit==1) count++; 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 keypanduan() {unsigned char a; a=keytest();//调用键盘检测子程序 if(a==0x0f) {display(dis_p);//无键输入调用显示程序 if(armbit==1) alarm(); }//判断定时设定否,若已设定则调用闹钟启动子程序 else {display(dis_p);//调用显示子程序作为延时去抖动 a=keytest(); if(a!=0x0f)//没有抖动,表示有按键按下 {a=search();//调用查键子程序 switch (a){ case 0x00:ftion0();break;//是时钟参数修改功能键,调用时钟设置子程序 case 0x02:cum();break;//是加1功能键,则调用加1修改功能子程序 case 0x03:h=1;keyset();break;//定时开,h=1,调用键盘设置子函数 case 0x04:h=0;keyset();break;//延时关,h=0,调用键盘设置子函数 default:break; } } } } //******************************************************************键盘设置子函数*************************************************// void keyset() {unsigned char b; while(1){ b=keytest();//调用键盘检测子程序 if(b==0x0f) {display(dis_p);//无键输入调用显示程序 } else {display(dis_p);//调用显示子程序作为延时去抖动 b=keytest(); if(b!=0x0f)//没有抖动,表示有按键按下 {b=search();//调用查键子程序 switch (b){ case 0x01:ftion1();break;//是定时参数修改功能键,调用定时设置子程序 case 0x02:cum();break;//是加1功能键,则调用加1修改功能子程序 default:break; } } } } } //******************************************************************手动模式灯设置子函数*************************************************// void dengset() {unsigned char a; a=keytest();//调用键盘检测子程序 if(a==0x0f) {display(dis_p);//无键输入调用显示程序 if(armbit==1) alarm(); }//判断定时设定否,若已设定则调用闹钟启动子程序 else {display(dis_p);//调用显示子程序作为延时去抖动 a=keytest(); if(a!=0x0f)//没有抖动,表示有按键按下 {a=search();//调用查键子程序 switch (a){ case 0x00:ftion0();break;//是时钟参数修改功能键,调用时钟设置子程序 case 0x02:cum();break;//是加1功能键,则调用加1修改功能子程序 case 0x03:h=1;keyset();break;//定时,h=1,调用键盘设置子函数 case 0x04:h=0;keyset();break;//延时,h=0,调用键盘设置子函数 case 0x05:l=0x01;break;//5#键盘代表亮1个LED case 0x06:l=0x03;break;//6#键盘代表亮2个LED case 0x07:l=0x07;break;//7#键盘代表亮3个LED case 0x08:l=0x0f;break;//8#键盘代表亮4个LED case 0x09:l=0x1f;break;//9#键盘代表亮5个LED case 0x0a:l=0x3f;break;//10#键盘代表亮6个LED case 0x0b:l=0x7f;break;//11#键盘代表亮7个LED case 0x0c:l=0xff;break;//12#键盘代表亮8个LED default:break; } } } } //******************************************************************外部中断1中断函数*************************************************// void int_1() interrupt 2//外部中断1中断类型号为2 { unsigned char i; P2=0xff;//读P2口引脚前先全部置1 i=P2;//在P2口引脚状态读入变量i i&=0x78;//采用与操作屏蔽掉i的低4位 switch(i) {case 0x08:zidong();break;//调用zidong()子函数,进入自动模式 case 0x10:shoudong();break;//调用shoudong()子函数,进入手动模式 case 0x20:guandeng();break;//调用guandeng()子函数,进入一键关灯 case 0x40:kaideng();break;//调用kaideng()子函数,进入一键开灯 default:break; } } //*****************************************************************自动模式子函数*******************************************************// void zidong() {if(r==1){ while(1){P1=x; display(dis_p);//调用显示程序 adc0809();//调用ADC转换子函数 x=t;//将转换结果送给变量x,并且保存LED灯亮的个数 keypanduan();//调用键盘判断子函数 y=0x01;//保存模式 r=1; } } } //*****************************************************************手动模式子函数*******************************************************// void shoudong() {if(r==1) { while(1){ P1=x; display(dis_p);//调用显示程序 dengset();//调用手动模式灯设置子函数 x=l;//将设置LED灯亮的个数保存起来 y=0x02;//保存模式 r=1; } } } //*****************************************************************一键关灯子函数*******************************************************// void guandeng() {P1=x;r=0; while(1){ P1=0x00; keypanduan(); } } //*****************************************************************一键开灯子函数*******************************************************// void kaideng() {P1=x;r=1; while(1){ switch(y) {case 0x00:moren();break;//恢复默认模式 case 0x01:zidong();break;//恢复自动模式 case 0x02:shoudong();break;//恢复手动模式 default:break; } } } //*****************************************************************默认模式*******************************************************// void moren() { r=1; while(1){ P1=0x3f; keypanduan(); x=0x3f; y=0x00;//保存模式 } }
|
|
相关推荐
1个回答
|
|
回帖奖励 +2 分积分
谢谢分享,路过学习。。。。
|
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
4930 浏览 3 评论
6220 浏览 1 评论
6485 浏览 0 评论
Protues中自己封装的芯片元件无Program File、Clock Frequency选项怎么解决,求求大神了!
8237 浏览 1 评论
基于51单片机的车辆倒车雷达报警系统,HC-SR04超声波测距,全套资料
1241 浏览 0 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-2 01:57 , Processed in 0.407341 second(s), Total 46, Slave 37 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号