OpenEdv-开源电子网

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

一个3*3键盘扫描程序的问题

[复制链接]

221

主题

501

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1238
金钱
1238
注册时间
2013-1-9
在线时间
121 小时
发表于 2016-2-23 09:28:36 | 显示全部楼层 |阅读模式
1金钱
本帖最后由 anazel 于 2016-2-23 09:30 编辑

程序如下:
PA6,PA7,PA8接行
PB5,PB6,PB7接列

u16 keyscan(void)  //实现矩阵键盘。返回值为各按键的键值,此键值由用户自己定义。

{
        int KeyVal;         //keyVal为最后返回的键值。
        
        GPIO_Write(GPIOA,(GPIOA->ODR & 0xfe3f | 0x01c0)); //先让PA6,PA7,PA8全部输出高。
        
        if((GPIOB->IDR & 0x00e0)==0x0000)  //如果PB5,PB6,PB7全为0,则没有键按下。此时,返回值为0.
                return 0;
        else
        {        
            delay_ms(5);    //延时5ms去抖动。
            if((GPIOB->IDR & 0x00e0)==0x0000)//如果延时5ms后,PB5到PB7又全为0,则,刚才引脚的电位变化是抖动产生的.
            return 0;
        }
        
        //GPIO_Write(GPIOA,(GPIOA->ODR & 0xfe3f | 0x0040));        //让PA8,PA7,PA6输出二进制的001.
        GPIOA->BSRR = 0x0040;
        
        switch(GPIOB->IDR & 0x00e0)//对PB5,PB6,PB7的值进行判断,以输出不同的键值。
        {
                case 0x0020: KeyVal = 1; break;
                case 0x0040: KeyVal = 2; break;
                case 0x0080: KeyVal = 3; break;
        }

        GPIO_Write(GPIOA,(GPIOA->ODR & 0xfe3f | 0x0080));        //让PBA,PA7,PA6输出二进制的010.

        switch(GPIOB->IDR & 0x00e0)//对PB5,PB6,PB7的值进行判断,以输出不同的键值。
        {
                case 0x0020: KeyVal=4;        break;
                case 0x0040: KeyVal=5;        break;
                case 0x0080: KeyVal=6;        break;
        }
        
        
        GPIO_Write(GPIOA,(GPIOA->ODR & 0xfe3f | 0x0100));        //让PB8,PA7,PA6输出二进制的100.
        
        switch(GPIOB->IDR & 0x00e0)//对PB5,PB6,PB7的值进行判断,以输出不同的键值。
        {
                case 0x0020: KeyVal=7;        break;
                case 0x0040: KeyVal=8;        break;
                case 0x0080: KeyVal=9;        break;
        }


        return KeyVal;               
}
这样写可以正常扫描出键值,如果把 GPIOA->BSRR = 0x0040;这句话换成
GPIO_Write(GPIOA,(GPIOA->ODR & 0xfe3f | 0x0040));        //让PA8,PA7,PA6输出二进制的001.
那么只有键值8判断不出来,其他的都能正确判断出来,不知道什么原因。


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

使用道具 举报

4

主题

49

帖子

0

精华

初级会员

Rank: 2

积分
193
金钱
193
注册时间
2016-1-14
在线时间
42 小时
发表于 2016-2-23 10:47:24 | 显示全部楼层
键值8的引脚是不是配置的输入模式?
回复

使用道具 举报

221

主题

501

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1238
金钱
1238
注册时间
2013-1-9
在线时间
121 小时
 楼主| 发表于 2016-2-23 10:54:11 | 显示全部楼层
管脚配置如下:
        
        GPIOStru.GPIO_Mode = GPIO_Mode_Out_PP;  //定义PA6,PA7,PA8为推挽输出。
        GPIOStru.GPIO_Speed = GPIO_Speed_50MHz;
        GPIOStru.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8;

        GPIO_Init(GPIOA,&GPIOStru);

       
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);

        GPIOStru.GPIO_Mode = GPIO_Mode_IPD;  //定义PB5,PB6,PB7为下拉输入。
        GPIOStru.GPIO_Speed = GPIO_Speed_50MHz;
        GPIOStru.GPIO_Pin = GPIO_Pin_5| GPIO_Pin_6|GPIO_Pin_7;
现在的问题是:
GPIOA->BSRR = GPIOA->ODR & 0xfe3f | 0x0040;   可以正常判断键值

GPIOA->ODR = GPIOA->ODR & 0xfe3f | 0x0040; 其他的都能正常判断,就是8不能判断出来,没反应。
一个是控制BSRR,一个是控制ODR,应该都是让PA8到PA6输出001吧,不知道什么原因对键值8的判断有影响。
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-20 22:49

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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