完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
【创龙AM4379 Cortex-A9试用体验】之采用GPIO扩展口自定义键盘Input驱动+QT界面键盘输入测试 尽管现在的大部分移动终端基本上都采用了触摸屏的人机交互方式,但是在有些场合并不是适合采用触摸式的用户输入,比如粉尘密度较大的车间、煤矿井下作业环境等。去年遇到过一个煤矿瓦斯浓度分析仪的小项目,要求LCD屏显示采集的数据,拟合称曲线,可以人工输入一些设置参数,明确要求不能用触摸屏,必须采用机械按键的方式输入数据。我们目前的项目多数与铸造车间有关,在铸造熔炼侧,空气中粉尘密度大,并且多为铁粉,如果数据采集仪放在熔炼侧,基本上半天时间LCD屏上就会落满灰尘,如果频繁触摸LCD表面,势必会过早划伤LCD屏,并且操作灵敏度也会有一定的影响。这篇使用报告我们就来介绍一下如何开发满足车间小量数字输入的需求,功能简单的,又满足Linux Input框架模型的键盘驱动程序。 1. 硬件设置 和上一篇试用报告一下,我们依然采用TL-4379开发板GPIO扩展接口提供的GPIO3_14,GPIO3_16,GPIO4_3和GPIO4_2来模拟键盘的1,2,TAB和ENTER键。如图所示: 按键与键盘扫描码的对应关系为: GPIO3_14 —— 1 GPIO3_16 —— 2 GPIO4_3 —— TAB GPIO4_2 —— ENTER 硬件连接原理图: 硬件连接实物图: 2. 驱动程序 驱动程序采用Linux标准的Input架构,申请Input device结构体,设置、注册该Input设备处理的输入事件类型、按键扫描码等。我们定义中断处理程序,对机械按键进行消抖处理,确定按键有效后想Linux Input核心上报按键事件及其码值。 2.1 头文件 由于Linux3.0之后的一些相关头文件与Linux2.6版本有较大不同,一定要注意头文件,否则在编译驱动时会报错。 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include 2.2 I/O口定义及全局变量 宏定义与硬件相关的I/O口、中断号及按键信息统一管理相关的结构体,如下所示: #define GPIO_KEY1_PIN_NUM (3*32 + 14) /*gpio 3_14 */ #define GPIO_KEY2_PIN_NUM (3*32 + 16) /*gpio 3_16 */ #define GPIO_KEY3_PIN_NUM (4*32 + 3) /*gpio 4_3 */ #define GPIO_KEY4_PIN_NUM (4*32 + 2) /*gpio 4_2 */ #define KEY1_IRQ gpio_to_irq(GPIO_KEY1_PIN_NUM) /*KEY1对应的中断号*/ #define KEY2_IRQ gpio_to_irq(GPIO_KEY2_PIN_NUM) /*KEY2对应的中断号*/ #define KEY3_IRQ gpio_to_irq(GPIO_KEY3_PIN_NUM) /*KEY3对应的中断号*/ #define KEY4_IRQ gpio_to_irq(GPIO_KEY4_PIN_NUM) /*KEY4对应的中断号*/ struct pin_desc{ intirq; char*name; unsignedint pin; unsignedint key_val; }; struct pin_desc pins_desc[4] = { {-1,"K1", GPIO_KEY1_PIN_NUM, KEY_1}, /*按键1*/ {-1,"K2", GPIO_KEY2_PIN_NUM, KEY_2}, /*按键2*/ {-1,"K3", GPIO_KEY3_PIN_NUM, KEY_TAB}, /*按键TAB*/ {-1,"K4", GPIO_KEY4_PIN_NUM, KEY_ENTER}, /*按键ENTER,即回车键*/ }; static struct input_dev *buttons_dev; /*输入设备结构体指针,作为全局变量为其他函数使用*/ static struct pin_desc *irq_pd; static struct timer_list buttons_timer; /*定义消抖定时器*/ 2.3 按键中断处理函数 当按键被按下时,触发系统中断,我们在中断函数中启动定时器,对按键进行去抖处理,当判断出确实是机械按键被按下了时,去抖定时器上报按键的键码值到Input核心层。 static irqreturn_t buttons_irq(int irq,void *dev_id) { /*10ms后启动定时器 */ irq_pd= (struct pin_desc *)dev_id; mod_timer(&buttons_timer,jiffies+HZ/100); returnIRQ_RETVAL(IRQ_HANDLED); } static void buttons_timer_function(unsignedlong data) { structpin_desc * pindesc = irq_pd; unsignedint pinval; if(!pindesc) return; pinval= gpio_get_value(pindesc->pin); if(pinval) { /*松开 : 最后一个参数: 0-松开, 1-按下 */ input_event(buttons_dev,EV_KEY, pindesc->key_val, 0); input_sync(buttons_dev); } else { /*按下 */ input_event(buttons_dev,EV_KEY, pindesc->key_val, 1); input_sync(buttons_dev); } } 2.4 驱动模块初始化函数 在该函数中,申请GPIO资源,设置GPIO为输入,申请GPIO对应的中断,同时分配Input device结构体,设置按键码值等。 static int buttons_init(void) { inti; intret; /*设置按键中断*/ pins_desc[0].irq= KEY1_IRQ; pins_desc[1].irq= KEY2_IRQ; pins_desc[2].irq= KEY3_IRQ; pins_desc[3].irq= KEY4_IRQ; ret= gpio_request_one(pins_desc[0].pin, GPIOF_IN, "KEY1 IRQ"); /* 申请 IO ,为输入*/ if(ret < 0) { printk(KERN_ERR"Failed to request GPIO for KEY1n"); } ret= gpio_request_one(pins_desc[1].pin, GPIOF_IN, "KEY2 IRQ"); /* 申请 IO ,为输入*/ if(ret < 0) { printk(KERN_ERR"Failed to request GPIO for KEY2n"); } ret= gpio_request_one(pins_desc[2].pin, GPIOF_IN, "KEY3 IRQ"); /* 申请 IO ,为输入*/ if(ret < 0) { printk(KERN_ERR"Failed to request GPIO for KEY3n"); } ret= gpio_request_one(pins_desc[3].pin, GPIOF_IN, "KEY4 IRQ"); /* 申请 IO ,为输入*/ if(ret < 0) { printk(KERN_ERR"Failed to request GPIO for KEY4n"); } /*设置 GPIO 为输入 */ for(i=0;i<4;i++) gpio_direction_input(pins_desc.pin); /*为GPIO3_14,GPIO3_16,GPIO4_2,GPIO4_3申请中断 */ if(request_irq(KEY1_IRQ,buttons_irq, IRQ_TYPE_EDGE_BOTH, "K1", &pins_desc[0])) { printk(KERN_ERR"Failed to request IRQ for KEY1n"); } if(request_irq(KEY2_IRQ,buttons_irq, IRQ_TYPE_EDGE_BOTH, "K2", &pins_desc[1])) { printk(KERN_ERR"Failed to request IRQ for KEY2n"); } if(request_irq(KEY3_IRQ,buttons_irq, IRQ_TYPE_EDGE_BOTH, "K3", &pins_desc[2])) { printk(KERN_ERR"Failed to request IRQ for KEY3n"); } if(request_irq(KEY4_IRQ,buttons_irq, IRQ_TYPE_EDGE_BOTH, "K4", &pins_desc[3])) { printk(KERN_ERR"Failed to request IRQ for KEY4n"); } /*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_1,buttons_dev->keybit); set_bit(KEY_2,buttons_dev->keybit); set_bit(KEY_ENTER,buttons_dev->keybit); set_bit(KEY_TAB,buttons_dev->keybit); /*3. 注册 */ input_register_device(buttons_dev); /*4. 硬件相关的操作 */ init_timer(&buttons_timer); buttons_timer.function= buttons_timer_function; add_timer(&buttons_timer); return0; } 2.5 驱动模块退出函数 释放初始化时申请的系统资源。 static void buttons_exit(void) { inti; for(i = 0; i < 4; i++) { free_irq(pins_desc.irq,&pins_desc); } for(i = 0; i < 4; i++) { gpio_free(pins_desc.pin); } del_timer(&buttons_timer); input_unregister_device(buttons_dev); input_free_device(buttons_dev); } 2.6 驱动模块注册、注销及授权申明 module_init(buttons_init); module_exit(buttons_exit); MODULE_LICENSE("GPL"); 2.7编译驱动模块 执行命令: make ARCH=armCROSS_COMPILE=arm-linux-gnueabihf- 编译结果如图所示: 将key_board.ko拷贝到NFS共享目录: cp ./key_board.ko /nfsshare 3. 创建QT测试程序 创建QT测试程序qt_keyboard_test,设计界面如图所示: 设置“=”按钮的命令处理函数,如图所示: 我们模拟键盘的ENTER功能,所以我们必须将“=”按钮设置为默认按钮,在Widget的构造函数中设置如下: 编译工程,结果如下图所示: 将qt_keyboard_test拷贝到NFS共项目目录。 4. TL-4379开发板上电测试 4.1 给TL-4379开发板上电 TL-4379上电后,执行命令: mount -t nfs 192.168.1.103:/nfsshare /mnt-o nolock cd /mnt /etc/init.d/matrix-gui-2.0 stop 4.2 加载key_board.ko 执行命令加载key_board.ko驱动模块: insmod key_board.ko 如果所示: 查看当前嵌入式Linux系统下的Input设备: ls /dev/input 如图所示: 执行命令,测试一下4个按键的事件是否传递到了应用层: 依次按下KEY1,KEY2,KEY3和KEY4,说明4个按钮的事件消息已经上传到了应用层。 4.3 加载QT测试程序 执行如下命令启动QT测试程序: ./qt_keyboard_test -plugintslib:/dev/input/touchscreen0 启动界面如图所示: |
|
相关推荐
|
|
你正在撰写讨论
如果你是对讨论或其他讨论精选点评或询问,请使用“评论”功能。
飞凌嵌入式ElfBoard ELF 1板卡-CAN编程示例之开发板测试
654 浏览 0 评论
该问题是用APP给芯海科技的CST92F25芯片发指令是出现的
2242 浏览 1 评论
771 浏览 0 评论
1530 浏览 1 评论
2276 浏览 1 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-22 13:16 , Processed in 0.481561 second(s), Total 37, Slave 29 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号