先定义矩阵键盘自定义按键设置按键编号为0~F,要求按动按键时,将按键编 号发送到对方的单片机并在LED上显示出

  下面以51综合学习系统为硬件平台,介绍矩阵式键盘的编程方法。具体功能为:按下其键后,在一位上显示出键值。0到16个键分别对应显示0到F。
  1、硬件原理    本实验可以直接在配套开发板上完成,图如下图所示。
  根据电路原理图,键盘扫描方法是:行线P1O~P13为输出线,列线P14~P17为输入线。一开始单片机将行线(P1O-P13)全部输出低,此时读入列线数据,若列线全为高电平说明没有键接下,若有列线为低电平则调用延时程序来去除按键抖动。延时后再读入列线看是否有低电平,如果列线数据还是有低电平,说明确实有键接下,接下来便是确定键值。下面以第二行的S5键为例,看接下S5后我们应该怎么得到这个键值。当判定确实有键接下之后,将行线轮流置为低电平,根据读入列线的数据可以确定键值。首先,单片机将P1O置为低电平,P11~P13置为高电平,此时读出的列线数据全为高电平,说明第一行没有键接下;接着单片机将P11输出低电平,P1O、P12、P13置为高电平,再读列线数据,此时的列线数值为1011(OxOB),即P11与P15交叉点上的按键S5被接下,而OxOB就代表S5的键值了。转到S5键功能处理子程序就可以达到目的。
    2.程序流程    软件流程图如下图所示。51单片机综合学习系统资源丰富,板内有:8位数码管、32路LED、4x4矩阵键盘、4个直控按键盘、蜂鸣器喇叭、试验、I2C总线接口、SPI总线接口、l60x液晶、l28x64液晶、红外接收头接口、支持PS/2接口的104键标准键盘、驱动接口、ADCO832模/数转换接口、PC817光电耦合器、串行时钟芯片DSl302、温度DSl8B2O按口、RS232串口通讯、外扩展接口等,可以方便地接更多的实验资源。
  3. 软件代码    相关的软件代码如下:    /* 矩阵键盘测试程序*/
&&&&&往下看有更多相关资料
试试再找找您想看的资料
资料搜索:
查看相关资料 & & &
   同意评论声明
   发表
尊重网上道德,遵守中华人民共和国的各项有关法律法规
承担一切因您的行为而直接或间接导致的民事或刑事法律责任
本站管理人员有权保留或删除其管辖留言中的任意内容
本站有权在网站内转载或引用您的评论
参与本评论即表明您已经阅读并接受上述条款
copyright & &广电电器(中国梧州) -all right reserved& 若您有什么意见或建议请mail: & &
地址: 电话:(86)774-2826670& & &&)单片机显示与按键项目报告_图文_百度文库
您的浏览器Javascript被禁用,需开启后体验完整功能,
享专业文档下载特权
&赠共享文档下载特权
&10W篇文档免费专享
&每天抽奖多种福利
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
单片机显示与按键项目报告
阅读已结束,下载本文需要
想免费下载本文?
定制HR最喜欢的简历
下载文档到电脑,同时保存到云知识,更方便管理
加入VIP
还剩25页未读,
定制HR最喜欢的简历
你可能喜欢51单片机综合学习系统之矩阵键盘篇 《电子制作》2007年11月
51单片机综合学习系统之矩阵键盘篇 《电子制作》2007年11月 站长原创,如需引用请注明出处
&&&&大家好,通过以前的学习,我们已经对51单片机综合学习系统的使用方法及学习方式有所了解与熟悉,学会了单片机控制数码管显示的基本知识,体会到了综合学习系统的易用性与易学性,这一期我们将来一起学习矩阵键盘的基本原理与使用方法。
矩阵键盘应用实例
&&&&本期介绍了独立按键的应用,独立按键具有编程简单但占用I/O口资源的特点,不适合在按键较多的场合应用。在实际应用中经常要用到输入数字、字母等功能,如电子密码锁、电话机键盘等一般都至少有12到16个按键,在这种情况下如果用独立按键的话显然太浪费I/O口资源,为此我们就引入了矩阵键盘的应用。
矩阵键盘简介
&&&&矩阵键盘又称行列键盘,它是用四条I/O线作为行线,四条I/O线作为列线组成的键盘。在行线和列线的每个交叉点上设置一个按键。这样键盘上按键的个数就为4*4个。这种行列式键盘结构能有效地提高单片机系统中I/O口的利用率。
矩阵键盘的工作原理
&&&&最常见的键盘布局如图1所示。一般由16个按键组成,在单片机中正好可以用一个P口实现16个按键功能,这也是在单片机系统中最常用的形式,4*4矩阵键盘的内部电路如图2所示。
图1 矩阵键盘布局图
图2 矩阵键盘内部电路图
&&&&当无按键闭合时,P10~P13与P14~P17之间开路。当有键闭合时,与闭合键相连的两条I/O口线之间短路。判断有无按键按下的方法是:一步,置列线P14~P17为输入状态,从行线P10~P13输出低电平,读入列线数据,若某一列线为低电平,则该列线上有键闭合。第二步,行线轮流输出低电平,从列线P14~P17读入数据,若有某一列为低电平,则对应行线上有键按下。综合一二两步的结果,可确定按键编号。但是键闭合一次只能进行一次键功能操作,因此须等到按键释放后,再进行键功能操作,否则按一次键,有可能会连续多次进行同样的键操作。
矩阵键盘软硬件设计实例
&&&&本期以51单片机综合学习系统为硬件平台,介绍矩阵式键盘的编程方法。实验通过按下相应键后在一位数码管上显示出键值。0到16个键分别对应显示0到F。
图3 矩阵键盘实验演示图
10.1.3.1 硬件原理图
&&&&本实验可以直接在配套开发板上完成,其硬件原理图如图4所示:
图4 硬件原理图
&&&&根据4电路原理图,键盘扫描方法是:行线P10~P13为输出线,列线P14~P17为输入线。一开始单片机将行线(P10~P13)全部输出低电平,此时读入列线数据,若列线全为高电平则没有键按下,当列线有出现低电平时调用延时程序以此来去除按键抖动。延时完成后再判断是否有低电平,如果此时读入列线数据还是有低电平,则说明确实有键按下。较后一步确定键值。现在我们以第二行的S5键为例,若按下S5后我们应该怎么得到这个键值呢?当判断确实有键按下之后,行线轮流输出低电平,根据读入列线的数据可以确定键值。首先,单片机将P10输出为低电平,其它P11~P13输出高电平,此时读取列线的数据全为高电平,说明没有在一行有键按下;其次,单片机将P11输出低电平,其它P10、P12、P13仍为高电平,此时再来读取列线数据,发现列线读到的数据有低电平,数值为B),如果我们的键盘布局已经确定,那么0x0B就代表S5的值了。转到S5键功能处理子程序就可以达到目的。
程序流程图
10-5 软件流程图
&&&&51单片机综合学习系统资源丰富,可做实验有:8位LED数码管、32路LED、4x4矩阵键盘、4个直控键盘、蜂鸣器喇叭、继电器试验、I2C总线接口、SPI总线接口、160X液晶、128X64液晶、红外接收头接口、支持PS/2接口的104键标准键盘、步进电机驱动接口、ADC0832模/数转换接口、PC817光电耦合器、串行时钟芯片DS1302、温度传感器DS18B20接口、RS232串口通讯、外扩展接口以便外接更多的实验资源。
/***************************************************************************/
/*杭州晶控电子有限公司*/
/*http://www.hificat.com*/
/*矩阵键盘测试程序*/
/*目标器件:AT89S51*/
/*晶振:11.0592MHZ*/
/*编译环境:Keil 7.50A*/
/***************************************************************************/
/*********************************包含头文件********************************/
#include&reg51.h&
/*********************************数码管表格********************************/
unsigned char table[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,
0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E};
/****************************************************************************
函数功能:延时子程序
****************************************************************************/
void delay(void)
unsigned char i,j;
for(i=0;i&20;i++)
for(j=0;j&250;j++);
/****************************************************************************
函数功能:LED显示子程序
入口参数:i
****************************************************************************/
void display(unsigned char i)
P0=table[i];
/****************************************************************************
函数功能:键盘扫描子程序
****************************************************************************/
void keyscan(void)
//扫描一行
if(n!=0xf0)
if(n!=0xf0)
case(0xe0):display(3);
case(0xd0):display(2);
case(0xb0):display(1);
case(0x70):display(0);
//扫描第二行
if(n!=0xf0)
if(n!=0xf0)
case(0xe0):display(7);
case(0xd0):display(6);
case(0xb0):display(5);
case(0x70):display(4);
//扫描第三行
if(n!=0xf0)
if(n!=0xf0)
case(0xe0):display(11);
case(0xd0):display(10);
case(0xb0):display(9);
case(0x70):display(8);
//扫描第四行
if(n!=0xf0)
if(n!=0xf0)
case(0xe0):display(15);
case(0xd0):display(14);
case(0xb0):display(13);
case(0x70):display(12);
/****************************************************************************
函数功能:主程序
****************************************************************************/
void main(void)
keyscan();
以上部分内容转载于网上,如有涉及到版权问题,请即通知本人删除 浙ICP备号
联系地址:浙江省杭州市西湖科技园西园七路3号4层
邮政编码:310011&Email:
电话总机:0 &&产品咨询:转分机1 &&技术支持:转分机2 &&传真:转分机3 &&手机:
技术QQ熊工:
技术QQ徐工:
杭州晶控电子有限公司 版权所有
COPYRIGHT2003――2011 HANGZHOU KinCony ELECTRONICS CO.,LTD All
rights reserved【创龙AM4379 Cortex-A9试用体验】之编写4X4矩阵键盘驱动及基于QT GUI的键盘输入测试 - ARM技术论坛 -
中国电子技术论坛 -
最好最受欢迎电子论坛!
后使用快捷导航没有帐号?
林超文手把手教你学!
教你1000种电路设计思路
张飞硬件电路之PFC全集
参与免费送VIP+原创视频
运放、ADC、电磁兼容
【创龙AM4379 Cortex-A9试用体验】之编写4X4矩阵键盘驱动及基于QT GUI的键盘输入测试
助理工程师
22:19:49  
【创龙AM4379 Cortex-A9试用体验】之编写4X4矩阵键盘驱动及基于QT GUI的键盘输入测试在上篇试用报告《【创龙AM4379 Cortex-A9试用体验】之采用GPIO扩展口自定义键盘Input驱动+QT界面键盘输入测试》中,我们用4个按键模拟了数字1,数字2,以及TAB、ENTER键,使得通过GPIO的扩展口连接按键,结合上拉电阻实现了一般机械键盘的功能,但是,对按键较少的应用中,比如只需要输入0-9字符时,单个按键连接单个I/O口实现键盘功能还可以采用,但是如果我们需要一个功能相对较完整的数字键盘,如需具有0-9,小数点、空格键、TAB键、ENTER键、SHIFT键、退格键等等时,如果采用上一篇试用报告讲解的方法,就有点儿太浪费GPIO端口了,在工业应用中,GPIO口是非常宝贵的资源,我们在设计输入输出时,尽量会留一些备用接口,以备工业调试现场时一些为规划功能的扩展需要。我们这里采用单片机通常都会采用的行X列矩阵键盘,由行触发的中断,调用列的扫描方式,测试用户到底按下了哪个键。如果在单片机的应用中,实现4X4矩阵键盘的功能就比较简单了,而对于Linux系统下的4X4键盘,我们必须为其编写符合Linux Input规范的驱动程序。鉴与TL-4379运行的是QT5.4.1版本的GUI,而有别于QT4,& && & QT5的软键盘开发变化较大,我暂时还没有搞定QT5的软键盘移植,但是又想有输入,并且满足特殊行业禁止使用触摸屏的要求,我们这里就以4X4矩阵键盘为例,开发其在Linux下的Input驱动程序,并在QT GUI界面测试编写的矩阵键盘驱动程序的正确性。1. 硬件搭建为了完成本次测试,并为今后的开发板功能开发提供便利,特意从某宝上买了一块4X4键盘,尽量减少开发过程中繁琐的连线。4X4矩阵键盘如图所示:
QQ图片42.png (495.66 KB, 下载次数: 2)
22:10 上传
硬件原理图,及我对每个按键的功能规划如图所示:
4x4按键分配.png (53.65 KB, 下载次数: 3)
22:10 上传
从AM4379参考手册中,GPIO用作矩阵键盘是,触发中断的引脚需接上拉电阻,如图所示:
QQ图片19.png (43.03 KB, 下载次数: 3)
22:11 上传
矩阵键盘与TL-4379开发板的连接如图所示:
QQ图片18.png (61.14 KB, 下载次数: 2)
22:11 上传
这里特别强调一下,AM437X与AM335X芯片在引脚定义上有较大不同,在AM335X中,每个GPIO都与一个特殊功能一一对应,而在AM437X中,一个特殊功能引脚可以对应对个GPIO,如下图所示:
QQ图片41.png (58.99 KB, 下载次数: 3)
22:12 上传
对于主功能为spi2_sclk,其对应gpio3_24和gpio0_22,至于spi2_sclk对应哪个GPIO,则需要我们设置0x7或0x9模式,而对于spi4_d1其只对应一个GPIO,即gpio5_6。对应一个主功能引脚只对应一个GPIO的情况,我们可以通过Linux系统下的gpio_request等申请资源,设置输入或输出,而对于一个主功能对应两个GPIO的情况,我们必须通过重映射该引脚的寄存器设置。简便起见,我这里主要选择了一个主功能只对应一个GPIO引脚的I/O口。硬件连接效果如图所示:
120.jpg (654.08 KB, 下载次数: 3)
22:12 上传
2. 4X4矩阵键盘原理4X4矩阵键盘的原理如下:以上述原理图为例,我们设置L1-L4对应的I/O为输入,并且配置为带中断的I/O口,R1-R4对应的I/O口为输出。在键值开始扫描之前,设置R1-R4输出为低电平,当用户按下某个键后,对对应的行中断线被拉低,触发下降沿中断,在中断处理函数中,依次设置R1为0,看看这一列中的哪一行为0输入,如果没有0输入,机械R2输出0,看看R2这一列哪一行输入为0,依次类推,直到确定触发中断的那个按钮所在的行和列,这样我们就可计算该键的键值KEB-VAL=4*ROW + COL。3. 驱动程序开发3.1 头文件除了包含一般的头文件外,还要包含input.h头文件,该文件中包含了每个键盘按键对应的键码值。#include&linux/module.h&#include&linux/kernel.h&#include&linux/fs.h&#include&linux/init.h&#include&linux/delay.h&#include&linux/cdev.h&#include&linux/miscdevice.h&#include&linux/sched.h&#include&linux/pm.h&#include&linux/sysctl.h&#include&linux/proc_fs.h&#include&linux/irq.h&#include&linux/device.h&#include&linux/interrupt.h&#include&linux/semaphore.h&#include&linux/signal.h&#include&linux/platform_device.h&#include&linux/input.h&#include&linux/gpio.h&#include&asm/uaccess.h&#include&linux/irq.h&#include&asm/irq.h&#include&linux/poll.h&#include&linux/timer.h&
3.2 按键编号及中断编号定义#defineGPIO_L1_PIN_NUM (3*32 + 14) /* gpio 3_14 */#defineGPIO_L2_PIN_NUM (3*32 + 16) /* gpio 3_16 */#defineGPIO_L3_PIN_NUM (4*32 + 3) /* gpio 4_3 */#defineGPIO_L4_PIN_NUM (4*32 + 2) /* gpio 4_2 */ #defineGPIO_R1_PIN_NUM (3*32 + 17) /* gpio 3_17 */#defineGPIO_R2_PIN_NUM (5*32 + 6) /* gpio 5_6 */#defineGPIO_R3_PIN_NUM (5*32 + 4) /* gpio 5_4 */#defineGPIO_R4_PIN_NUM (0*32 + 5) /* gpio 0_5 */
#defineL1_IRQ&&gpio_to_irq(GPIO_L1_PIN_NUM)& &/*KEY1对应的中断号*/#defineL2_IRQ&&gpio_to_irq(GPIO_L2_PIN_NUM)& &/*KEY2对应的中断号*/#defineL3_IRQ&&gpio_to_irq(GPIO_L3_PIN_NUM)& &/*KEY3对应的中断号*/#defineL4_IRQ&&gpio_to_irq(GPIO_L4_PIN_NUM)& &/*KEY4对应的中断号*/ 3.3 关键结构体及初始化staticstruct input_dev *buttons_&&/*输入设备结构体指针,作为全局变量为其他函数使用*/staticstruct timer_list buttons_ /*定义消抖定时器*/structbutton_irq_desc *button_irq_g; /*保存触发中断的那个结构体*/ unsignedint key_value = KEY_0;& && && & //全局按键码 structbutton_irq_desc {& && && && & char *}; /********************************************************* *行I/O端口定义 ********************************************************/staticunsigned long row_table [] = {& & GPIO_R1_PIN_NUM,& & GPIO_R2_PIN_NUM,& & GPIO_R3_PIN_NUM ,& & GPIO_R4_PIN_NUM,}; /********************************************************* *列I/O端口定义 ********************************************************/staticstruct button_irq_desc button_irqs [] = {& & {-1, GPIO_L1_PIN_NUM, 0, &KEY1&},& & {-1, GPIO_L2_PIN_NUM, 1, &KEY2&},& & {-1,GPIO_L3_PIN_NUM, 2, &KEY3&},& & {-1, GPIO_L4_PIN_NUM, 3, &KEY4&},&&}; staticvolatile int ev_key = 0;structtimer_ 3.4 使能、禁止中断在按键的扫描过程中,需要反复的拉低中断输入引脚,而这时我们只想读取引脚的状态,而无需让下降沿触发中断,所以在扫描码值时,我们关闭中断,扫描结束后,再次使能中断,为下一次按键读取做准备。static voiddisable_irqs(void){& & disable_irq(L1_IRQ);& & disable_irq(L2_IRQ);& & disable_irq(L3_IRQ);& & disable_irq(L4_IRQ);}staticvoid enable_irqs(void){& & enable_irq(L1_IRQ);& & enable_irq(L2_IRQ);& & enable_irq(L3_IRQ);& & enable_irq(L4_IRQ);} 3.5 按键扫描程序根据第二节介绍的原理,形成按键扫描算法: 依次拉低某列的输入值staticvoid buttons_kscan_reset(int row){& & & & for(i=0; i & 4; i++) & && &{& && &&&if(i == row)& && && && &gpio_set_value(row_table,0);& &&&//行电平设置,第row列置低,其他置高& && &&&else& && && && &gpio_set_value(row_table, 1);& & }} 扫描实体:static intbuttons_scan(void){& & int i,j,k=0;& & int column = 0;& && &//列& & int row = 0;& && && &//行& && && &//printk(&11/n&);& & disable_irqs();& & for (i = 0; i & 4; i++)& & //列线置低& && &{& && && && & & && && && & gpio_set_value(row_table, 0);& & }& && && & for (j = 0; j & 4; j++) & & {& && &&&if(gpio_get_value(button_irqs[j].pin)== 0 )& && & //若某一列变低电平则保存该列值& && &&&{& && && && &column =& && && && && && &&&}& & }& & & & if(j&4)& & {& && &&&for ( j = 0; j & 4; j++) & && &&&{ & && && && &buttons_kscan_reset(j);& && &//01 1110& && && && &ndelay(100); & && && &&&if(gpio_get_value(button_irqs[column].pin) == 0)& &&&//扫描行& && && && &{& && && && && & row =& && && && && && && && && &}& && &&&}& && && && & & && && && & k = column * 4 +& && && && & & && &&&ev_key =& && && && &&&//第k个按键被按下& & }& & for (i = 0; i & 4; i++)& &//列线置低& & {& && && && &&&& && && && & gpio_set_value(row_table, 0);& & }& && && && &//发送按键码& && &/* 松开 : 最后一个参数: 0-松开, 1-按下 */& && &switch(ev_key)& && &{& && && && & case 0:& && && && && && &&&key_value = KEY_1;& && && && && && &&&& && && && & case 1:& && && && && && &&&key_value = KEY_2;& && && && && && &&&& && && && & case 2:& && && && && && &&&key_value = KEY_3;& && && && && && &&&& && && && & case 3:& && && && && && &&&key_value = KEY_BACKSPACE;& && && && && && &&&& && && && & case 4:& && && && && && &&&key_value = KEY_4;& && && && && && &&&& && && && & case 5:& && && && && && &&&key_value = KEY_5;& && && && && && &&&& && && && & case 6:& && && && && && &&&key_value = KEY_6;& && && && && && &&&& && && && & case 7:& && && && && && &&&key_value = KEY_TAB;& && && && && && &&&& && && && & case 8:& && && && && && &&&key_value = KEY_7;& && && && && && &&&& && && && & case 9:& && && && && && &&&key_value = KEY_8;& && && && && && &&&& && && && & case 10:& && && && && && &&&key_value = KEY_9;& && && && && && &&&& && && && & case 11:& && && && && && &&&key_value = KEY_LEFTSHIFT;& && && && && && &&&& && && && & case 12:& && && && && && &&&key_value = KEY_0;& && && && && && &&&& && && && & case 13:& && && && && && &&&key_value = KEY_DOT;& && && && && && &&&& && && && & case 14:& && && && && && &&&key_value = KEY_SPACE;& && && && && && &&&& && && && & case 15:& && && && && && &&&key_value = KEY_ENTER;& && && && && && &&&& && &}& && &input_event(buttons_dev, EV_KEY,key_value, 1);& && &input_sync(buttons_dev);&&& & del_timer(&mytimer);& && && & & & enable_irqs();& & return 0;}
voidset_timer(void){& & init_timer(&mytimer);& & mytimer.expires = jiffies + 10;& & mytimer.function = buttons_& & add_timer(&mytimer); } 3.6 中断处理程序及定时器消抖由于机械式按键的固有特性,我们必须通过硬件或软件的方式对按键抖动进行过滤处理,我们这里采用定时器避开按键10-20ms的抖动窗口前期,按键的扫描触发实际上是在消抖定时器的回调函数中执行的。/********************************************************* *中断程序,在其中调用定时器, *进行定时及扫描。 ********************************************************/staticirqreturn_t buttons_interrupt(int irq, void *dev_id){& && &button_irq_g = (struct button_irq_desc*)dev_& && &mod_timer(&buttons_timer,jiffies+HZ/8);&&//设置去抖时间& && && && &return IRQ_RETVAL(IRQ_HANDLED);& && && & } staticvoid buttons_timer_function(unsigned long data){& && && & disable_irqs();& & down =!gpio_get_value(button_irq_g-&pin); & & if(down)& && && && & //按下& & {& && &&&set_timer(); & & }& && &else& && && && && &//松开& && &{& && && && & /* 松开 : 最后一个参数: 0-松开, 1-按下 */& && && && & unsigned int key_value = KEY_0;& && && && & switch(ev_key)& && && && & {& && && && && && &&&case 0:& && && && && && && && && &key_value = KEY_1;& && && && && && && && && && && && && && && &&&case 1:& && && && && && && && && &key_value = KEY_2;& && && && && && && && && && && && && && && &&&case 2:& && && && && && && && && &key_value = KEY_3;& && && && && && && && && && && && && && && &&&case 3:& && && && && && && && && &key_value =KEY_BACKSPACE;& && && && && && && && && && && && && && && &&&case 4:& && && && && && && && && &key_value = KEY_4;& && && && && && && && && && && && && && && &&&case 5:& && && && && && && && && &key_value = KEY_5;& && && && && && && && && && && && && && && &&&case 6:& && && && && && && && && &key_value = KEY_6;& && && && && && && && && && && && && && && &&&case 7:& && && && && && && && && &key_value = KEY_TAB;& && && && && && && && && && && && && && && &&&case 8:& && && && && && && && && &key_value = KEY_7;& && && && && && && && && && && && && && && &&&case 9:& && && && && && && && && &key_value = KEY_8;& && && && && && && && && && && && && && && &&&case 10:& && && && && && && && && &key_value = KEY_9;& && && && && && && && && && && && && && && &&&case 11:& && && && && && && && && &key_value =KEY_LEFTSHIFT;& && && && && && && && && && && && && && && &&&case 12:& && && && && && && && && &key_value = KEY_0;& && && && && && && && && && && && && && && &&&case 13:& && && && && && && && && &key_value = KEY_DOT;& && && && && && && && && && && && && && && &&&case 14:& && && && && && && && && &key_value =KEY_SPACE;& && && && && && && && && && && && && && && &&&case 15:& && && && && && && && && &key_value =KEY_ENTER;& && && && && && && && && && && && && & }& && && && & input_event(buttons_dev, EV_KEY,key_value, 0);& && && && & input_sync(buttons_dev);& && &}& & & & enable_irqs();} 3.7 初始化驱动模块在驱动的初始化模块中,我们首先申请GPIO资源,设置行中断输入,列GPIO输出,然后动态分配Input设备描述结构体,设置该输入设备可向系统提交的按键值,最后注册该输入结构体。static int__init dev_init(void){& && && && && &int err = 0;& && && && &/*设置中断号*/& && &button_irqs [0].irq = L1_IRQ;& && &button_irqs [1].irq = L2_IRQ;& && &button_irqs [2].irq = L3_IRQ;& && &button_irqs [3].irq = L4_IRQ;& && && && &/*申请中断引脚对应的GPIO*/& && &ret = gpio_request_one(button_irqs[0].pin,GPIOF_IN, &L1 IRQ&); /* 申请 IO ,为输入*/& && &if (ret & 0) {& && && && & printk(KERN_ERR &Failed torequest GPIO for L1\n&);& && &}& && && && &ret = gpio_request_one(button_irqs[1].pin,GPIOF_IN, &L2 IRQ&); /* 申请 IO ,为输入*/& && &if (ret & 0) {& && && && & printk(KERN_ERR &Failed to requestGPIO for L2\n&);& && &} & && &ret = gpio_request_one(button_irqs[2].pin,GPIOF_IN, &L3 IRQ&); /* 申请 IO ,为输入*/& && &if (ret & 0) {& && && && & printk(KERN_ERR &Failed torequest GPIO for L3\n&);& && &} & && &ret = gpio_request_one(button_irqs[3].pin,GPIOF_IN, &L4 IRQ&); /* 申请 IO ,为输入*/& && &if (ret & 0) {& && && && & printk(KERN_ERR &Failed torequest GPIO for L4\n&);& && &}& && && && &/*申请列引脚对应的GPIO*/& && &ret = gpio_request(row_table[0], &R1IRQ&); /* 申请 IO ,为输入*/& && &if (ret & 0) {& && && && & printk(KERN_ERR &Failed torequest GPIO for R1\n&);& && &}& && && && &ret = gpio_request(row_table[1], &R2IRQ&); /* 申请 IO ,为输入*/& && &if (ret & 0) {& && && && & printk(KERN_ERR &Failed torequest GPIO for R2\n&);& && &} & && &ret = gpio_request(row_table[2], &R3IRQ&); /* 申请 IO ,为输入*/& && &if (ret & 0) {& && && && & printk(KERN_ERR &Failed torequest GPIO for R3\n&);& && &} & && &ret = gpio_request(row_table[3], &R4IRQ&); /* 申请 IO ,为输入*/& && &if (ret & 0) {& && && && & printk(KERN_ERR &Failed torequest GPIO for R4\n&);& && &}& && && && &/* 设置中断引脚为输入 */& && &for(i=0;i&4;i++)& && && && & gpio_direction_input(button_irqs.pin);& && && && &/* 设置列引脚为输出 */& && &for(i=0;i&4;i++)& && &{& && && && & gpio_direction_output(row_table,0);& && &}& && && && &/* 为GPIO3_14,GPIO3_16,GPIO4_2,GPIO4_3申请中断 */& && &if(request_irq(button_irqs [0].irq,buttons_interrupt, IRQ_TYPE_EDGE_BOTH, &K1&, &button_irqs[0]))& && &{& && && && & printk(KERN_ERR &Failed torequest IRQ for KEY1\n&);& && &}& && && && &if(request_irq(button_irqs [1].irq,buttons_interrupt, IRQ_TYPE_EDGE_BOTH, &K2&, &button_irqs[1]))& && &{& && && && & printk(KERN_ERR &Failed torequest IRQ for KEY2\n&);& && &} & && &if(request_irq(button_irqs [2].irq,buttons_interrupt, IRQ_TYPE_EDGE_BOTH, &K3&, &button_irqs[2]))& && &{& && && && & printk(KERN_ERR &Failed torequest IRQ for KEY3\n&);& && &} & && &if(request_irq(button_irqs [3].irq,buttons_interrupt, IRQ_TYPE_EDGE_BOTH, &K4&, &button_irqs[3]))& && &{& && && && & printk(KERN_ERR &Failed torequest IRQ for KEY4\n&);& && &}& && && && &/* 1. 分配一个input_dev结构体 */& && &buttons_dev = input_allocate_device();; & && &/* 2. 设置 */& && &/* 2.1 能产生哪类事件 */& && &set_bit(EV_KEY, buttons_dev-&evbit);& && &set_bit(EV_REP, buttons_dev-&evbit);& && && && &/* 2.2 能产生这类操作里的哪些事件: 0,1,TAB,ENTER */& && &set_bit(KEY_0, buttons_dev-&keybit);& && &set_bit(KEY_1, buttons_dev-&keybit);& && &set_bit(KEY_2, buttons_dev-&keybit);& && &set_bit(KEY_3, buttons_dev-&keybit);& && &set_bit(KEY_4, buttons_dev-&keybit);& && &set_bit(KEY_5, buttons_dev-&keybit);& && &set_bit(KEY_6, buttons_dev-&keybit);& && &set_bit(KEY_7, buttons_dev-&keybit);& && &set_bit(KEY_8, buttons_dev-&keybit);& && &set_bit(KEY_9, buttons_dev-&keybit);& && &set_bit(KEY_BACKSPACE,buttons_dev-&keybit);& && &set_bit(KEY_TAB, buttons_dev-&keybit);& && &set_bit(KEY_LEFTSHIFT,buttons_dev-&keybit);& && &set_bit(KEY_ENTER,buttons_dev-&keybit);& && &set_bit(KEY_SPACE,buttons_dev-&keybit);& && &set_bit(KEY_DOT, buttons_dev-&keybit); & && &/* 3. 注册 */& && &input_register_device(buttons_dev);& && && && &/*消抖定时器*/& && &init_timer(&buttons_timer);& && &buttons_timer.function =buttons_timer_& && &add_timer(&buttons_timer);& && && &} 3.8 驱动模块退出函数释放GPIO资源,释放申请的中断,及注销Input设备。staticvoid __exit dev_exit(void){& && && && &/*卸载模块时,释放中断*/& && &for (i = 0; i &sizeof(button_irqs)/sizeof(button_irqs[0]); i++) & && &{& && &&&if (button_irqs.irq & 0) & && && && & {& && && && && && &&&}& && &&&free_irq(button_irqs.irq, (void*)&button_irqs);& & }& && && && &/*卸载模块时,释放GPIO资源*/& && &for (i = 0; i & 4; i++)& && &{& && && && & gpio_free(button_irqs.pin);& && &}& && && && &for (i = 0; i & 4; i++)& && &{& && && && & gpio_free(row_table);& && &}& && && && &del_timer(&buttons_timer);& && &input_unregister_device(buttons_dev);& && &input_free_device(buttons_dev);& &} 3.9 其他代码module_init(dev_init);module_exit(dev_exit);MODULE_LICENSE(&GPL&);MODULE_AUTHOR(&LZP&);3.10 编译驱动模块执行命令:makeARCH=arm CROSS_COMPILE=arm-linux-gnueabihf-编译结果如图所示:
QQ图片32.png (37.45 KB, 下载次数: 3)
22:13 上传
将驱动模块key_board_have_input.ko拷贝到NFS共享目录。 4. QT GUI测试QT GUI程序我们还采用上一篇试用报告中的加法运算界面。启动TL-4379开发板,执行如下命令:mount -tnfs 192.168.1.103:/nfsshare /mnt/ -o nolockcd /mntinsmodkey_board_have_input.ko加载驱动后,执行结果如图所示:
QQ图片05.png (16.11 KB, 下载次数: 4)
22:14 上传
执行命令,启动QT GUI测试程序:./qt_keyboard_test&&-plugin tslib:/dev/input/touchscreen0&&执行结果如图所示:
532.jpg (305.28 KB, 下载次数: 3)
22:14 上传
在第一个输入框,通过4X4矩阵键盘,输入58,如图所示:
553.jpg (488.07 KB, 下载次数: 3)
22:15 上传
按TAB键,光标跳转到第二个输入框,输入97,如图所示:
645.jpg (1020.59 KB, 下载次数: 8)
22:15 上传
按TAB键,是光标跳转到“=”按钮,按钮边沿出现一个黑色的矩形框,如图所示:
703.jpg (1.05 MB, 下载次数: 5)
22:16 上传
按下ENTER键,即第16个键,计算加法结果如图所示:
737.jpg (706.4 KB, 下载次数: 2)
22:16 上传
按下TAB键,光标跳转到第一个输入框,如图所示:
754.jpg (910.53 KB, 下载次数: 4)
22:17 上传
58被选中,我们按下右上角的BACKSPACE键,即退格键,将58这个数字删除,如图所示:
815.jpg (925.37 KB, 下载次数: 9)
22:18 上传
我们再次在第一输入框内输入小数点,和空格键,效果如图所示:
843.jpg (769.61 KB, 下载次数: 5)
22:18 上传
5. 小结我们在上一篇试用报告的基础上,结合矩阵键盘的扫描原理,编写了4X4矩阵键盘的驱动程序,通过在QT GUI上做功能测试,基本达到了预期效果,实现了0-9,小数点、退格键、空格键、ENTER键和SHIFT键功能,对于我在上一篇试用报告中提到的那个煤矿瓦斯浓度检测仪表,我们采用TL-矩阵键盘,完全可以实现客户提出的功能要求。通过开发板的试用,挖掘开发板的各项功能的过程中,我也在不断的学习,这些看似基本的功能实现,对我实际工作中的方案制定有很多帮助,使我的方案设计中不再仅仅限于单片机,或Cortex-M3、Cortex-M4的这些中低端应用了,今天就写这么多,下篇报告再见!
10:30:13  
助理工程师
12:26:39  
谢谢关注,多多交流
等待验证会员
15:20:54  
本帖最后由 雪烧云朵 于
15:22 编辑
楼主 想请教个问题 请问你的上层qt应用程序是如何使用这个外接矩阵键盘的&&是通过其他自带的键盘事件直接响应的吗?
方便的话 可以留下qq聊聊 谢谢&&我的qq:
助理工程师
13:04:19  
楼主 想请教个问题 请问你的上层qt应用程序是如何使用这个外接矩阵键盘的&&是通过其他自带的键盘事件直接响应的吗?
方便的话 可以留下qq聊聊 谢谢&&我的qq:
下载我提供的驱动和QT程序源码,里面注释的比较详细
17:01:53  
下载我提供的驱动和QT程序源码,里面注释的比较详细
驱动和QT程序源码在哪里呢?
17:01:54  
下载我提供的驱动和QT程序源码,里面注释的比较详细
驱动和QT程序源码在哪里呢?
林超文手把手教你学!
教你1000种电路设计思路
张飞硬件电路之PFC全集
参与免费送VIP+原创视频
运放、ADC、电磁兼容
Powered by
供应链服务
版权所有 (C) 深圳华强聚丰电子科技有限公司

我要回帖

更多关于 键盘自定义按键设置 的文章

 

随机推荐