按键扫描问题

2019-03-24 20:00发布

以下是一段函数发生器的源码,源码按键部分有问题,就是当按键按下后,数码管数字跳得很快,也就是说,本来是1,我想让他变成2,结果按了一下直接跳到5了,我看看延迟也是有的,就是查不出是什么原因,另外,当我在示波器上调试的时候输出的波形不是连续的,而是看到一个点在运动,运动的轨迹是对的,是不是采样的频率太低了,具体怎么改,求高手指教,万分感激!!!!!!!   #include <reg52.h>
#include <stdio.h>
#include <absacc.h>
#define uchar unsigned char
uchar code tab[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//0---9数字共阴极
uchar code tab1[8]={0X73,0x73,0x73,0x76,0x79,0x38,0x38,0x3f};// PPP. HELLO共阴极
uchar code tosin[256]={0x80,0x83,0x86,0x89,0x8d,0x90,0x93,0x96,0x99,0x9c,0x9f,0xa2,0xa5,0xa8,0xab,0xae,0xb1,0xb4,0xb7,0xba,0xbc,0xbf,0xc2,0xc5 ,0xc7,0xca,0xcc,0xcf,0xd1,0xd4,0xd6,0xd8,0xda,0xdd,0xdf,0xe1,0xe3,0xe5,0xe7,0xe9,0xea,0xec,0xee,0xef,0xf1,0xf2,0xf4,0xf5 ,0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfd,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfd ,0xfd,0xfc,0xfb,0xfa,0xf9,0xf8,0xf7,0xf6,0xf5,0xf4,0xf2,0xf1,0xef,0xee,0xec,0xea,0xe9,0xe7,0xe5,0xe3,0xe1,0xde,0xdd,0xda ,0xd8,0xd6,0xd4,0xd1,0xcf,0xcc,0xca,0xc7,0xc5,0xc2,0xbf,0xbc,0xba,0xb7,0xb4,0xb1,0xae,0xab,0xa8,0xa5,0xa2,0x9f,0x9c,0x99 ,0x96,0x93,0x90,0x8d,0x89,0x86,0x83,0x80,0x80,0x7c,0x79,0x76,0x72,0x6f,0x6c,0x69,0x66,0x63,0x60,0x5d,0x5a,0x57,0x55,0x51 ,0x4e,0x4c,0x48,0x45,0x43,0x40,0x3d,0x3a,0x38,0x35,0x33,0x30,0x2e,0x2b,0x29,0x27,0x25,0x22,0x20,0x1e,0x1c,0x1a,0x18,0x16 ,0x15,0x13,0x11,0x10,0x0e,0x0d,0x0b,0x0a,0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x02,0x01,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02 ,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0d,0x0e,0x10,0x11,0x13,0x15 ,0x16,0x18,0x1a,0x1c,0x1e,0x20,0x22,0x25,0x27,0x29,0x2b,0x2e,0x30,0x33,0x35,0x38,0x3a,0x3d,0x40,0x43,0x45,0x48,0x4c,0x4e ,0x51,0x55,0x57,0x5a,0x5d,0x60,0x63,0x66 ,0x69,0x6c,0x6f,0x72,0x76,0x79,0x7c,0x80 };//正弦波数据 uchar b=0,c=0,d=0,e=0,i,k,tl,th; int ww=0,qw=0,bw=9,sw=8,gw=3,zkgw=0,zksw=5;//ww为万位数字,qw为千位数字,bw为百位数字,
                               //sw为十位数字,gw为个位数字,zkgw为占空比个位数字,zksw为占空比十位数字 int t,f,m,choice=1,zk=50;  //t为时间变量,f为频率变量,choice为波形类型选择变量,zk为占空比变量,默认占空比为50% void delay10ms() //延时10ms程序
{
 unsigned char i,j;
 for(i=20;i>0;i--)
 for(j=248;j>0;j--);
}
void chushihua(void)//初始化显示  PPP.HELLO
{
P3=0xfe;
P2=tab1[0];
 for(i=0;i<=60;i++);
P3=0xfd;
P2=tab1[1];
 for(i=0;i<=60;i++);
P3=0xfb;
P2=tab1[2];
 for(i=0;i<=60;i++);
P3=0xfb;//小数点显示
P2=0x80;
 for(i=0;i<=60;i++);
P3=0xf7;
P2=tab1[3];
 for(i=0;i<=60;i++);
P3=0xef;
P2=tab1[4];
 for(i=0;i<=60;i++);
 P3=0xdf;
P2=tab1[5];
 for(i=0;i<=60;i++);
P3=0xbf;
P2=tab1[6];
 for(i=0;i<=60;i++);
P3=0x7f;
P2=tab1[7];
 for(i=0;i<=60;i++);
} /*1键选择发波类型,1为正弦波,2为三角波,3为方波*/
void key1(void)            {
if(choice<4)
choice=choice+1;
 else
choice=1;} /*个位频率调整*/
void key2(void)         
{
if(gw<9)
gw=gw+1;
else
gw=0;}
  
/*十位频率调整*/
void key3(void)       
{if(sw<9)
sw=sw+1;
else
sw=0;} /*百位频率调整*/
void key4(void)    
{
if(bw<9)
bw=bw+1;
else
bw=0;}
 
/*千位频率调整*/
void key5(void)  
{
if(qw<9)
qw=qw+1;
else
qw=0;} /*万位频率调整*/
void key6(void)    
{
if(ww<5)
ww=ww+1;
else
ww=0;} /*方波占空比加大*/
void key7(void)    
{if(zk<100)
zk=zk+1;
else
zk=0;} /*方波占空比减小*/
void key8(void)   
{
if(zk>=1)
zk=zk-1;
else
zk=0;
} /*计算显示数字*/
void jisuan(void)
{TR0=0;//关闭定时器
f=100000*ww+1000*qw+100*bw+10*sw+gw;
t=1000000/f;
th=-t/256;
tl=-t%256;
ww=f/10000;
f=f%10000;
qw=f/1000;
f=f%1000;
bw=f/100;
f=f%100;
sw=f/10;
gw=f%10;
zkgw=zk%10;
zksw=zk/10;
TR0=1;} /*显示*/
void display (void)
{ P3=0xfb;
P2=tab[choice];
for(i=0;i<=60;i++);
    P3=0xfb;
      P2=0x80;//小数点显示
  for(i=0;i<=60;i++);
 P3=0xf7;
P2=tab[ww];
for(i=0;i<=60;i++);
  P3=0xef;
P2=tab[qw];
for(i=0;i<=60;i++);
P3=0xdf;
P2=tab[bw];
for(i=0;i<=60;i++);
P3=0xbf;
P2=tab[sw];
for(i=0;i<=60;i++);
P3=0x7f;
P2=tab[gw];
for(i=0;i<=60;i++);
if(choice==3){
  P3=0xfd;
P2=tab[zkgw];
           for(i=0;i<=60;i++);
             P3=0xfe;
     P2=tab[zksw];
           for(i=0;i<=60;i++);
      P3=0xfd;
     P2=0x80;//小数点显示
             for(i=0;i<=60;i++);
     }}
/*键盘扫描*/
void judge(void)
{
        {   unsigned char X,Y,Z;
 P1=0xff;
 P1=0x0f;       //先对P3置数  行扫描
 if(P1!=0x0f)     //判断是否有键按下
 {delay10ms();    //延时,软件去干扰
  if(P1!=0x0f)   //确认按键按下X = P1;
  {
 X=P1;          //保存行扫描时有键按下时状态
 P1=0xf0;       //列扫描
 Y=P1;          //保存列扫描时有键按下时状态
  Z=X|Y;         //取出键值
 switch ( Z )   //判断键值(那一个键按下)
 {   case 0x7d: key1(); break;
      case 0xee: key2(); break; //对键值赋值
  case 0xde: key3(); break;
     case 0xbe: key4(); break;
     case 0x7e: key5(); break;
        case 0xed: key6(); break;
        case 0xdd: key7(); break;
        case 0xbd: key8(); break;
 }}} }}
void main(void)
{int n;
for(n=0;n<500;n++){
chushihua();
}
TMOD=0X01;
TR0=1;
th=-t/256;
tl=-t%156;
TH0=th;
TL0=tl;
ET0=1;
EA=1;
while(1)
  {jisuan();
 for(i=0;i<=50;i++);
  display();
   judge();
  } }
void time0_int(void) interrupt 1   //中断服务程序
{
TR0=0;
if(choice==1)
    { P0=tosin;             //正弦波
    b++; }
else if(choice==2)                //三角波
      {if(c<=128)P0=c;
       else P0=255-c;
         c++;
         }
else if(choice==3)                // 方波
      {k=zk*256/100;
       d++;
       if(d<=k)P0=0x00;
       else P0=0xff;}
else if(choice==4)                //锯齿波
      {if(e<=255)P0=255-e;
       else P0=0;
         e++;
         }
TH0=th;
TL0=tl;
TR0=1;
}             此帖出自小平头技术问答
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
9条回答
richiefang
2019-03-25 13:54
用边沿触发的按键中断代替电平触发,就不需要判断按键松放了,消除硬件抖动以后,按一下就是一个中断,放开再按一下又是一个中断。

一周热门 更多>