|
最近在做单片机系统的项目设计,自己的系统板还在厂家制作,要一段时间才能送来,借用同学的小开发板先写了一个简易数字钟程序!<br />基本情况如下:<br />硬件平台:单片机:华邦系列W78E516B40DL<br /> 晶振:12MHZ<br /> 8个二极管<br /> 四个数码管<br /> 四个按键<br /> 一个温度传感器<br /> 串口通信:MAX232<br />软件平台:Keil uVision2<br />开发语言:C语言<br />程序下载软件:8051IspWriter.exe<br />程序实现功能:4个数码管依次显示分钟和秒钟,4个按键,按SW1,SW2,SW3,SW4依次实现分钟,秒钟的十位,个位加一!<br />最终源程序如下:<br /> #include<reg51.h><br />#include<absacc.h><br />#define uchar unsigned char<br />#define uint unsigned int<br />uchar *dis_ptr;<br />uchar data dis_buf[4]={0,0,0,0};//显示缓冲区<br />uchar data time_buf[2]={0x00,0x00};//显示数据<br />uchar code seg_tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,<br /> 0xf8,0x80,0x90,0xff};//7段共阳极,依次为0-9<br />uchar code digit_tab[4]={1,2,4,8};//动态显示缓冲区<br />uint m=0;<br />uint n=0;<br />uint key_flag=0;<br />sbit p24=P2^4;<br />sbit p25=P2^5;<br />sbit p26=P2^6;<br />sbit p27=P2^7;<br />void init_sys();<br />void disply_one(void);<br />void dis_buf_flash(void);<br />bit key_test(void);<br />void key(void);<br />void key_delay();<br />void main()<br />{init_sys();<br />for(;;);}<br />void init_sys(void)//T0工作于方式2,定时250um,<br />{<br />dis_ptr=dis_buf+3;<br />TH0=6;<br />TL0=6;<br />TMOD=2;<br />IE=0x82;<br />IP=2;<br />TR0=1;<br />}<br /><br />void disply_one(void)//动态显示1位<br />{uchar i;<br />P0=seg_tab[*dis_ptr];<br />i=dis_ptr-dis_buf;<br />P2=~digit_tab;<br />if (dis_ptr>dis_buf)<br /> dis_ptr--;<br />else dis_ptr=dis_buf+3;<br />}<br /><br /><br />void dis_buf_flash(void)//显示数据送缓冲区<br />{<br />dis_buf[0]=time_buf[0]/10;<br />dis_buf[1]=time_buf[0]%10;<br />dis_buf[2]=time_buf[1]/10;<br />dis_buf[3]=time_buf[1]%10;<br />}<br /><br /><br />void time0(void) interrupt 1 <br />{ <br /> <br /> TF0=0;<br /> m++;<br /> n++;<br /> if(key_test()==0)<br /> {key_delay();<br /> if(key_test()==0)<br /> {key_flag=0;}<br /> }<br /> if ((n>=40)&&(key_flag==0))//10ms扫描键盘<br /> {n=0;<br /> key_test();//扫描键盘<br /> if(key_test()==1){<br /> key_delay(); <br /> if(key_test()==1)<br /> {key();}<br /> <br /> }<br /> }<br /> if (m>=4000)//1秒处理<br /> { m=0;<br /> time_buf[1]+=1;<br /> if (time_buf[1]>=60)//1分处理<br /> {time_buf[1]=0;<br /> time_buf[0]+=1;}<br /> if (time_buf[0]>=60)//1时处理<br /> {time_buf[0]=0;<br /> time_buf[1]=0;}<br /> <br /> }<br /> <br /> dis_buf_flash();<br /> disply_one(); <br /> <br /> }<br />bit key_test(void)//测试键盘有无键按下<br />{<br />if ((p24==0)||(p25==0)||(p26==0)||(p27==0))<br />return ((bit)1);<br />else return ((bit)0);<br />}<br /><br /><br />void key(void)//按键处理<br />{key_flag=1;<br />if(p24==0){<br /> time_buf[0]+=10;}<br /> else if(p25==0){time_buf[0]+=1;}<br /> else if(p26==0){time_buf[1]+=10;}<br />else time_buf[1]+=1;<br /><br /><br />}<br /> <br /><br />void key_delay()<br />{uchar i,s;<br />for(i=10000,s=5;s>=1;i--)<br /> {s=i;}<br />}<br />最终正常显示,按键可调!<br /><br />中途遇到的问题:<br />按单键无反映!只有一起按紧SW1和SW2才出现分钟的两位一直向上加,但也不可控制加的大小!<br />解决1:在按键和释放键的时候加一个去抖动延迟函数<br />void key_delay()<br />{uchar i,s;<br />for(i=10000,s=5;s>=1;i--)<br /> {s=i;}<br />结果:<br /><br />按每个按键都能改变相应的位数的数字,但不可控制。改变太快!<br /><br />解决2:加一个扫描标志,当检测到有键按下时,停止扫描键盘,当键释放时,继续扫描键盘<br />这样就能保证按一次键被扫描一次,从而实现加一。<br /> |
|