找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2127|回复: 10
收起左侧

想问一下4*5矩阵键盘扫描如何编码的问题

[复制链接]
ID:891775 发表于 2021-5-12 13:54 来自手机 | 显示全部楼层 |阅读模式
4*5矩阵键盘应该怎么编码呀
回复

使用道具 举报

ID:716656 发表于 2021-5-12 16:02 | 显示全部楼层
把4*4的程序研究透,4*5的也好弄了,只不过多用1个其他组的IO,当然程序也会多一些内容,编码用与运算
回复

使用道具 举报

ID:213173 发表于 2021-5-12 17:03 | 显示全部楼层
给你一个示例参考。 矩阵键盘6 4异组端口读写 仿真.zip (119.54 KB, 下载次数: 26)
回复

使用道具 举报

ID:394903 发表于 2021-5-12 17:06 | 显示全部楼层
就跟点阵扫描是一样的
回复

使用道具 举报

ID:332444 发表于 2021-5-12 18:47 | 显示全部楼层
一组IO可以接32按键
回复

使用道具 举报

ID:332444 发表于 2021-5-12 18:50 | 显示全部楼层

回复

使用道具 举报

ID:743654 发表于 2021-5-13 09:29 | 显示全部楼层
wulin 发表于 2021-5-12 17:03
给你一个示例参考。

请问我主函数是while(1)里循环扫描按键,子函数也有用到按键,是不是按键也要在while(1)循环扫描?这样的话如何跳出子函数按键,回到主函数呢?
回复

使用道具 举报

ID:213173 发表于 2021-5-13 10:45 | 显示全部楼层
cheney03 发表于 2021-5-13 09:29
请问我主函数是while(1)里循环扫描按键,子函数也有用到按键,是不是按键也要在while(1)循环扫描?这 ...

按键扫描函数可以输出键值变量,其它子函数只要判断键值是否在其使用范围即可。
回复

使用道具 举报

ID:883031 发表于 2021-5-13 11:12 | 显示全部楼层
/*头文件*/
#include<stdio.h>
#include<at89x52.h>


///////////////////////////////////////////////////////////////////////////
//                         /*全局符号定义*/                             //            

#define DRV_NUM 4                        //行线数,驱动线<8
#define SCN_NUM 6                        //列线数,扫描线<8
#define TRUE 1
#define FALSE 0
#define HIGH 1
#define LOW 0
#define DELAY_VALUE 3                        //定义延时值

#define DRVKEY P2
#define SCNKEY P1

unsigned char DrvKey;                        //驱动线值
unsigned char ScnKey;                        //扫描线值

/*******************************************************************************
*   函数原型:bit KeyScan(void);
*   功    能:键盘扫描子程序,判断是否有键按下。
*******************************************************************************/
bit KeyScan(void)
{
        DRVKEY = 0xf0;
        ScnKey = SCNKEY ^ 0xff;      //列线值取反,以便判断
        ScnKey &= 0x3f;                       

        if (ScnKey != 0)                //列线值不全为0,则有键按下
        {
                return TRUE;
        }
        else                    //否则,无键按下
        {
                return FALSE;
        }       
}

/*******************************************************************************
*   函数原型:void Delay(unsigned char i);
*   功    能:延时子程序,用于去抖。
*******************************************************************************/
void Delay(unsigned char i)
{
        int j = 0;
        int k = 0;
        k = i * i;
        while (j < k)
        {
                j++;
        }
}
/*******************************************************************************
*   函数原型:bit AvoidWobble(void);
*   功    能:去抖子程序,用于消除抖动,判断是否真有键按下。
*******************************************************************************/
bit AvoidWobble(void)
{
        Delay(DELAY_VALUE);                //延时再读
        if (KeyScan())                        //仍有键按下,返回1
        {
                return TRUE;
        }
        else                    //无键按下则为抖动
        {
                return FALSE;
        }
}
/*******************************************************************************
*   函数原型:unsigned char GetKeyValue(void);
*   功    能:键盘子程序。最大8*8键盘。
*******************************************************************************/
unsigned char GetKeyValue(void)
{
        unsigned char i;
        unsigned char j;
        unsigned char Key_Value = 0;
        unsigned char temp = 0x01;
       
    if (KeyScan())              //有键按下取其值
    {
            if (AvoidWobble())                //确实有键按下,取其值
            {
                    for (i = 0;i < DRV_NUM;i++)   //行线移位送0
                    {
                            DRVKEY = (temp << i) ^ 0xff;
   
                            for (j =0;j < SCN_NUM;j++)   //列线移位扫描
                            {
                                ScnKey = SCNKEY;         //读列线值
                                    ScnKey >>= j;            
                                    ScnKey &= 0x01;
                                    if (ScnKey == 0)         //判断第j位是否为0
                                    {
                                            Key_Value += j;        //计算健值
                                            while(KeyScan())       //等待按键松开
                        {
                            ;
                        }
                                            return Key_Value;
                                    }
                            }
                            Key_Value += SCN_NUM;          //第i行无按键按下,键值加列线值,扫描第i+1行
                    }
                    return 255;
            }
            else
            {
                    return 255;
            }
    }
    else
    {
        return 255;
    }
}


这个程序没问题,你改一下行线和列线的定义就行了。
回复

使用道具 举报

ID:743654 发表于 2021-5-14 08:50 | 显示全部楼层
wulin 发表于 2021-5-13 10:45
按键扫描函数可以输出键值变量,其它子函数只要判断键值是否在其使用范围即可。

我之前就是这样操作的,貌似进入子函数,判断键值按键不起作用。按键扫描函数还得重新放到while(1)再扫描一遍,退出子函数循环不好退出,有时候还会有按键失灵的情况。
回复

使用道具 举报

ID:213173 发表于 2021-5-14 09:44 | 显示全部楼层
cheney03 发表于 2021-5-14 08:50
我之前就是这样操作的,貌似进入子函数,判断键值按键不起作用。按键扫描函数还得重新放到while(1)再扫描 ...

那是因为你的程序构架有严重缺陷才会发生这样问题。
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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