OpenEdv-开源电子网

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

矩阵键盘程序

[复制链接]

10

主题

71

帖子

0

精华

高级会员

Rank: 4

积分
817
金钱
817
注册时间
2016-2-5
在线时间
163 小时
发表于 2016-8-9 18:10:14 | 显示全部楼层 |阅读模式
10金钱
这两天在用F1写一个12个按键的矩阵键盘实验,用了一位吧友的库函数程序进行了改写,但是写完之后调试发现之后其中3个有效,另外9个怎么按都没有反应,检查了流程也没发现那有问题,求大神帮忙看一下到底那出了问题
[mw_shl_code=applescript,true]# include "key.h"
# include "delay.h"
# include "led.h"


void key_init(void)
{
RCC->APB2ENR |= 1<<4;
        
        GPIOC->CRL &= 0xf0000000;
        GPIOC->CRL |= 0x08888333;
}

u8 keyscan(void)
{
        u8 Lie, Hang, k, i;
        GPIOC->ODR |= 0x78;                //初始化行列,行全部拉低,01111000
        if((GPIOC->IDR & 0x78) != 0x78)        //IDR状态&上01111000是不是不等于01111000
        {
                delay_ms(10);//消抖
                if((GPIOC->IDR & 0x78) != 0x78)//在此判断,如果还不=
                {
                        Lie = GPIOC->IDR;        //读取IDR状态赋给Lie,但是Lie只有8位所以只接收低8位数据
                        Hang = Lie;                        //在把Lie里面的内容赋给Hang
                        Lie = ~Lie;                        //将Lie里面的内容取反列如01110000取反变成10001111
                        Lie &= 0x78;                //将取反之后的值&上0x78.10001111&01111000变成00001000即0x08
                        GPIOC->BRR = 0x7f;        //GPIOC低7位全部清零。
                        for(i=0; i<3&&((Hang&0x78) != 0x78); i++)        //将行循环拉高
                        {
                                GPIOC->ODR |= (Hang&0x78) | (0x01<<i);        //将Hang&0x78之后在左移i位
                                Hang = GPIOC->IDR;//再此读取IDR状态赋给Hang,因为一行被拉高所以如果有按键按下在这一行,按键的另一端会被拉高
                                GPIOC->BRR = 0x7f;//清零。
                        }
                        Hang &= 0x07;                //将Hang&00000111
                        k = Lie | Hang;                //将行列相加
                        GPIOC->ODR |= 0x78;        //将行列初始化
                        while((GPIOC->IDR&0x78) != 0x78)//判断按键是否还按下,如果是则进入循环等待
                        {
                                delay_ms(30);
                        }
                        GPIOC->BRR = 0x7f;                //清除低7位ODR状态
                        return k;                                //返回键值
                }
        }        
        return 0;
}

u8 keychuli(void)
{
        u8 key_1 = 0, keyz = 0;
        u8 i = 1;
        while(i)
        {
                keyz = keyscan();
                if(keyz != 0)
                {
                        switch(keyz)
                        {
                                case 0x09ED0 = !LED0; key_1 = 1; i--; break;
                                case 0x11ED1 = !LED1; key_1 = 2; i--; break;
                                case 0x21ED0 = !LED0; key_1 = 3; i--; break;
                                case 0x41ED1 = !LED1; key_1 = 4; i--; break;
                                case 0x0aED0 = !LED0; key_1 = 5; i--; break;
                                case 0x1aED1 = !LED1; key_1 = 6; i--; break;
                                case 0x2aED0 = !LED0; key_1 = 7; i--; break;
                                case 0x4aED1 = !LED1; key_1 = 8; i--; break;
                                case 0x0cED0 = !LED0; key_1 = 9; i--; break;
                                case 0x1cED1 = !LED1; key_1 = 10; i--; break;
                                case 0x2c:LED0 = !LED0; key_1 = 11; i--; break;
                                case 0x4c:LED1 = !LED1; key_1 = 12; i--; break;
                                default:break;
                        }
                }
        }        
        return key_1;
}[/mw_shl_code]
只有左边三个按键按下有效,其他几个都无效,求大神帮忙看一下,万分感谢

矩阵键盘

矩阵键盘

最佳答案

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

解决就好,可能我的思维方式和你不同,所以修改的方式也不一样
不甘黄土掩枯骨,宁化寒光映碧霄。
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

0

主题

40

帖子

0

精华

高级会员

Rank: 4

积分
756
金钱
756
注册时间
2016-2-25
在线时间
137 小时
发表于 2016-8-9 18:10:15 | 显示全部楼层
夜乄歌 发表于 2016-8-11 19:24
终于解决了,换了种写法,现在正常了好蛋疼,- -论坛寄存器的历程好少

解决就好,可能我的思维方式和你不同,所以修改的方式也不一样
回复

使用道具 举报

10

主题

71

帖子

0

精华

高级会员

Rank: 4

积分
817
金钱
817
注册时间
2016-2-5
在线时间
163 小时
 楼主| 发表于 2016-8-9 20:05:16 | 显示全部楼层
本帖最后由 夜乄歌 于 2016-8-9 20:06 编辑

坐等大神们都吃完饭约完会
不甘黄土掩枯骨,宁化寒光映碧霄。
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165524
金钱
165524
注册时间
2010-12-1
在线时间
2116 小时
发表于 2016-8-9 23:11:28 | 显示全部楼层
帮顶
回复

使用道具 举报

0

主题

40

帖子

0

精华

高级会员

Rank: 4

积分
756
金钱
756
注册时间
2016-2-25
在线时间
137 小时
发表于 2016-8-10 10:49:48 | 显示全部楼层
你应该不是左三个(S1、S5、S9)好使吧?应该是只能读回下边四个(S9、S10、S11、S12),程序到第26行你就已经判断出是哪一列按键按下,接下来的代码你循环拉高行,但是执行的结果是行拉高后你又把行的值原样读回来了,而且for循环执行一遍,最后只剩下第三行的值。
回复

使用道具 举报

0

主题

40

帖子

0

精华

高级会员

Rank: 4

积分
756
金钱
756
注册时间
2016-2-25
在线时间
137 小时
发表于 2016-8-10 10:59:22 | 显示全部楼层
你在for循环里代码替换成下面代码试试(增加一个变量Lie1)

GPIOC->ODR |= (Hang&0x78) | (0x01<<i);        
Hang = GPIOC->IDR;
GPIOC->BRR = 0x7f;
Lie1 = Hang & 0x78;
if(Lie1  != 0)
{break;}

回复

使用道具 举报

10

主题

71

帖子

0

精华

高级会员

Rank: 4

积分
817
金钱
817
注册时间
2016-2-5
在线时间
163 小时
 楼主| 发表于 2016-8-11 14:46:11 | 显示全部楼层
黎明前沉寂 发表于 2016-8-10 10:49
你应该不是左三个(S1、S5、S9)好使吧?应该是只能读回下边四个(S9、S10、S11、S12),程序到第26行你就 ...

是只有左边三个有效,循环拉高是就是为了将之前变低的那一端也拉高,这样在for的判断条件里面&0x78那个括号就为0,然后下面又&了0x07,这样行就出来了电平高的那一位就是行,在与列一加就是列行
不甘黄土掩枯骨,宁化寒光映碧霄。
回复

使用道具 举报

10

主题

71

帖子

0

精华

高级会员

Rank: 4

积分
817
金钱
817
注册时间
2016-2-5
在线时间
163 小时
 楼主| 发表于 2016-8-11 14:46:36 | 显示全部楼层
黎明前沉寂 发表于 2016-8-10 10:59
你在for循环里代码替换成下面代码试试(增加一个变量Lie1)

GPIOC->ODR |= (Hang&0x78) | (0x01BRR = 0x ...

昨天一天没在家,刚回来,我现在试一下哈
不甘黄土掩枯骨,宁化寒光映碧霄。
回复

使用道具 举报

10

主题

71

帖子

0

精华

高级会员

Rank: 4

积分
817
金钱
817
注册时间
2016-2-5
在线时间
163 小时
 楼主| 发表于 2016-8-11 15:57:42 | 显示全部楼层
黎明前沉寂 发表于 2016-8-10 10:59
你在for循环里代码替换成下面代码试试(增加一个变量Lie1)

GPIOC->ODR |= (Hang&0x78) | (0x01BRR = 0x ...

貌似不能这样改吧,这样改回导致只有第一排有效,因为lie1不管怎么样都是不等0的,所以只扫描了第一行就跳出循环了,我之前只有3个有效原因找到了,键值写错了,但是还是有点小问题正在调试中
不甘黄土掩枯骨,宁化寒光映碧霄。
回复

使用道具 举报

10

主题

71

帖子

0

精华

高级会员

Rank: 4

积分
817
金钱
817
注册时间
2016-2-5
在线时间
163 小时
 楼主| 发表于 2016-8-11 19:24:32 | 显示全部楼层
黎明前沉寂 发表于 2016-8-10 10:59
你在for循环里代码替换成下面代码试试(增加一个变量Lie1)

GPIOC->ODR |= (Hang&0x78) | (0x01BRR = 0x ...

终于解决了,换了种写法,现在正常了好蛋疼,- -论坛寄存器的历程好少
不甘黄土掩枯骨,宁化寒光映碧霄。
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-7 22:32

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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