4581|9

3

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

按键扫描问题 [复制链接]

以下是一段函数发生器的源码,源码按键部分有问题,就是当按键按下后,数码管数字跳得很快,也就是说,本来是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;
}

 

 

 

 

 

 

此帖出自51单片机论坛

最新回复

键盘处理逻辑有问题  详情 回复 发表于 2011-4-30 23:16
点赞 关注
 

回复
举报

1668

帖子

0

TA的资源

裸片初长成(初级)

沙发
 
这种问题很常见。确认下面这几点:
1、硬件/软件防抖?
2、中断是电平触发还是边沿触发?

此帖出自51单片机论坛
 
 
 

回复

3

帖子

0

TA的资源

一粒金砂(初级)

板凳
 

回复 沙发 richiefang 的帖子

我看看软件防抖不是有延迟程序的么,求高手最好直接说明我程序错在哪里,具体怎么改,万分感谢!!!!!!!
此帖出自51单片机论坛
 
 
 

回复

159

帖子

0

TA的资源

一粒金砂(高级)

4
 
软件防抖不止是延时,还要判断什么时候抬起,延时到了需要按键抬起了才处理
此帖出自51单片机论坛
 
个人签名*我的EMAIL:     sunke9@qq.com  
*我的博客http://blog.ednchina.com/sunke9/
*我网店:https://sunke9.taobao.com/
承接:电子、自动控制产品设计开发;单片机、ARM编程。
 
 

回复

129

帖子

0

TA的资源

一粒金砂(中级)

5
 
我的想法是:用中断,进中断后设标志位,然后处理后在开中断
此帖出自51单片机论坛
 
个人签名我一直在努力着。。。
 
 

回复

3

帖子

0

TA的资源

一粒金砂(初级)

6
 

回复 板凳 532727489 的帖子

怎么把按键松放程序加进去呢?求高手指教
此帖出自51单片机论坛
 
 
 

回复

1668

帖子

0

TA的资源

裸片初长成(初级)

7
 
用边沿触发的按键中断代替电平触发,就不需要判断按键松放了,消除硬件抖动以后,按一下就是一个中断,放开再按一下又是一个中断。
此帖出自51单片机论坛
 
 
 

回复

159

帖子

0

TA的资源

一粒金砂(高级)

8
 

X=P1;          //保存行扫描时有键按下时状态
P1=0xf0;       //列扫描
Y=P1;          //保存列扫描时有键按下时状态
  Z=X|Y;         //取出键值
后面加上
do
{
X=P1;          //保存行扫描时有键按下时状态
P1=0xf0;       //列扫描
Y=P1;          //保存列扫描时有键按下时状态
}while(X|Y);
这就是判断按键是不是空
此帖出自51单片机论坛
 
个人签名*我的EMAIL:     sunke9@qq.com  
*我的博客http://blog.ednchina.com/sunke9/
*我网店:https://sunke9.taobao.com/
承接:电子、自动控制产品设计开发;单片机、ARM编程。
 
 

回复

3138

帖子

0

TA的资源

裸片初长成(初级)

9
 
 贴一大堆代码让人直接找错不是提问的好办法,况且有时不是能“有没错”这么简单回答的,特别是涉及到概念、思路、方法的时候。

 其实正如楼上帅斑竹指出的,中断的关键是:触发源是“电平”还是“跃变沿”,按键检测的要害是“防抖动”。好好地把这两点琢磨清楚,脚下就是一马平川,也不必找什么高手低手看程序了。

 对按键处理而言俺的看法是,置电平触发,用定时器+状态机处理为上策。
此帖出自51单片机论坛

赞赏

1

查看全部赞赏

 
 
 

回复

2130

帖子

0

TA的资源

五彩晶圆(中级)

10
 
键盘处理逻辑有问题
此帖出自51单片机论坛
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表