OpenEdv-开源电子网

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

求求大佬们拯救一下我,这个代码调整了好几天了,依旧读不出键值

[复制链接]

2

主题

16

帖子

0

精华

新手上路

积分
25
金钱
25
注册时间
2020-7-13
在线时间
3 小时
发表于 2020-7-24 18:44:29 | 显示全部楼层 |阅读模式
5金钱
本帖最后由 山猪王 于 2020-7-24 20:15 编辑
  1. //代码写的是矩阵键盘的读取键值,其中消抖采用了定时器的方法。这里高两位是P44 和P42   低六位是从P30到P35
复制代码
我看大家不能直接看见,所以又复制了过来。
这个子函数是在定时器中断里面调用的,定时器为5ms
恳求大佬们能救救我,万分感谢!!

unsigned char key_value;
void read_key(void)
{
  char  key_temp, key_temp_1, key_temp_2, key_temp_3, key_temp_4;
  char key_press=0;
        
  P3 = 0xcf;  P42 = 0;  P44 = 0;   //拉低高四位,看低四位是否有变化
         key_temp = P3;
        key_temp = key_temp & 0xcf;        //0xcf--11001111
        if(key_temp != 0xcf)  key_press++;  //消抖(定时器代码没贴,用的是5ms的定时器)
        else  key_press = 0;
        
  if( key_press == 3 )         //确定已经按下
    {
           P3=0xef;                               //0xef--11101111
           P42=1;            P44=1;      
           key_temp_1 = P3;
           key_temp_1 = key_temp_1 & 0xef;
            switch(key_temp_1)
           {
            case 0xee:
                key_value = 19;  break;               
            case 0xed:
                key_value = 18;  break;   
            case 0xeb:
                key_value = 17;  break;   
            case 0xe7:
                key_value = 16;  break;                                                
                  }
                        while(key_temp_1 != 0xef);   //判断是否释放
                                
                                                
            P3=0xdf;         //0xdf--11011111
            P42=1;            P44=1;
            key_temp_2 = P3;
            key_temp_2 = key_temp_2 & 0xdf;
            switch(key_temp_2)
            {
            case 0xde:
                key_value = 15;  break;               
            case 0xdd:
                key_value = 14;  break;   
            case 0xdb:
                key_value = 13;  break;   
            case 0xd7:
                key_value = 12;  break;
                  }
                        while(key_temp_2 != 0xdf);
                                
                                                
            P3=0xff;        
            P42=0;            P44=1;
            key_temp_3 = P3;
            key_temp_3 = key_temp_3 & 0xff;
            switch(key_temp_3)
            {
            case 0xfe:
                key_value = 11; break;               
            case 0xfd:
                key_value = 10; break;   
            case 0xfb:
                key_value = 9;  break;   
            case 0xf7:
                key_value = 8;  break;                                                
            }
                        while(key_temp_3 != 0x3f);
                                       
                                                
                P3=0xff;   
                P42=1;
                P44=0;
                key_temp_4 = P3;
            key_temp_4 = key_temp_4 & 0xff;
            switch(key_temp_4)
                {
                        case 0xfe:
                                key_value = 7;  break;               
                        case 0xfd:
                                key_value = 6;  break;   
                        case 0xfb:
                                key_value = 5;  break;   
                        case 0xf7:
                                key_value = 4;  break;                                
                 }
                        while(key_temp_4 != 0xff);            
         }                    
}               



正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

2

主题

16

帖子

0

精华

新手上路

积分
25
金钱
25
注册时间
2020-7-13
在线时间
3 小时
 楼主| 发表于 2020-7-24 20:16:23 | 显示全部楼层
山猪王被困四天多了,希望能有大侠出手相助,万分感激!!!
回复

使用道具 举报

30

主题

188

帖子

0

精华

高级会员

Rank: 4

积分
594
金钱
594
注册时间
2014-4-3
在线时间
74 小时
发表于 2020-7-25 23:28:31 | 显示全部楼层
《51单片机轻松入门-基于STC15W4K系列》第12章配套有各种按键程序(见附件),还有免费视频讲解。 第12章 接口程序.rar (307.23 KB, 下载次数: 6)
回复

使用道具 举报

10

主题

3281

帖子

1

精华

论坛元老

Rank: 8Rank: 8

积分
8205
金钱
8205
注册时间
2020-5-11
在线时间
3700 小时
发表于 2020-7-26 11:51:59 | 显示全部楼层
本帖最后由 LcwSwust 于 2020-7-26 11:53 编辑

char key_press=0;应在前面加static ,否则它怎么能加到3?
依我之见,先去掉消抖,消抖不应是按下时消,应在放开时消(连续3次放开则确定为放开)。基本功能整好后再加消抖。
代码先别整那么多,把一行(或一列)调通再说。
查询键值我不喜欢用
case 0xee:  key_value = 19;  break;
这种方式,若有多个键同时按下,你这case就不成立了。
我的方法是:
#define BIT(x) (1<<(x))
if((P3&BIT(0))==0)key_value=1;
if((P3&BIT(1))==0)key_value=2;
专治疑难杂症
回复

使用道具 举报

2

主题

16

帖子

0

精华

新手上路

积分
25
金钱
25
注册时间
2020-7-13
在线时间
3 小时
 楼主| 发表于 2020-7-29 10:32:12 | 显示全部楼层
LcwSwust 发表于 2020-7-26 11:51
char key_press=0;应在前面加static ,否则它怎么能加到3?
依我之见,先去掉消抖,消抖不应是按下时消,应 ...

key_press的问题后来我也发现了,改了之后依旧不行,我这个代码的思路是先进行总的消抖然后再判断是哪一个键值按下,现在我把顺序调整了一下,先判断哪一行或者哪一列被按下了,然后在消抖,消抖完确定是具体的哪一个键值,这样就行了,所以我就很奇怪
回复

使用道具 举报

3

主题

18

帖子

0

精华

初级会员

Rank: 2

积分
128
金钱
128
注册时间
2019-2-15
在线时间
29 小时
发表于 2020-7-29 19:11:05 | 显示全部楼层
原理图和新版的程序,贴一下,我看看
回复

使用道具 举报

3

主题

18

帖子

0

精华

初级会员

Rank: 2

积分
128
金钱
128
注册时间
2019-2-15
在线时间
29 小时
发表于 2020-7-29 19:18:48 | 显示全部楼层
5ms消抖时间太短了,建议至少10ms,稳妥一点,20ms
回复

使用道具 举报

2

主题

16

帖子

0

精华

新手上路

积分
25
金钱
25
注册时间
2020-7-13
在线时间
3 小时
 楼主| 发表于 2020-7-30 09:39:42 | 显示全部楼层
永远的lgz 发表于 2020-7-29 19:18
5ms消抖时间太短了,建议至少10ms,稳妥一点,20ms

我用key_press计数的,加起来相当于消抖了15ms
回复

使用道具 举报

2

主题

16

帖子

0

精华

新手上路

积分
25
金钱
25
注册时间
2020-7-13
在线时间
3 小时
 楼主| 发表于 2020-7-30 09:51:24 | 显示全部楼层
永远的lgz 发表于 2020-7-29 19:11
原理图和新版的程序,贴一下,我看看

#include <STC15F2K60S2.H>
#include <intrins.h>
#define uchar unsigned char


static uchar key_flag1;

static uchar num_1;
static uchar ge,shi,bai;
uchar code table[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
static uchar key_value;

void init(void)
{
        P2=(P2&0x1f)|0x80;
        P0=0xff;
        P2=(P2&0x1f)|0xa0;
        P0=0xaf;
        P2=(P2&0x1f)|0xe0;
        P0=0xff;
        P2&=0x1f;
        P3=0xff;
}       

void timersInit(void)
{
        TMOD &= 0xF0;               
        TL0 = 0x00;               
        TH0 = 0x28;                       
        TF0 = 0;                               
        TR0 = 1;               
        ET0=1;       
        EA=1;
}

void Delay10ms()                //@11.0592MHz
{
        unsigned char i, j;

        _nop_();
        _nop_();
        i = 108;
        j = 144;
        do
        {
                while (--j);
        } while (--i);
}



void display()
{       
        bai=num_1/100;
        shi=(num_1%100)/10;
        ge=num_1%10;
       
        P2=(P2&0x1f)|0xc0;
        P0=0x80;       
        P2=(P2&0x1f)|0xe0;
        P0=table[ge];       
        Delay10ms();
        P2=(P2&0x1f)|0xc0;
        P0=0x40;       
        P2=(P2&0x1f)|0xe0;
        P0=table[shi];
  Delay10ms();
        P2=(P2&0x1f)|0xc0;
        P0=0x20;       
        P2=(P2&0x1f)|0xe0;
        P0=table[bai];       
        Delay10ms();
        P2&=0x1f;
}

void read_key(void)
{
  static uchar  key_temp, key_temp_1, key_temp_2, key_temp_3, key_temp_4;
  static uchar key_press=0;      
  P3 = 0xcf;  P42 = 0;  P44 = 0;   
  key_temp = P3;
        key_temp = key_temp & 0xcf;        
        if(key_temp != 0xcf)  key_press++;  
        else  key_press = 0;

  if( key_press == 3 )        
    {
                         P3=0xef;                               //0xef--11101111
                         P42=1;   P44=1;      
                         key_temp_1 = P3;
                         key_temp_1 = key_temp_1 & 0xef;
                                switch(key_temp_1)
                         {
                                case 0xee:
                                                key_value = 19; key_flag1=1; break;               
                                case 0xed:
                                                key_value = 18; key_flag1=1; break;   
                                case 0xeb:
                                                key_value = 17; key_flag1=1; break;   
                                case 0xe7:
                                                key_value = 16; key_flag1=1; break;                                                
                                                        }
                                                                                while(key_temp_1 != 0xef);     //等待按键释放
                                                                                                               
                                                                                                                                                                               
                                P3=0xdf;         //0xdf--11011111
                                P42=1;            P44=1;
                                key_temp_2 = P3;
                                key_temp_2 = key_temp_2 & 0xdf;
                                switch(key_temp_2)
                                {
                                case 0xde:
                                                key_value = 15; key_flag1=1; break;               
                                case 0xdd:
                                                key_value = 14; key_flag1=1; break;   
                                case 0xdb:
                                                key_value = 13; key_flag1=1; break;   
                                case 0xd7:
                                                key_value = 12; key_flag1=1; break;
                                                        }
                                                                                while(key_temp_2 != 0xdf);
                                                                                                               
                                                                                                                                                                               
                                P3=0xff;        
                                P42=0;            P44=1;
                                key_temp_3 = P3;
                                key_temp_3 = key_temp_3 & 0xff;
                                switch(key_temp_3)
                                {
                                case 0xfe:
                                                key_value = 11; key_flag1=1;break;               
                                case 0xfd:
                                                key_value = 10; key_flag1=1;break;   
                                case 0xfb:
                                                key_value = 9;  key_flag1=1;break;   
                                case 0xf7:
                                                key_value = 8;  key_flag1=1;break;                                                
                                }
                                                                                while(key_temp_3 != 0x3f);
                                                                                                                                         
                                                                                                                                                               
                                P3=0xff;   
                                P42=1;
                                P44=0;
                                key_temp_4 = P3;
                                key_temp_4 = key_temp_4 & 0xff;
                                switch(key_temp_4)
                                                {
                                                                                case 0xfe:
                                                                                                                key_value = 7; key_flag1=1; break;               
                                                                                case 0xfd:
                                                                                                                key_value = 6; key_flag1=1; break;   
                                                                                case 0xfb:
                                                                                                                key_value = 5; key_flag1=1; break;   
                                                                                case 0xf7:
                                                                                                                key_value = 4; key_flag1=1; break;                                
                                                 }
                                                                                while(key_temp_4 != 0xff);            
                 }
         }
       
       
       
       




uchar key_handle(uchar num)
{
        switch(num)               
        {
                case 4: num++; break;
                case 5: num--; break;
                case 8: num=num+2; break;
                case 9: num=num-2; break;
                case 12: num=num+5; break;
                case 13: num=num-5; break;
                case 16: num=num+10; break;
                case 17: num=num-10; break;
                case 15: num=num+50; break;
                case 14: num=num-50; break;
                case 19: num=num+100; break;
                case 18: num=num-100; break;
                case 6: num=0; break;
                case 7: num=999; break;
                case 10: num=300; break;
                case 11: num=700; break;
                case 0: num=num; break;
        }
        if(num>999)
        {
                num=999;
        }
        return num;
}

void time0_sevice() interrupt 1
{
        if(key_flag1)    //只有当按键按下并且读到键值,才会进行下一步的键值处理
        {
                key_flag1=0;
                num_1=key_handle(key_value);  
        }
}


void Delay1000ms()                //@11.0592MHz
{
        unsigned char i, j, k;

        i = 43;
        j = 6;
        k = 203;
        do
        {
                do
                {
                        while (--k);
                } while (--j);
        } while (--i);
}

void main ()
{
    init();
    timersInit();  
    while(1)
    {
        display();

    }

}

回复

使用道具 举报

3

主题

18

帖子

0

精华

初级会员

Rank: 2

积分
128
金钱
128
注册时间
2019-2-15
在线时间
29 小时
发表于 2020-7-30 11:42:18 | 显示全部楼层
还有原理图啊,兄弟
回复

使用道具 举报

3

主题

18

帖子

0

精华

初级会员

Rank: 2

积分
128
金钱
128
注册时间
2019-2-15
在线时间
29 小时
发表于 2020-7-30 12:14:21 | 显示全部楼层
init();是要初始化些什么东西,没看懂,注释一下
回复

使用道具 举报

2

主题

16

帖子

0

精华

新手上路

积分
25
金钱
25
注册时间
2020-7-13
在线时间
3 小时
 楼主| 发表于 2020-8-3 10:48:30 | 显示全部楼层
永远的lgz 发表于 2020-7-30 11:42
还有原理图啊,兄弟

你说的是这个吗? 111.png

回复

使用道具 举报

2

主题

16

帖子

0

精华

新手上路

积分
25
金钱
25
注册时间
2020-7-13
在线时间
3 小时
 楼主| 发表于 2020-8-3 10:49:19 | 显示全部楼层
永远的lgz 发表于 2020-7-30 12:14
init();是要初始化些什么东西,没看懂,注释一下

这就是初始化蜂鸣器,LED,以及给数码管消隐
回复

使用道具 举报

3

主题

18

帖子

0

精华

初级会员

Rank: 2

积分
128
金钱
128
注册时间
2019-2-15
在线时间
29 小时
发表于 2020-8-3 12:35:38 | 显示全部楼层
j5的1脚和2脚用来做什么?整个原理图发给我,而不只是按键检测这一部分电路
QQ截图20200803123407.png
回复

使用道具 举报

3

主题

18

帖子

0

精华

初级会员

Rank: 2

积分
128
金钱
128
注册时间
2019-2-15
在线时间
29 小时
发表于 2020-8-3 12:37:20 | 显示全部楼层
我对你这个问题挺感兴趣的,你想解决问题的,就加紧时间回复,等了你几天才回复一句,太慢了,我这几天一直都在线的
回复

使用道具 举报

2

主题

16

帖子

0

精华

新手上路

积分
25
金钱
25
注册时间
2020-7-13
在线时间
3 小时
 楼主| 发表于 2020-8-5 11:32:36 | 显示全部楼层
永远的lgz 发表于 2020-8-3 12:35
j5的1脚和2脚用来做什么?整个原理图发给我,而不只是按键检测这一部分电路

这个就是矩阵键盘啊...因为自己一直在敲代码,忘记了上这个网站
回复

使用道具 举报

2

主题

16

帖子

0

精华

新手上路

积分
25
金钱
25
注册时间
2020-7-13
在线时间
3 小时
 楼主| 发表于 2020-8-5 11:35:27 | 显示全部楼层
山猪王 发表于 2020-8-3 10:48
你说的是这个吗?

CT107D电路原理图 - 副本_1.jpg
回复

使用道具 举报

2

主题

16

帖子

0

精华

新手上路

积分
25
金钱
25
注册时间
2020-7-13
在线时间
3 小时
 楼主| 发表于 2020-8-5 11:36:49 | 显示全部楼层
永远的lgz 发表于 2020-8-3 12:35
j5的1脚和2脚用来做什么?整个原理图发给我,而不只是按键检测这一部分电路

原理图是有点小问题的,就那个P36 P37     是被   P42 和P44代替的
回复

使用道具 举报

0

主题

8

帖子

0

精华

新手入门

积分
17
金钱
17
注册时间
2020-6-24
在线时间
4 小时
发表于 2020-8-5 12:11:05 | 显示全部楼层
是我没看明白你的代码吗?还是这么明显的逻辑问题你们没看见?
从你的代码逻辑看,不管read_key外部怎么调用的,函数内部都不可能出现key_press = 0;啊。
先  P3 = 0xcf; 然后 key_temp = P3;那key_temp 也必然是0xcf了,key_temp = key_temp & 0xcf;  后值也不会变,因此,下面的if判断后肯定是走了else key_press = 0;了。
void read_key(void)
{
  static uchar  key_temp, key_temp_1, key_temp_2, key_temp_3, key_temp_4;
  static uchar key_press=0;      
  P3 = 0xcf;  P42 = 0;  P44 = 0;   
  key_temp = P3;
        key_temp = key_temp & 0xcf;        
        if(key_temp != 0xcf)  key_press++;  
        else  key_press = 0;

  if( key_press == 3 )        
    {
回复

使用道具 举报

3

主题

18

帖子

0

精华

初级会员

Rank: 2

积分
128
金钱
128
注册时间
2019-2-15
在线时间
29 小时
发表于 2020-8-5 14:22:41 | 显示全部楼层
不用看什么,你这个read_key()都没有被main()调用过,怎么按键检测?
回复

使用道具 举报

2

主题

16

帖子

0

精华

新手上路

积分
25
金钱
25
注册时间
2020-7-13
在线时间
3 小时
 楼主| 发表于 2020-8-5 14:54:54 | 显示全部楼层
永远的lgz 发表于 2020-8-5 14:22
不用看什么,你这个read_key()都没有被main()调用过,怎么按键检测?

read_key()函数中给key_value赋值,然后在中断里面对key_value进行处理啊
回复

使用道具 举报

2

主题

16

帖子

0

精华

新手上路

积分
25
金钱
25
注册时间
2020-7-13
在线时间
3 小时
 楼主| 发表于 2020-8-5 14:55:25 | 显示全部楼层
永远的lgz 发表于 2020-8-5 14:22
不用看什么,你这个read_key()都没有被main()调用过,怎么按键检测?

key_value是全局变量,所以这函数我就没有加返回值
回复

使用道具 举报

3

主题

18

帖子

0

精华

初级会员

Rank: 2

积分
128
金钱
128
注册时间
2019-2-15
在线时间
29 小时
发表于 2020-8-5 23:12:10 | 显示全部楼层
山猪王 发表于 2020-8-5 14:55
key_value是全局变量,所以这函数我就没有加返回值

key_value的值变化发生在哪里?你不调用red_key(),键值发生变化了,你知道吗?
回复

使用道具 举报

0

主题

12

帖子

0

精华

初级会员

Rank: 2

积分
156
金钱
156
注册时间
2020-4-19
在线时间
30 小时
发表于 2020-8-13 16:15:54 | 显示全部楼层
                                P3=0xdf;         //0xdf--11011111
                                P42=1;            P44=1;
///这里最好加点延时    不少国产51是招架不住这么快
                                key_temp_2 = P3;
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2024-11-23 08:39

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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