4X4矩阵键盘扫描:

1. 4根行线的GIO均设为Output,根列线的GIO均设为Input;

2. 4根行线的GIO分别置为0111、1011、1101、1110,读逐一读取列线GIO的值,可确定是哪一个按键。

电路图例如以下:

注意:

1. 图中用作输入的GIO,一定要有一个上拉电阻。

2. 芯片中的每个引脚是否用作了GPIO口来用。需配置芯片的寄存器,使引脚当作GPIO口来使用,才会有效。

測试代码例如以下:

#define KEY_GIO_ROW_1	37
#define KEY_GIO_ROW_2 33
#define KEY_GIO_ROW_3 32
#define KEY_GIO_ROW_4 35
#define KEY_GIO_COL_1 22
#define KEY_GIO_COL_2 23
#define KEY_GIO_COL_3 24
#define KEY_GIO_COL_4 36
int scanKey()
{
int keyValue = 0;
int col1Value=0,col2Value=0,col3Value=0,col4Value=0,row1Value=0,row2Value=0,row3Value=0,row4Value=0;
static int press1=0,press2=0,press3=0,press4=0;
static int press5=0,press6=0,press7=0,press8=0;
static int press9=0,press10=0,press11=0,press12=0;
static int press13=0,press14=0,press15=0,press16=0; dm365SetGPIO(KEY_GIO_ROW_1, 0);
dm365SetGPIO(KEY_GIO_ROW_2, 1);
dm365SetGPIO(KEY_GIO_ROW_3, 1);
dm365SetGPIO(KEY_GIO_ROW_4, 1);
col1Value = dm365GetGPIO(KEY_GIO_COL_1);
col2Value = dm365GetGPIO(KEY_GIO_COL_2);
col3Value = dm365GetGPIO(KEY_GIO_COL_3);
col4Value = dm365GetGPIO(KEY_GIO_COL_4);
keyValue = col1Value | (col2Value << 1) | (col3Value << 2) | (col4Value << 3);
// printf("=1==keyValue = %x\n",keyValue);
switch(keyValue)
{
case 0x0E:
{
if(!press1)
{
press1 = 1;
printf("KEY 1\n");
}
}
break;
case 0x0D:
{
if(!press2)
{
press2 = 1;
printf("KEY 2\n");
}
}
break;
case 0x0B:
{
if(!press3)
{
press3 = 1;
printf("KEY 3\n");
}
}
break;
case 0x07:
{
if(!press4)
{
press4 = 1;
printf("KEY 4\n");
}
}
break;
default:
{
press1 = 0;
press2 = 0;
press3 = 0;
press4 = 0;
}
break;
} dm365SetGPIO(KEY_GIO_ROW_1, 1);
dm365SetGPIO(KEY_GIO_ROW_2, 0);
dm365SetGPIO(KEY_GIO_ROW_3, 1);
dm365SetGPIO(KEY_GIO_ROW_4, 1);
col1Value = dm365GetGPIO(KEY_GIO_COL_1);
col2Value = dm365GetGPIO(KEY_GIO_COL_2);
col3Value = dm365GetGPIO(KEY_GIO_COL_3);
col4Value = dm365GetGPIO(KEY_GIO_COL_4);
keyValue = col1Value | (col2Value << 1) | (col3Value << 2) | (col4Value << 3);
// printf("=2==keyValue = %x\n",keyValue);
switch(keyValue)
{
case 0x0E:
{
if(!press5)
{
press5 = 1;
printf("KEY 5\n");
}
}
break;
case 0x0D:
{
if(!press6)
{
press6 = 1;
printf("KEY 6\n");
}
}
break;
case 0x0B:
{
if(!press7)
{
press7 = 1;
printf("KEY 7\n");
}
}
break;
case 0x07:
{
if(!press8)
{
press8 = 1;
printf("KEY 8\n");
}
}
break;
default:
{
press5 = 0;
press6 = 0;
press7 = 0;
press8 = 0;
}
break;
} dm365SetGPIO(KEY_GIO_ROW_1, 1);
dm365SetGPIO(KEY_GIO_ROW_2, 1);
dm365SetGPIO(KEY_GIO_ROW_3, 0);
dm365SetGPIO(KEY_GIO_ROW_4, 1);
col1Value = dm365GetGPIO(KEY_GIO_COL_1);
col2Value = dm365GetGPIO(KEY_GIO_COL_2);
col3Value = dm365GetGPIO(KEY_GIO_COL_3);
col4Value = dm365GetGPIO(KEY_GIO_COL_4);
keyValue = col1Value | (col2Value << 1) | (col3Value << 2) | (col4Value << 3);
// printf("=3==keyValue = %x\n",keyValue);
switch(keyValue)
{
case 0x0E:
{
if(!press9)
{
press9 = 1;
printf("KEY 9\n");
}
}
break;
case 0x0D:
{
if(!press10)
{
press10 = 1;
printf("KEY 10\n");
}
}
break;
case 0x0B:
{
if(!press11)
{
press11 = 1;
printf("KEY 11\n");
}
}
break;
case 0x07:
{
if(!press12)
{
press12 = 1;
printf("KEY 12\n");
}
}
break;
default:
{
press9 = 0;
press10 = 0;
press11 = 0;
press12 = 0;
}
break;
} dm365SetGPIO(KEY_GIO_ROW_1, 1);
dm365SetGPIO(KEY_GIO_ROW_2, 1);
dm365SetGPIO(KEY_GIO_ROW_3, 1);
dm365SetGPIO(KEY_GIO_ROW_4, 0);
col1Value = dm365GetGPIO(KEY_GIO_COL_1);
col2Value = dm365GetGPIO(KEY_GIO_COL_2);
col3Value = dm365GetGPIO(KEY_GIO_COL_3);
col4Value = dm365GetGPIO(KEY_GIO_COL_4);
keyValue = col1Value | (col2Value << 1) | (col3Value << 2) | (col4Value << 3);
// printf("=4==keyValue = %x\n",keyValue);
switch(keyValue)
{
case 0x0E:
{
if(!press13)
{
press13 = 1;
printf("KEY 13\n");
}
}
break;
case 0x0D:
{
if(!press14)
{
press14 = 1;
printf("KEY 14\n");
}
}
break;
case 0x0B:
{
if(!press15)
{
press15 = 1;
printf("KEY 15\n");
}
}
break;
case 0x07:
{
if(!press16)
{
press16 = 1;
printf("KEY 16\n");
}
}
break;
default:
{
press13 = 0;
press14 = 0;
press15 = 0;
press16 = 0;
}
break;
} return keyValue;
}
void *KeyMngThread()
{
int resetValue = 1;
int resetCout = 0;
int alarmInValue = 1;
int alarmInCout = 0;
while(1)
{
resetValue = dm365GetGPIO(GIO_RESET);
if(0 == resetValue)
{
resetCout++;
}
else if(1 == resetValue)
{
resetCout = 0;
}
if(resetCout == 30)
{
resetCout = 0;
system("rm -f /mnt/nand/sysenv.cfg");
system("/bin/sync");
// System("reboot");
system("/tmp/shutdown -r now \n");
}
alarmInValue = dm365GetGPIO(GIO_ALARM_IN);
if(0 == alarmInValue)
{
dm365SetGPIO(GIO_LED,0); //control led off .
}
else if(1 == alarmInValue)
{
dm365SetGPIO(GIO_LED,1); //control led on .
} scanKey(); usleep(100000);
} }

代码中dm365SetGPIO( )里将GPIO默认设置为Output,

dm365GetGPIO( )中将GPIO默认设置为Input,

通过字符设备驱动实现应用层操作底层GPIO。

4X4矩阵键盘扫描程序的更多相关文章

  1. 4x4矩阵键盘 扫描程序

    一:不排除第四位异常处理 uchar JuzhenkeyScan() { // P3=0xfe; // temp=P3; // while(temp!=0xfe) // { // temp=P3; / ...

  2. 4x4矩阵键盘扫描

    4x4矩阵键盘扫描 Windows 10 IoT Core 是微软针对物联网市场的一个重要产品,与以往的Windows版本不同,是为物联网设备专门设计的,硬件也不仅仅限于x86架构,同时可以在ARM架 ...

  3. Win10 IoT C#开发 6 - 4x4矩阵键盘扫描

    Windows 10 IoT Core 是微软针对物联网市场的一个重要产品,与以往的Windows版本不同,是为物联网设备专门设计的,硬件也不仅仅限于x86架构,同时可以在ARM架构上运行. 上一章我 ...

  4. 「雕爷学编程」Arduino动手做(26)——4X4矩阵键盘模块

    37款传感器与模块的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止37种的.鉴于本人手头积累了一些传感器和模块,依照实践出真知(一定要动手做)的理念,以学习和交流为目的,这里 ...

  5. 基于FPGA的4x4矩阵键盘驱动调试

    好久不见,因为博主最近两个月有点事情,加上接着考试,考完试也有点事情要处理,最近才稍微闲了一些,这才赶紧记录分享一篇博文.FPGA驱动4x4矩阵键盘.这个其实原理是十分简单,但是由于博主做的时候遇到了 ...

  6. STM32 实现 4*4 矩阵键盘扫描(HAL库、标准库 都适用)

    本文实现的代码是基于STM32HAL库的基础上的,不过标准库也可以用,只是调用的库函数不同,逻辑跟配置是一样的,按我这里的逻辑来配置即可. 1.键盘原理图: 原理举例:先把 F0-F7 内部拉高,这样 ...

  7. stm32矩阵键盘扫描数据通过USB发送

                   Keyboard.c #include "keyboard.h"#include "my_usb.h"#include " ...

  8. MCU软件最佳实践——矩阵键盘驱动

    1.矩阵键盘vs独立按键 在mcu应用开发过程中,独立按键比较常见,但是在需要的按键数比较多时,使用矩阵键盘则可以减少io占用,提高系统资源利用率.例如,某mcu项目要求有16个按钮,如果采用独立按键 ...

  9. 【STM32学习笔记】STM32f407 使用4*4矩阵键盘

    作者:李剀 出处:https://www.cnblogs.com/kevin-nancy/ 欢迎转载,但也请保留上面这段声明.谢谢! 写在前面: 这是本人第一次开始写博客,可能写的不是很好,也请大家谅 ...

随机推荐

  1. 在Foreda8上试安装Apchehttpd-2.4.6.tar.gz

    下文是我边试边做的记录,不保证内容的完整性和正确性. 由于我的Apsire机器是最简安装Foreda8,所以需要安装httpd,熟悉一遍也是很好的嘛. 我从网上搜罗并下载了apchehttpd-2.4 ...

  2. Discuz常见小问题-如何修改导航栏

    1 比如我要修改第一个导航栏,则在界面-导航设置,主导航,然后点击右边的编辑按钮 2 比如我把"首页"的名字改成"论坛首页",别的都不改,然后点击提交,刷新页面 ...

  3. 破解无线网络密码-BT3如何使用2

    本教程只作学习和交流使用,任何其它商用与本人无关, 在开始教程之前, 首先需要用到几个软件,感兴趣的朋友看完贴子后可以去百度搜一下下载地址, 虚拟机: VMware Workstation 6.5 正 ...

  4. 线性表 顺序存储 链式存储 ---java实现

    首先抽象出一个线性表抽象类(包括主要的增删操作) public abstract class MyAbstractList<E> { public abstract void add(E ...

  5. Camel之AsyncProcessor

    Camel支持一种更复杂的异步的处理模型,异步处理器实现一个继承自Processor接口的AsyncProcessor接口,使用异步Processor的长处: a.异步Processor不会因等待堵塞 ...

  6. java正则表达式简介

    Java的正则表达式讲解:(为了能看清,本文正则表达式用中文的句号代替英文句点) 1 英文句点符号:匹配单个任意字符. eg: 表达式”t.o  可以匹配:tno,t#o,teo等等.不可以匹配:tn ...

  7. MySQL 设置慢查询为200ms

    1:查看当前版本并设置long_query_time为0.2 mysql> select version(); +------------+ | version() | +----------- ...

  8. Python之对象的属性

    # -*- coding: utf-8 -*- #python 27 #xiaodeng #Python之对象的属性 #http://python.jobbole.com/82622/ #对象的属性 ...

  9. HTTP报文01

    #xiaodeng #HTTP报文01 #HTTP权威指南 45 报文向下游流动- 不管是请求报文还是响应报文,所有报文都会向下游流动. 所有报文的发送者都在接收者的上游. 报文的组成部分 对报文进行 ...

  10. LR函数基础(二)

    (一)用到的函数: (1) web_set_option()   //重定向设置 (2)web_reg_save_param和custom_request都常于处理参数的动态生成. web_reg_s ...