资料介绍
11.6 按键驱动程序实例
11.6.1 按键工作原理
LED和蜂鸣器是最简单的GPIO的应用,都不需要任何外部输入或控制。按键同样使用GPIO接口,但按键本身需要外部的输入,即在驱动程序中要处理外部中断。按键硬件驱动原理图如图11-7所示。在图11-7的4×4矩阵按键(K1~K16)电路中,使用4个输入/输出端口(EINT0、EINT2、EINT11和EINT19)和4个输出端口(KSCAN0~KSCAN3)。
图11.7 按键驱动电路原理图
按键驱动电路使用的端口和对应的寄存器如表11-18所示。
表11.18 按键电路的主要端口
管 脚端 口输入/输出管 脚端 口输入/输出
KEYSCAN0GPE11输出EINT0EINIT0/GPF0输入/输出
KEYSCAN1GPG6输出EINT2EINT2/GPF2输入/输出
KEYSCAN2GPE13输出EINT11EINT11/GPG3输入/输出
KEYSCAN3GPG2输出EINT19EINT19/GPG11输入/输出
因为通常中断端口是比较珍贵且有限的资源,所以在本电路设计中,16个按键复用了4个中断线。那怎么样才能及时而准确地对矩阵按键进行扫描呢?
某个中断的产生表示,与它所对应的矩阵行的4个按键中,至少有一个按键被按住了。因此可以通过查看产生了哪个中断,来确定在矩阵的哪一行中发生了按键操作(按住或释放)。例如,如果产生了外部2号线中断(EINT2变为低电平),则表示K7、K8、K9和K15中至少有一个按键被按住了。这时候4个EINT端口应该通过GPIO配置寄存器被设置为外部中断端口,而且4个KSCAN端口的输出必须为低电平。
在确定按键操作所在行的位置之后,我们还得查看按键操作所在列的位置。此时要使用KSCAN端口组,同时将4个EINT端口配置为通用输入端口(而不是中断端口)。在4个KSCAN端口中,轮流将其中某一个端口的输出置为低电平,其他3个端口的输出置为高电平。这样逐列进行扫描,直到按键所在列的KSCAN端口输出为低电平,此时按键操作所在行的EINT管脚的输入端口的值会变成低电平。例如,在确认产生了外部2号中断之后,进行逐列扫描。若发现在KSCAN1为低电平时(其他端口输出均为高电平),GPF2(EINT2管脚的输入端口)变为低电平,则可以断定按键K8被按住了。
以上的讨论都是在按键的理想状态下进行的,但实际的按键动作会在短时间(几毫秒至几十毫秒)内产生信号抖动。例如,当按键被按下时,其动作就像弹簧的若干次往复运动,将产生几个脉冲信号。一次按键操作将会产生若干次按键中断,从而会产生抖动现象。因此驱动程序中必须要解决去除抖动所产生的毛刺信号的问题。
11.6.2 按键驱动程序
首先按键设备相关的数据结构的定义如下所示:
/* butt_drv.h */
……
typedef struct _st_key_info_matrix /* 按键数据结构 */
{
unsigned char key_id; /* 按键ID */
unsigned int irq_no; /* 对应的中断号 */
unsigned int irq_gpio_port; /* 对应的中断线的输入端口地址*/
unsigned int kscan_gpio_port; /* 对应的KSCAN端口地址 */
} st_key_info_matrix;
typedef struct _st_key_buffer /* 按键缓冲数据结构 */
{
unsigned long jiffy[MAX_KEY_COUNT]; /* 按键时间, 5s以前的铵键作废*/
unsigned char buf[MAX_KEY_COUNT]; /* 按键缓冲区 */
unsigned int head,tail; /* 按键缓冲区头和尾 */
} st_key_buffer;
……
下面是矩阵按键数组的定义,数组元素的信息(一个按键信息)按照0行0列,0行1列,…,3行2列,3行3列的顺序逐行排列。
static st_key_info_matrix key_info_matrix[MAX_COLUMN][MAX_ROW] =
{
{{10, IRQ_EINT0, S3C2410_GPF0, S3C2410_GPE11}, /* 0行0列 */
{11, IRQ_EINT0, S3C2410_GPF0, S3C2410_GPG6},
{12, IRQ_EINT0, S3C2410_GPF0, S3C2410_GPE13},
{16, IRQ_EINT0, S3C2410_GPF0, S3C2410_GPG2}},
{{7, IRQ_EINT2, S3C2410_GPF2, S3C2410_GPE11}, /* 1行0列 */
{8, IRQ_EINT2, S3C2410_GPF2, S3C2410_GPG6},
{9, IRQ_EINT2, S3C2410_GPF2, S3C2410_GPE13},
{15, IRQ_EINT2, S3C2410_GPF2, S3C2410_GPG2}},
{{4, IRQ_EINT11, S3C2410_GPG3, S3C2410_GPE11}, /* 2行0列 */
{5, IRQ_EINT11, S3C2410_GPG3, S3C2410_GPG6},
{6, IRQ_EINT11, S3C2410_GPG3, S3C2410_GPE13},
{14, IRQ_EINT11, S3C2410_GPG3, S3C2410_GPG2}},
{{1, IRQ_EINT19, S3C2410_GPG11, S3C2410_GPE11}, /* 3行0列 */
{2, IRQ_EINT19, S3C2410_GPG11, S3C2410_GPG6},
{3, IRQ_EINT19, S3C2410_GPG11, S3C2410_GPE13},
{13, IRQ_EINT19, S3C2410_GPG11, S3C2410_GPG2}},
};
下面是与按键相关的端口的初始化函数。这些函数已经在简单的GPIO字符设备驱动程序里被使用过。此外,set_irq_type()函数用于设定中断线的类型,在本实例中通过该函数将4个中断线的类型配置为下降沿触发式。
11.6.1 按键工作原理
LED和蜂鸣器是最简单的GPIO的应用,都不需要任何外部输入或控制。按键同样使用GPIO接口,但按键本身需要外部的输入,即在驱动程序中要处理外部中断。按键硬件驱动原理图如图11-7所示。在图11-7的4×4矩阵按键(K1~K16)电路中,使用4个输入/输出端口(EINT0、EINT2、EINT11和EINT19)和4个输出端口(KSCAN0~KSCAN3)。
图11.7 按键驱动电路原理图
按键驱动电路使用的端口和对应的寄存器如表11-18所示。
表11.18 按键电路的主要端口
管 脚端 口输入/输出管 脚端 口输入/输出
KEYSCAN0GPE11输出EINT0EINIT0/GPF0输入/输出
KEYSCAN1GPG6输出EINT2EINT2/GPF2输入/输出
KEYSCAN2GPE13输出EINT11EINT11/GPG3输入/输出
KEYSCAN3GPG2输出EINT19EINT19/GPG11输入/输出
因为通常中断端口是比较珍贵且有限的资源,所以在本电路设计中,16个按键复用了4个中断线。那怎么样才能及时而准确地对矩阵按键进行扫描呢?
某个中断的产生表示,与它所对应的矩阵行的4个按键中,至少有一个按键被按住了。因此可以通过查看产生了哪个中断,来确定在矩阵的哪一行中发生了按键操作(按住或释放)。例如,如果产生了外部2号线中断(EINT2变为低电平),则表示K7、K8、K9和K15中至少有一个按键被按住了。这时候4个EINT端口应该通过GPIO配置寄存器被设置为外部中断端口,而且4个KSCAN端口的输出必须为低电平。
在确定按键操作所在行的位置之后,我们还得查看按键操作所在列的位置。此时要使用KSCAN端口组,同时将4个EINT端口配置为通用输入端口(而不是中断端口)。在4个KSCAN端口中,轮流将其中某一个端口的输出置为低电平,其他3个端口的输出置为高电平。这样逐列进行扫描,直到按键所在列的KSCAN端口输出为低电平,此时按键操作所在行的EINT管脚的输入端口的值会变成低电平。例如,在确认产生了外部2号中断之后,进行逐列扫描。若发现在KSCAN1为低电平时(其他端口输出均为高电平),GPF2(EINT2管脚的输入端口)变为低电平,则可以断定按键K8被按住了。
以上的讨论都是在按键的理想状态下进行的,但实际的按键动作会在短时间(几毫秒至几十毫秒)内产生信号抖动。例如,当按键被按下时,其动作就像弹簧的若干次往复运动,将产生几个脉冲信号。一次按键操作将会产生若干次按键中断,从而会产生抖动现象。因此驱动程序中必须要解决去除抖动所产生的毛刺信号的问题。
11.6.2 按键驱动程序
首先按键设备相关的数据结构的定义如下所示:
/* butt_drv.h */
……
typedef struct _st_key_info_matrix /* 按键数据结构 */
{
unsigned char key_id; /* 按键ID */
unsigned int irq_no; /* 对应的中断号 */
unsigned int irq_gpio_port; /* 对应的中断线的输入端口地址*/
unsigned int kscan_gpio_port; /* 对应的KSCAN端口地址 */
} st_key_info_matrix;
typedef struct _st_key_buffer /* 按键缓冲数据结构 */
{
unsigned long jiffy[MAX_KEY_COUNT]; /* 按键时间, 5s以前的铵键作废*/
unsigned char buf[MAX_KEY_COUNT]; /* 按键缓冲区 */
unsigned int head,tail; /* 按键缓冲区头和尾 */
} st_key_buffer;
……
下面是矩阵按键数组的定义,数组元素的信息(一个按键信息)按照0行0列,0行1列,…,3行2列,3行3列的顺序逐行排列。
static st_key_info_matrix key_info_matrix[MAX_COLUMN][MAX_ROW] =
{
{{10, IRQ_EINT0, S3C2410_GPF0, S3C2410_GPE11}, /* 0行0列 */
{11, IRQ_EINT0, S3C2410_GPF0, S3C2410_GPG6},
{12, IRQ_EINT0, S3C2410_GPF0, S3C2410_GPE13},
{16, IRQ_EINT0, S3C2410_GPF0, S3C2410_GPG2}},
{{7, IRQ_EINT2, S3C2410_GPF2, S3C2410_GPE11}, /* 1行0列 */
{8, IRQ_EINT2, S3C2410_GPF2, S3C2410_GPG6},
{9, IRQ_EINT2, S3C2410_GPF2, S3C2410_GPE13},
{15, IRQ_EINT2, S3C2410_GPF2, S3C2410_GPG2}},
{{4, IRQ_EINT11, S3C2410_GPG3, S3C2410_GPE11}, /* 2行0列 */
{5, IRQ_EINT11, S3C2410_GPG3, S3C2410_GPG6},
{6, IRQ_EINT11, S3C2410_GPG3, S3C2410_GPE13},
{14, IRQ_EINT11, S3C2410_GPG3, S3C2410_GPG2}},
{{1, IRQ_EINT19, S3C2410_GPG11, S3C2410_GPE11}, /* 3行0列 */
{2, IRQ_EINT19, S3C2410_GPG11, S3C2410_GPG6},
{3, IRQ_EINT19, S3C2410_GPG11, S3C2410_GPE13},
{13, IRQ_EINT19, S3C2410_GPG11, S3C2410_GPG2}},
};
下面是与按键相关的端口的初始化函数。这些函数已经在简单的GPIO字符设备驱动程序里被使用过。此外,set_irq_type()函数用于设定中断线的类型,在本实例中通过该函数将4个中断线的类型配置为下降沿触发式。
下载该资料的人也在下载
下载该资料的人还在阅读
更多 >
- 细说嵌入式驱动程序设计
- 嵌入式Linux驱动程序开发
- 基于嵌入式Linux的人机交互接口设备驱动程序的研究和实现
- 嵌入式Linux系统的驱动原理和使用ARM Linux实现SPI驱动程序的说明 11次下载
- 嵌入式Linux设备驱动程序开发基础知识总结免费下载 13次下载
- 嵌入式Linux的中断驱动程序设计 3次下载
- 嵌入式Linux下的LCD驱动程序设计方案解析 0次下载
- 嵌入式Linux字符设备驱动的设计与应用
- 嵌入式Linux字符设备驱动的设计与应用
- 基于嵌入式Linux的步进电机驱动程序设计
- 基于嵌入式LINUX下CAN设备驱动程序设计
- 嵌入式Linux网络驱动程序的开发及实现原理
- 嵌入式USB从设备驱动程序设计
- 嵌入式通信设备驱动程序设计标准化
- 嵌入式Linux设备驱动开发
- 如何写一个Linux设备驱动程序 4314次阅读
- 设计嵌入式驱动程序有什么窍门 2508次阅读
- 设计嵌入式驱动程序有哪些小窍门 2553次阅读
- 米尔科技LINUX设备驱动程序教程 1965次阅读
- 嵌入式Linux内核的驱动程序开发是怎样的 1415次阅读
- 基于PXA255开发板外围字符设备的嵌入式Linux字符设备驱动设计与应用 1138次阅读
- 基于嵌入式Linux下的I2C设备驱动的总体思路与框架设计 3671次阅读
- 基于嵌入式Linux内核的系统设备驱动程序开发设计 1113次阅读
- 嵌入式系统开发中驱动程序设计的5个方法盘点 3057次阅读
- 可动态安装的Linux设备驱动程序 957次阅读
- 基于嵌入式Linux的无线视频监控系统设计 3004次阅读
- 嵌入式驱动的构造分析总结 4503次阅读
- 基于FPGA嵌入式系统的设备驱动开发 2259次阅读
- Xilinx设备的驱动程序 7967次阅读
- PCI驱动程序开发实例 6701次阅读
下载排行
本周
- 1感应笔电路图
- 0.06 MB | 7次下载 | 免费
- 2美的电磁炉维修手册大全
- 1.56 MB | 5次下载 | 5 积分
- 3Cortex-M3/M4F指令集技术用户手册
- 2.28MB | 3次下载 | 免费
- 4SMD LED选型手册 贴片灯珠
- 5.47 MB | 3次下载 | 免费
- 5基于PLC的拉丝机张力控制系统研究
- 0.14 MB | 2次下载 | 5 积分
- 6LZC3106G高性能谐振控制器中文手册
- 1.29 MB | 1次下载 | 1 积分
- 7JL2233B集成电平转换功能的LDO中文手册
- 0.50 MB | 1次下载 | 免费
- 8加密芯片的一种破解方法和对应加密方案改进设计
- 0.29 MB | 1次下载 | 免费
本月
- 1使用单片机实现七人表决器的程序和仿真资料免费下载
- 2.96 MB | 44次下载 | 免费
- 2UC3842/3/4/5电源管理芯片中文手册
- 1.75 MB | 19次下载 | 免费
- 3华瑞昇CR216芯片数字万用表规格书附原理图及校正流程方法
- 0.74 MB | 14次下载 | 3 积分
- 4DMT0660数字万用表产品说明书
- 0.70 MB | 13次下载 | 免费
- 53314A函数发生器维修手册
- 16.30 MB | 13次下载 | 免费
- 6TPS54202H降压转换器评估模块用户指南
- 1.02MB | 8次下载 | 免费
- 7STM32F101x8/STM32F101xB手册
- 1.69 MB | 8次下载 | 1 积分
- 8感应笔电路图
- 0.06 MB | 7次下载 | 免费
总榜
- 1matlab软件下载入口
- 未知 | 935119次下载 | 10 积分
- 2开源硬件-PMP21529.1-4 开关降压/升压双向直流/直流转换器 PCB layout 设计
- 1.48MB | 420062次下载 | 10 积分
- 3Altium DXP2002下载入口
- 未知 | 233084次下载 | 10 积分
- 4电路仿真软件multisim 10.0免费下载
- 340992 | 191367次下载 | 10 积分
- 5十天学会AVR单片机与C语言视频教程 下载
- 158M | 183335次下载 | 10 积分
- 6labview8.5下载
- 未知 | 81581次下载 | 10 积分
- 7Keil工具MDK-Arm免费下载
- 0.02 MB | 73807次下载 | 10 积分
- 8LabVIEW 8.6下载
- 未知 | 65987次下载 | 10 积分
评论
查看更多