野火电子论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 11362|回复: 28

基于STM32的复杂矩阵键盘扫描

[复制链接]
发表于 2016-7-19 10:49:54 | 显示全部楼层 |阅读模式
我想用STM32写一个36*4(行*列)的矩阵键盘扫描,我用的MCU是STM32F207ZGT6,我应该怎么写。。。各路神仙,求指导,谢谢!!!
回复

使用道具 举报

发表于 2016-7-19 11:18:23 | 显示全部楼层
这个只能靠自己写
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-7-19 11:37:27 | 显示全部楼层
许亮 发表于 2016-7-19 11:18
这个只能靠自己写

好吧,有没有参考程序呢
回复 支持 反对

使用道具 举报

发表于 2016-7-19 14:35:20 | 显示全部楼层
个人感觉思路还是很清晰的呀!!没有什么门槛呀!!可以自己尝试下!!
回复 支持 反对

使用道具 举报

发表于 2016-7-19 14:43:48 | 显示全部楼层
参考51的来写
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-7-20 09:33:10 | 显示全部楼层

好吧,我看着郭天祥的51矩阵键盘来写!!!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-7-20 09:33:40 | 显示全部楼层
Mr.Guo 发表于 2016-7-19 14:35
个人感觉思路还是很清晰的呀!!没有什么门槛呀!!可以自己尝试下!!

好吧,我看着郭天祥的51矩阵键盘来写!!!
回复 支持 反对

使用道具 举报

发表于 2016-7-20 09:35:16 | 显示全部楼层
我昨天写了一个4*4的矩阵键盘  基于STM32F1    36*4  应该和4*4的原理一样  采用的是库函数
回复 支持 反对

使用道具 举报

发表于 2016-7-20 09:49:22 | 显示全部楼层
a18270826679 发表于 2016-7-20 09:35
我昨天写了一个4*4的矩阵键盘  基于STM32F1    36*4  应该和4*4的原理一样  采用的是库函数

把代码发上来给大家学习下               
回复 支持 反对

使用道具 举报

发表于 2016-7-20 09:49:50 | 显示全部楼层
a18270826679 发表于 2016-7-20 09:35
我昨天写了一个4*4的矩阵键盘  基于STM32F1    36*4  应该和4*4的原理一样  采用的是库函数

发上来,这样就解决了楼主的问题了
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-7-20 10:19:03 | 显示全部楼层
a18270826679 发表于 2016-7-20 09:35
我昨天写了一个4*4的矩阵键盘  基于STM32F1    36*4  应该和4*4的原理一样  采用的是库函数

发上来看一下,大咖!!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-7-20 10:36:41 | 显示全部楼层
我的硬件就这样
QQ图片20160720103732.png
QQ图片20160720103737.png
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-7-20 10:40:02 | 显示全部楼层
我的Key_Scan()应该怎么写
QQ图片20160720104154.png
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-7-20 10:59:37 | 显示全部楼层
Mr.Guo 发表于 2016-7-19 14:35
个人感觉思路还是很清晰的呀!!没有什么门槛呀!!可以自己尝试下!!

主要问题是:我的行和列不是同一组GPIO。比如说:我的行是GPIOE,列是GPIOG,我的键盘扫描写起来有点吃力!
回复 支持 反对

使用道具 举报

发表于 2016-7-20 12:30:15 | 显示全部楼层
许亮 发表于 2016-7-20 09:49
把代码发上来给大家学习下


#include "./KEY/KEY.h"

void KEY_Init(void) //3õê¼»ˉ¾ØÕó¼üÅìòaê1óÃμÄGPIO¿ú¡£
{

        GPIO_InitTypeDef  GPIO_InitStructure;
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);

        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;       //¶¨ò&#229B8μ&#189B11ÎaéÏà-êäèë¡¢¡¢¡£
        GPIO_InitStructure.GPIO_Speed= GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6;
    GPIO_Init(GPIOB,&GPIO_InitStructure);
       
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;       //¶¨ò&#229B12μ&#189B15ÎaÏÂà-êäèë¡£
        GPIO_InitStructure.GPIO_Speed= GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10;
    //òòÎaéÏÃ涨òåòy½ÅÎaêä3öê±£¬òѾ-′ò¿aÕû¸öGPIOAμÄê±ÖóáË£¬
        //ËùòÔ′Ë′|2»ÔùDèòaoˉêyRCC_APB2PeriphClockCmd()à′′ò¿aê±ÖóáË¡£
    GPIO_Init(GPIOB,&GPIO_InitStructure);               
}
void delay_ms(unsigned        short time)
{
        unsigned short i=0;
        while(time--)
        {
                i=12000;
                while(i--);
        }
}
int KEY_Scan(void) //êμÏÖ¾ØÕó¼üÅì¡£·μ»ØÖμÎa£¬¸÷°′¼üμļüÖ죬′˼üÖμóéóû§×Ô¼o¶¨òå¡£
{
        u8 KeyVal;         //keyValÎa×îoó·μ»ØμļüÖμ¡£

        GPIO_SetBits(GPIOB,GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6);
       
                if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10)==0x0)
                return -1;
        else
        {       
            delay_ms(5);    //Ñóê±5ms襶¶¶ˉ¡£
        if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10)==0x0)
            return -1;
        }
        GPIO_ResetBits(GPIOB,GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6);
        GPIO_SetBits(GPIOB,GPIO_Pin_3);
                switch(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10))//¶&#212B12μ&#189B15μÄÖμ½øDDÅD¶Ï£¬òÔêä3ö2»í¬μļüÖμ¡£
                        {
                                case 0x1: KeyVal=15; break;
                                case 0x2: KeyVal=11;break;
                                case 0x4: KeyVal=7;        break;
                                case 0x8: KeyVal=3;        break;
                        }
        GPIO_ResetBits(GPIOB,GPIO_Pin_3|GPIO_Pin_5|GPIO_Pin_6);
        GPIO_SetBits(GPIOB,GPIO_Pin_4);
                switch(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10))//¶&#212B12μ&#189B15μÄÖμ½øDDÅD¶Ï£¬òÔêä3ö2»í¬μļüÖμ¡£
                {
                        case 0x1: KeyVal=14;        break;
                        case 0x2: KeyVal=10;        break;
                        case 0x4: KeyVal=6;        break;
                        case 0x8: KeyVal=2;        break;
                }

        GPIO_ResetBits(GPIOB,GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_6);
        GPIO_SetBits(GPIOB,GPIO_Pin_5);
                switch(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10))//¶&#212B12μ&#189B15μÄÖμ½øDDÅD¶Ï£¬òÔêä3ö2»í¬μļüÖμ¡£
                {
                        case 0x1: KeyVal=13;        break;
                        case 0x2: KeyVal=9;        break;
                        case 0x4: KeyVal=5;        break;
                        case 0x8: KeyVal=1;        break;
                }
        GPIO_ResetBits(GPIOB,GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5);
        GPIO_SetBits(GPIOB,GPIO_Pin_6);
                switch(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10))//¶ÔPB12μ½PB15μÄÖμ½øDDÅD¶Ï£¬òÔêä3ö2»í¬μļüÖμ¡£
                {
                        case 0x1: KeyVal=12;        break;
                        case 0x2: KeyVal=8;        break;
                        case 0x4: KeyVal=4;        break;
                        case 0x8: KeyVal=0;        break;
                }       
               
        return KeyVal;               
}

已经实现了。
回复 支持 反对

使用道具 举报

发表于 2016-7-20 12:30:39 | 显示全部楼层

#include "./KEY/KEY.h"

void KEY_Init(void) //3õê¼»ˉ¾ØÕó¼üÅìòaê1óÃμÄGPIO¿ú¡£
{

        GPIO_InitTypeDef  GPIO_InitStructure;
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);

        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;       //¶¨ò&#229B8μ&#189B11ÎaéÏà-êäèë¡¢¡¢¡£
        GPIO_InitStructure.GPIO_Speed= GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6;
    GPIO_Init(GPIOB,&GPIO_InitStructure);
       
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;       //¶¨ò&#229B12μ&#189B15ÎaÏÂà-êäèë¡£
        GPIO_InitStructure.GPIO_Speed= GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10;
    //òòÎaéÏÃ涨òåòy½ÅÎaêä3öê±£¬òѾ-′ò¿aÕû¸öGPIOAμÄê±ÖóáË£¬
        //ËùòÔ′Ë′|2»ÔùDèòaoˉêyRCC_APB2PeriphClockCmd()à′′ò¿aê±ÖóáË¡£
    GPIO_Init(GPIOB,&GPIO_InitStructure);               
}
void delay_ms(unsigned        short time)
{
        unsigned short i=0;
        while(time--)
        {
                i=12000;
                while(i--);
        }
}
int KEY_Scan(void) //êμÏÖ¾ØÕó¼üÅì¡£·μ»ØÖμÎa£¬¸÷°′¼üμļüÖ죬′˼üÖμóéóû§×Ô¼o¶¨òå¡£
{
        u8 KeyVal;         //keyValÎa×îoó·μ»ØμļüÖμ¡£

        GPIO_SetBits(GPIOB,GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6);
       
                if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10)==0x0)
                return -1;
        else
        {       
            delay_ms(5);    //Ñóê±5ms襶¶¶ˉ¡£
        if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10)==0x0)
            return -1;
        }
        GPIO_ResetBits(GPIOB,GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6);
        GPIO_SetBits(GPIOB,GPIO_Pin_3);
                switch(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10))//¶&#212B12μ&#189B15μÄÖμ½øDDÅD¶Ï£¬òÔêä3ö2»í¬μļüÖμ¡£
                        {
                                case 0x1: KeyVal=15; break;
                                case 0x2: KeyVal=11;break;
                                case 0x4: KeyVal=7;        break;
                                case 0x8: KeyVal=3;        break;
                        }
        GPIO_ResetBits(GPIOB,GPIO_Pin_3|GPIO_Pin_5|GPIO_Pin_6);
        GPIO_SetBits(GPIOB,GPIO_Pin_4);
                switch(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10))//¶&#212B12μ&#189B15μÄÖμ½øDDÅD¶Ï£¬òÔêä3ö2»í¬μļüÖμ¡£
                {
                        case 0x1: KeyVal=14;        break;
                        case 0x2: KeyVal=10;        break;
                        case 0x4: KeyVal=6;        break;
                        case 0x8: KeyVal=2;        break;
                }

        GPIO_ResetBits(GPIOB,GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_6);
        GPIO_SetBits(GPIOB,GPIO_Pin_5);
                switch(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10))//¶&#212B12μ&#189B15μÄÖμ½øDDÅD¶Ï£¬òÔêä3ö2»í¬μļüÖμ¡£
                {
                        case 0x1: KeyVal=13;        break;
                        case 0x2: KeyVal=9;        break;
                        case 0x4: KeyVal=5;        break;
                        case 0x8: KeyVal=1;        break;
                }
        GPIO_ResetBits(GPIOB,GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5);
        GPIO_SetBits(GPIOB,GPIO_Pin_6);
                switch(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10))//¶ÔPB12μ½PB15μÄÖμ½øDDÅD¶Ï£¬òÔêä3ö2»í¬μļüÖμ¡£
                {
                        case 0x1: KeyVal=12;        break;
                        case 0x2: KeyVal=8;        break;
                        case 0x4: KeyVal=4;        break;
                        case 0x8: KeyVal=0;        break;
                }       
               
        return KeyVal;               
}

已经实现了。
回复 支持 反对

使用道具 举报

发表于 2016-7-20 12:39:15 | 显示全部楼层
没写按键松检测
QQ图片20160720123447.png
QQ图片20160720123502.png
QQ图片20160720123516.png
QQ图片20160720123636.png
回复 支持 反对

使用道具 举报

发表于 2016-7-20 12:39:55 | 显示全部楼层
图片的顺序  有的乱 你们自己看的懂
回复 支持 反对

使用道具 举报

发表于 2016-7-20 12:50:37 | 显示全部楼层
火哥哥 发表于 2016-7-20 10:19
发上来看一下,大咖!!

STM32矩阵键盘实现4*4
http://www.firebbs.cn/forum.php? ... 6&fromuid=25747
(出处: 野火论坛)
完整的
回复 支持 反对

使用道具 举报

发表于 2016-7-20 12:50:58 | 显示全部楼层
万卿月 发表于 2016-7-20 09:49
发上来,这样就解决了楼主的问题了

STM32矩阵键盘实现4*4
http://www.firebbs.cn/forum.php? ... 6&fromuid=25747
(出处: 野火论坛)
回复 支持 反对

使用道具 举报

发表于 2016-7-20 12:51:18 | 显示全部楼层
许亮 发表于 2016-7-20 09:49
把代码发上来给大家学习下

STM32矩阵键盘实现4*4
http://www.firebbs.cn/forum.php? ... 6&fromuid=25747
(出处: 野火论坛)
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-7-20 15:51:47 | 显示全部楼层
a18270826679 发表于 2016-7-20 12:51
STM32矩阵键盘实现4*4
http://www.firebbs.cn/forum.php?mod=viewthread&tid=12556&fromuid=25747
(出 ...

你那样写不对吧,怎么调试出来的
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-7-20 15:52:14 | 显示全部楼层
火哥哥 发表于 2016-7-20 15:51
你那样写不对吧,怎么调试出来的

你QQ多少呢
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-7-20 15:54:54 | 显示全部楼层
你这样写能调试出来啊@a18270826679
QQ图片20160720155519.png
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-7-20 18:07:51 | 显示全部楼层
针对这个硬件,谁能帮我写一下键盘扫描
QQ图片20160720180857.png
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-7-21 14:04:30 | 显示全部楼层
我的这个FPC上面有36行*4列,用来检测水位,这个矩阵键盘搞得我好痛苦!!!
QQ图片20160721140443.jpg
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-7-21 14:08:23 | 显示全部楼层
我采用的值这种办法,我贴上来代码#include "main.h"
#include "usart.h"

#define IO_COL_1_H()        {GPIO_SetBits(GPIOG,GPIO_Pin_0);}
#define IO_COL_1_L()        {GPIO_ResetBits(GPIOG,GPIO_Pin_0);}
#define IO_COL_2_H()        {GPIO_SetBits(GPIOG,GPIO_Pin_1);}
#define IO_COL_2_L()        {GPIO_ResetBits(GPIOG,GPIO_Pin_1);}
#define IO_COL_3_H()        {GPIO_SetBits(GPIOG,GPIO_Pin_2);}
#define IO_COL_3_L()        {GPIO_ResetBits(GPIOG,GPIO_Pin_2);}
#define IO_COL_4_H()        {GPIO_SetBits(GPIOG,GPIO_Pin_3);}
#define IO_COL_4_L()        {GPIO_ResetBits(GPIOG,GPIO_Pin_3);}
#define IO_COL_5_H()        {GPIO_SetBits(GPIOG,GPIO_Pin_4);}
#define IO_COL_5_L()        {GPIO_ResetBits(GPIOG,GPIO_Pin_4);}
#define IO_COL_6_H()        {GPIO_SetBits(GPIOG,GPIO_Pin_5);}
#define IO_COL_6_L()        {GPIO_ResetBits(GPIOG,GPIO_Pin_5);}
#define IO_COL_7_H()        {GPIO_SetBits(GPIOG,GPIO_Pin_6);}
#define IO_COL_7_L()        {GPIO_ResetBits(GPIOG,GPIO_Pin_6);}

volatile u8 i;
void pr(u8 i, double num, u8 row_cnt)
{
        char str[10];
        double result;
        result = num + (row_cnt*2.400);
        if (i == 1)
        {
                sprintf(str, "%f", result);        //将浮点数转换成字符串
                printf("%s\r", str);
        }
}

void Key_Delay(uint32_t nCount)
{
        nCount *=1000;
  while(nCount > 0)
  {
            nCount --;   
  }
}


int main(void)
{
        u8 row_cout = 0;
       
        GPIO_InitTypeDef GPIO_InitStructure;
       
        SystemInit();                        //系统初始化
        USART2_Config();        //串口初始化

        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_GPIOE | RCC_AHB1Periph_GPIOF | RCC_AHB1Periph_GPIOG , ENABLE);
       
/***********************行方向***************************/
/***********************key input************************/       
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
        GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;        //定义PE0到PE3为下拉输入   
        GPIO_Init(GPIOE, &GPIO_InitStructure);


/***********************列方向***************************/
/***********************key output***********************/
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 ;       
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
        GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;        //定义PG0到PG6为推挽输出
        GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
        GPIO_Init(GPIOG, &GPIO_InitStructure);       
       

        IO_COL_1_L();
        IO_COL_2_L();
        IO_COL_3_L();
        IO_COL_4_L();
        IO_COL_5_L();
        IO_COL_6_L();
        IO_COL_7_L();
       
       
        while(1)
        {
                /**********************第1行***********************/
                /***************PG0,PG2,PG4,PG6-->PE2**************/   
                #if        1
                Key_Delay(10);
                IO_COL_1_H();
                Key_Delay(1);
                if(GPIO_ReadInputDataBit(GPIOE, GPIO_Pin_2))
                {
                        i = 1;
                        pr(i, 0.200*13, row_cout);
                }
               
                IO_COL_1_L();
                Key_Delay(10);
                IO_COL_3_H();
                Key_Delay(1);
                if(GPIO_ReadInputDataBit(GPIOE, GPIO_Pin_2))
                {
                        i = 1;
                        pr(i, 0.200*9, row_cout);
                }
               
                IO_COL_3_L();
                Key_Delay(10);
                IO_COL_5_H();
                Key_Delay(1);
                if(GPIO_ReadInputDataBit(GPIOE, GPIO_Pin_2))
                {
                        i = 1;
                        pr(i, 0.200*5, row_cout);
                }
               
                IO_COL_5_L();
                Key_Delay(10);
                IO_COL_7_H();
                Key_Delay(1);
                if(GPIO_ReadInputDataBit(GPIOE, GPIO_Pin_2))
                {
                        i = 1;
                        pr(i, 0.200*1, row_cout);
                }
                IO_COL_7_L();
               
        #endif
        }       
}
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-7-21 14:15:30 | 显示全部楼层
我想着怎么写一个简单的函数,要是按照我的36行都这样写,会不会疯掉
回复 支持 反对

使用道具 举报

发表于 2016-12-4 15:38:13 | 显示全部楼层
a18270826679 发表于 2016-7-20 12:30
#include "./KEY/KEY.h"

void KEY_Init(void) //3õê¼»ˉ¾ØÕó¼ ...

有完整工程文件吗
回复 支持 反对

使用道具 举报

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

本版积分规则

联系站长|手机版|野火电子官网|野火淘宝店铺|野火电子论坛 ( 粤ICP备14069197号 ) 大学生ARM嵌入式2群

GMT+8, 2025-1-13 07:42 , Processed in 0.070193 second(s), 27 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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