OpenEdv-开源电子网

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

4*3矩阵键盘读取问题

[复制链接]

11

主题

92

帖子

0

精华

初级会员

Rank: 2

积分
131
金钱
131
注册时间
2016-3-27
在线时间
83 小时
发表于 2016-7-1 10:12:57 | 显示全部楼层 |阅读模式
10金钱
#include "stm32f10x.h"
#include "key.h"
#include "delay.h"

u8 KeyVal='0';
void Key_Init(void)  //初始化
{

        GPIO_InitTypeDef  GPIO_InitStructure;
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE); //使能时钟
       
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  //PC0-3设置推挽输出
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3;
       
        GPIO_Init(GPIOC,&GPIO_InitStructure);

       
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;  //PC8-10 设置下拉输入
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10;

        GPIO_Init(GPIOC,&GPIO_InitStructure);               
}

int key(void) //实现矩阵键盘。返回值为各按键的键值,自己定义
{
        // int KeyVal=0;        //keyVal为最后返回的键值

        //GPIO_SetBits(GPIOC,GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3);//PC0到PC3全部输出为高

       
        GPIO_Write(GPIOC,(GPIOC->ODR & 0xfff0 | 0x0)); //PC0到PC3全部输出为高
       
        if((GPIOC->IDR & 0x0F00)==0x0000)  //如果PC8到PC10全为0,则没有键按下,返回值为-1
                return -1;
    else
        {       
                DelayMs(5);    //延时5ms去抖
                if((GPIOC->IDR & 0x0F00)==0x0000)  //如果延时10ms后,PC8到PC10又全为0,则刚才引脚的电位变化是抖动产生的
                        return -1;
        }

        GPIO_Write(GPIOC,(GPIOC->ODR & 0xfff0 | 0x1));        //让PC0-3输出为二进制的0001
        switch(GPIOC->IDR & 0x0F00)                                //对PC8到PC10进行判断,输出不同的键值
        {
                case 0x0100: KeyVal='#';        break;
                case 0x0200: KeyVal='9';        break;
                case 0x0400: KeyVal='6';        break;
                case 0x0800: KeyVal='3';        break;
        }

        GPIO_Write(GPIOC,(GPIOC->ODR & 0xfff0 | 0x2));        //让PC0-3输出为二进制的0010
        switch(GPIOC->IDR & 0x0F00)                                //对PC8到PC10进行判断,输出不同的键值
        {
                case 0x0100: KeyVal='0';        break;
                case 0x0200: KeyVal='8';        break;
                case 0x0400: KeyVal='5';        break;
                case 0x0800: KeyVal='2';        break;
        }

        GPIO_Write(GPIOC,(GPIOC->ODR & 0xfff0 | 0x4));        //让PC0-3输出为二进制的0100
        switch(GPIOC->IDR & 0x0F00)                                //对PC8到PC10进行判断,输出不同的键值
        {
                case 0x0100: KeyVal='*';        break;
                case 0x0200: KeyVal='7';        break;
                case 0x0400: KeyVal='4';        break;
                case 0x0800: KeyVal='1';        break;
        }

       
        return KeyVal;               
}

这样写有什么问题吗,为什么KeyVal没有值返回,我想通过KeyVal传递给OLED,
在OLED中我定义了这样一个函数void OLED_ShowStr(unsigned char x, unsigned char y, unsigned char ch[], unsigned char TextSize);


void OLED_ShowStr(unsigned char x,unsigned char y,unsigned char ch[],unsigned char TextSize)
{
        unsigned char c = 0,i = 0,j = 0;
        switch(TextSize)
        {
/*                case 1:
                {
                while(ch[j] != '\0')
                {
                        c = ch[j] - 32;
                        if(x > 126)
                        {
                                x = 0;
                                y++;       
                        }
                        OLED_SetPos(x,y);
                        for(i=0;i<6;i++)
                                WriteDat(F6x8[c][i]);
                        x += 6;
                        j++;
                }
        }break;*/
                case 2:
                {
                        while(ch[j] !='\0')
                        {
                                c = ch[j]-32;
                                if(x>120)
                                {
                                        x = 0;
                                        y++;
                                }
                                OLED_SetPos(x,y);
                                for(i=0;i<8;i++)
                                        WriteDat(F8X16[c*16+i]);
                                OLED_SetPos(x,y+1);
                                for(i=0;i<8;i++)
                                        WriteDat(F8X16[c*16+i+8]);
                                x +=8;
                                j++;
                        }
                }break;
        }
}       


主函数中直接这样传递                        OLED_ShowStr(70,3,&KeyVal,2);

最后结果是可以显示预先设定的0,但按键没反应,有时候还会自动跳变成1,不知道问题在哪,DEBUG运行看KeyVal值,运行几次就变成1了

求助,新人很多基础问题不会,提前感谢大家耐心回答

最佳答案

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

那你显示一位数怎么显示的?依样画葫芦,多试,多看看资料,驱动函数 这个还是自己琢磨吧,总不能帮你看资料,帮你写程序吧,实践出真知
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

0

主题

183

帖子

0

精华

高级会员

Rank: 4

积分
684
金钱
684
注册时间
2016-1-27
在线时间
184 小时
发表于 2016-7-1 10:12:58 | 显示全部楼层
comprends 发表于 2016-7-1 17:06
就是这边扫描到的数据传给OLED显示出来,现在扫描到0~9,我想显示多位数,不知道怎么写

那你显示一位数怎么显示的?依样画葫芦,多试,多看看资料,驱动函数
这个还是自己琢磨吧,总不能帮你看资料,帮你写程序吧,实践出真知
回复

使用道具 举报

11

主题

92

帖子

0

精华

初级会员

Rank: 2

积分
131
金钱
131
注册时间
2016-3-27
在线时间
83 小时
 楼主| 发表于 2016-7-1 11:44:14 | 显示全部楼层
问题找到了。。因为没有用到PC8-PC11,所以   “    if((GPIOC->IDR & 0x0F00)==0x0000) “  这句代码里的F,应该该为7,,后续的所有涉及到PC8-PC10的都得更改。。
回复

使用道具 举报

11

主题

92

帖子

0

精华

初级会员

Rank: 2

积分
131
金钱
131
注册时间
2016-3-27
在线时间
83 小时
 楼主| 发表于 2016-7-1 11:44:59 | 显示全部楼层
另外,请教一下,怎么让他输出多位,比如说我按了1,显示出1,再按2,要求在后面显示2,就是说要显示12,或123这种多位数字
回复

使用道具 举报

0

主题

183

帖子

0

精华

高级会员

Rank: 4

积分
684
金钱
684
注册时间
2016-1-27
在线时间
184 小时
发表于 2016-7-1 15:06:04 | 显示全部楼层
comprends 发表于 2016-7-1 11:44
另外,请教一下,怎么让他输出多位,比如说我按了1,显示出1,再按2,要求在后面显示2,就是说要显示12,或 ...

显示到哪里?
按键扫描+显示输出就可以,是不知道怎么驱动显示吗?
回复

使用道具 举报

11

主题

92

帖子

0

精华

初级会员

Rank: 2

积分
131
金钱
131
注册时间
2016-3-27
在线时间
83 小时
 楼主| 发表于 2016-7-1 17:06:19 | 显示全部楼层
不吃鱼的老鼠 发表于 2016-7-1 15:06
显示到哪里?
按键扫描+显示输出就可以,是不知道怎么驱动显示吗?

就是这边扫描到的数据传给OLED显示出来,现在扫描到0~9,我想显示多位数,不知道怎么写
回复

使用道具 举报

1

主题

7

帖子

0

精华

新手上路

积分
26
金钱
26
注册时间
2016-7-21
在线时间
6 小时
发表于 2016-7-21 13:03:01 | 显示全部楼层
你这个按键松检测没加?
回复

使用道具 举报

11

主题

92

帖子

0

精华

初级会员

Rank: 2

积分
131
金钱
131
注册时间
2016-3-27
在线时间
83 小时
 楼主| 发表于 2016-7-25 17:55:18 | 显示全部楼层
a18270826679 发表于 2016-7-21 13:03
你这个按键松检测没加?

什么意思呢?我现在这个程序已经通了,可以达到我想要的效果,按下,显示,有消抖,但是不能连按,比如说你一直按着他会一直出数字,按一下松开就会显示
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-9 04:15

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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