OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 14764|回复: 14

新手求助,我想写一个有两个按键的程序,K1按下数码管数字加1,K2按下数码管数字减1;

[复制链接]

66

主题

364

帖子

0

精华

初级会员

Rank: 2

积分
132
金钱
132
注册时间
2015-6-18
在线时间
129 小时
发表于 2015-7-2 20:07:34 | 显示全部楼层 |阅读模式
5金钱
这是源程序,求大神指点,我知道我写的不对。。。
[mw_shl_code=c,true]#include <reg51.h> #include <intrins.h> #define GPIO_LED P0 //led使用P0口 sbit K1=P1^0; sbit K2=P1^1; //--定义全局函数--// unsigned char code DIG_CODE[17]={ 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; //0、1、2、3、4、5、6、7、8、9、A、b、C、d、E、F的显示码 void Delay10ms(unsigned int c); //延时10ms unsigned char Key_Scan(); char KeyValue; void main(void) { while(1) { Key_Scan(); GPIO_LED=~DIG_CODE[KeyValue]; } } unsigned char Key_Scan() { unsigned char i; //保存键值 i=0; if (K1==0||K2==0) //检测按键是否按下 { Delay10ms(1); //消除抖动 if (K1==0||K2==0) //再次检测按键是否按下 { KeyValue=0; if(K1==0) { KeyValue++; if(KeyValue>17) KeyValue=0; } if(K2==0) { KeyValue--; if(KeyValue<0) KeyValue=17; } while ((i<50) && K1!=0 && K2!=0) //检测按键是否松开 { Delay10ms(1); i++; } } } } void Delay10ms(unsigned int c) //误差 0us { unsigned char a, b; for (;c>0;c--) { for (b=38;b>0;b--) { for (a=130;a>0;a--); } } }[/mw_shl_code]

最佳答案

查看完整内容[请看2#楼]

回复【9楼】linxi: -------------------------------- 仔细分析改了一下,感觉问题主要出现在KeyValue=0的定义是不是全局变量还有松手检测也出了问题。 改成如下功能就可以实现了(但是感觉按键还不是很灵敏。。。有时按一次没反应): unsigned char Key_Scan() { unsigned char i=0; //保存键值             if(K1==0)  { ...
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

66

主题

364

帖子

0

精华

初级会员

Rank: 2

积分
132
金钱
132
注册时间
2015-6-18
在线时间
129 小时
 楼主| 发表于 2015-7-2 20:07:35 | 显示全部楼层
回复【9楼】linxi:
--------------------------------
仔细分析改了一下,感觉问题主要出现在KeyValue=0的定义是不是全局变量还有松手检测也出了问题。 改成如下功能就可以实现了(但是感觉按键还不是很灵敏。。。有时按一次没反应):
unsigned char Key_Scan()
{
unsigned char i=0; //保存键值
            if(K1==0) 
{
Delay10ms(1);
if(K1==0)
{
KeyValue=KeyValue+1;
if(KeyValue>15)
KeyValue=0;
}
}
if(K2==0)
{
Delay10ms(1);
if(K2==0)

KeyValue=KeyValue-1;
if(KeyValue<0)
KeyValue=15;
    }
}
while ((i<30) && K1==0)  //检测按键是否松开
{
Delay10ms(1);
i++;
}
while ((i<30) && K2==0)  //检测按键是否松开
{
Delay10ms(1);
i++;
}
return 0;
}
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165309
金钱
165309
注册时间
2010-12-1
在线时间
2108 小时
发表于 2015-7-2 20:52:26 | 显示全部楼层
帮顶。。。。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

头像被屏蔽

6168

主题

7036

帖子

1

精华

论坛元老

Rank: 8Rank: 8

积分
19705
金钱
19705
注册时间
2012-12-27
在线时间
25 小时
发表于 2015-7-2 21:29:47 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
回复

使用道具 举报

66

主题

364

帖子

0

精华

初级会员

Rank: 2

积分
132
金钱
132
注册时间
2015-6-18
在线时间
129 小时
 楼主| 发表于 2015-7-3 08:48:20 | 显示全部楼层
回复【2楼】正点原子:
---------------------------------
...原子哥。。。
回复

使用道具 举报

66

主题

364

帖子

0

精华

初级会员

Rank: 2

积分
132
金钱
132
注册时间
2015-6-18
在线时间
129 小时
 楼主| 发表于 2015-7-3 08:49:59 | 显示全部楼层
回复【3楼】xouou_53320:
---------------------------------
因为那个定义的显示码是我直接复制过来的。。。好像那个显示码是共阴极的,而实际电路是共阳极。。
回复

使用道具 举报

0

主题

16

帖子

0

精华

新手上路

积分
36
金钱
36
注册时间
2015-2-12
在线时间
0 小时
发表于 2015-7-3 09:09:02 | 显示全部楼层
按键松手检测可以不用循环,直接定义两个keylock变量,key1==1&&keylock==0,才加一 ,一旦进去就把keylock置一。别的地方没有看出来问题。
不做浮躁的嵌入式攻城狮。。。。
回复

使用道具 举报

66

主题

364

帖子

0

精华

初级会员

Rank: 2

积分
132
金钱
132
注册时间
2015-6-18
在线时间
129 小时
 楼主| 发表于 2015-7-3 11:32:37 | 显示全部楼层
回复【6楼】linxi:
---------------------------------
key1==1&&keylock==0? 不太懂。。。
回复

使用道具 举报

66

主题

364

帖子

0

精华

初级会员

Rank: 2

积分
132
金钱
132
注册时间
2015-6-18
在线时间
129 小时
 楼主| 发表于 2015-7-3 11:33:57 | 显示全部楼层
回复【3楼】xouou_53320:
---------------------------------
解疑老师  求指点啊
回复

使用道具 举报

0

主题

16

帖子

0

精华

新手上路

积分
36
金钱
36
注册时间
2015-2-12
在线时间
0 小时
发表于 2015-7-3 14:14:20 | 显示全部楼层
回复【7楼】xiaobudonglaoshi:
---------------------------------
就是if(key1==1&&keylock1==0)然后执行相应的加一操作,然后立即把keylock1置一。在按键去抖里再将keylock置0,就可以避免while等待了。
另外不知道你现在发生的问题是什么,看了你的程序,应该是可以实现的。另外你为什么说自己写的不对?有没有烧进单片机验证下。
不做浮躁的嵌入式攻城狮。。。。
回复

使用道具 举报

66

主题

364

帖子

0

精华

初级会员

Rank: 2

积分
132
金钱
132
注册时间
2015-6-18
在线时间
129 小时
 楼主| 发表于 2015-7-3 21:08:45 | 显示全部楼层
回复【9楼】linxi:
---------------------------------
我写的那个只能加到1  然后就加不动了  减的话之间显示8.。。
回复

使用道具 举报

66

主题

364

帖子

0

精华

初级会员

Rank: 2

积分
132
金钱
132
注册时间
2015-6-18
在线时间
129 小时
 楼主| 发表于 2015-7-3 21:25:01 | 显示全部楼层
回复【9楼】linxi:
---------------------------------
对了  还有俩警告  :MAIN.C(80): warning C173: missing return-expression
MAIN.C(80): warning C290: missing return value
回复

使用道具 举报

1

主题

374

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1309
金钱
1309
注册时间
2014-7-23
在线时间
418 小时
发表于 2015-7-3 21:41:37 | 显示全部楼层
看看了这是普中例程。。。。没必要在它上面加,按自己理解重新写,问题在按键处理上而且逻辑都不对,警告是“unsigned char Key_Scan()”,又没有return.
回复

使用道具 举报

0

主题

16

帖子

0

精华

新手上路

积分
36
金钱
36
注册时间
2015-2-12
在线时间
0 小时
发表于 2015-7-6 08:27:36 | 显示全部楼层
回复【13楼】xiaobudonglaoshi:
---------------------------------
按键不灵敏的话,可以适当把防抖动延时减小一点。如果楼主是按照开发板的源程序改的,建议搞清楚原理自己试试能跑就行。因为这个程序在实际中不是很实用。学完相关的单片机外设后,可是试着用定时器累计变量值来实现去抖动,按键用自锁变量实现。原则就是不让单片机等待。加油吧!
不做浮躁的嵌入式攻城狮。。。。
回复

使用道具 举报

0

主题

2

帖子

0

精华

新手入门

积分
16
金钱
16
注册时间
2015-12-26
在线时间
2 小时
发表于 2015-12-26 20:48:13 | 显示全部楼层
缘分吧,看到这个网站,
附上我测试通过的程序:

#include<STC12C2052AD.h>
typedef unsigned int uint;
typedef unsigned char uchar;

sbit LED1=P3^5;
sbit LED2=P3^4;
sbit LED3=P3^3;
sbit LED4=P3^2;

sbit key=P3^1;
sbit key1=P3^0;

uint aa;
uchar i,ge,shi,bai,qian;
uchar code table[]={         //共阳数码管真值表,加code 数组将存入程序存储RAM内,不占用内存Rom Flash
0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8,
0x80, 0x90, 0x88, 0x83, 0xC6, 0xA1, 0x86, 0x8E
};

void delay(uint x)                          
{
        uint y;
        for(;x>0;x--)
                for(y=0;y<600;y--);
}

void main()
{
        bit x=0,y=0;
//        bit y=1;

        TMOD=0x01;
        TH0=(65536-500)/256;
        TL0=(65536-500)%256;
        EA=1;
        ET0=1;
        TR0=1;

        while(1)
        {

           ge=aa%10;
           shi=aa/10%10;
           bai=aa/100%10;
           qian=aa/1000%10;

           x=key;
           if(y!=key){
                      delay(100);
                        if(x==key){
                          if(y==0){
                          
                                   aa++;
                          }
                         y=key;
                        }
           }
                if(key1==0){aa=0;}

        }

}


void Timerinterrupt0()interrupt 1 //using 3
{
        TR0=0;
          TH0=(65536-500)/256;
        TL0=(65536-500)%256;

        P1=0xFF;
                 switch(i)
                 {
                   case 0: LED1=0;LED4=1;        i++;        P1=table[ge];        delay(1);        break;
                   case 1: LED2=0;LED1=1;        i++;        P1=table[shi];        delay(1);        break;
                   case 2: LED3=0;LED2=1;        i++;        P1=table[bai];        delay(1);        break;
                   case 3: LED4=0;LED3=1;        i=0;        P1=table[qian];        delay(1);        break;
                   default: LED1=1;LED2=1;LED3=1;LED4=1;        break;
                 }
           TR0=1;
}
回复

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-23 13:21

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表