1 / 23

嵌入式键盘驱动

嵌入式键盘驱动. 广州嵌入式软件公共技术支持中心 梁老师 2007 年 04 月. 矩阵式键盘原理. 矩阵式键盘一般适用于按键数量较多的场合,它由行线和列线组成,按键位于行、列的交叉点上。 如图所示,一个 4×4 的行、列结构可以构成一个有 16 个按键的键盘。. 矩阵式键盘原理. 按键设置在行、列交叉点上,行、列分别连接到按键开关的两端。行线通过上拉电阻接到十 5 V 上。

munin
Download Presentation

嵌入式键盘驱动

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 嵌入式键盘驱动 广州嵌入式软件公共技术支持中心 梁老师 2007年04月

  2. 矩阵式键盘原理 • 矩阵式键盘一般适用于按键数量较多的场合,它由行线和列线组成,按键位于行、列的交叉点上。 • 如图所示,一个4×4的行、列结构可以构成一个有16个按键的键盘。

  3. 矩阵式键盘原理 • 按键设置在行、列交叉点上,行、列分别连接到按键开关的两端。行线通过上拉电阻接到十5 V上。 • 平时无按键动作时,行线处于高电平状态;而当有健按下时,行线电平状态将由通过此按键的列线电平决定:列线电平如果为低,行线电平为低;列线电平如果为高,则行线电平亦为高。这一点是识别矩阵式键盘是否被按下的关键所在。

  4. 矩阵式键盘原理 • 矩阵键盘按键的识别方法分两步进行: • ①识别键盘哪一行的键被按下。让所有列线均为低电平,检查各行线电平是否为低。如果有行线为低,则说明该行有键被按下,否则说明无键被按下。 • ②如果某行有键被按下,识别键盘哪一列的键被按下(亦称之为扫描法)。逐列置低电平,并置其余各列为高电平.检查各行线电平的变化。如果行电平变为低电平,则可确定此行此列交叉点处按键被按下。

  5. S3C2410 的I/O 介绍 • S3C2410 有117 个复用功能输入输出端口引脚,这些引脚是: • PortA(GPA):32 个输入/输出端口 • PortB(GPB):11 个输入/输出端口 • PortC(GPC):16 个输入/输出端口 • PortD(GPD):16 个输入/输出端口 • PortE(GPE):16 个输入/输出端口 • PortF(GPF):8 个输入/输出端口 • PortG(GPG):16 个输入/输出端口 • PortH(GPH):11 个输入/输出端口

  6. S3C2410 的I/O 介绍 • 端口控制说明 • 端口配置寄存器(GPACON――GPHCON) 大部分的引脚是复用的,所以必须对于每个引脚要求定义一个功能,端口配置寄存器定义了每个引脚的功能。 • 端口数据寄存器(GPADAT――GPHDAT) 如果端口配置成输出端口,数据能够被写到端口数据寄存器的对应位,然后通过管脚输出。如果端口配置成输入端口,能从端口数据寄存器对应的位中读出管脚上的电平 • 端口上拉寄存器(GPBUP――GPHUP) 端口上拉寄存器控制着每个端口组的上拉寄存器的使能或禁止,当对应位为0,这个引脚的上拉寄存器是允许的,当为1 时,上拉寄存器是禁止的。

  7. MIZI提供的S3C2410.H • 使用一个32位的数来表示端口的使用情况。 • 模式 |上拉 |端口 | 端口引脚 • MODE | PULLUP | PORT | OFS • 不需要自己手动组合,通过宏定义以及SHIFT和MASK组合。见程序

  8. MIZI提供的S3C2410.H • 端口的表示 • #define PORTA_OFS 0 • #define PORTB_OFS 1 • #define PORTC_OFS 2 • #define PORTD_OFS 3 • #define PORTE_OFS 4 • #define PORTF_OFS 5 • #define PORTG_OFS 6 • #define PORTH_OFS 7

  9. MIZI提供的S3C2410.H • 端口引脚的表示 • #define GPIO_A0 MAKE_GPIO_NUM(PORTA_OFS, 0) • #define GPIO_A1 MAKE_GPIO_NUM(PORTA_OFS, 1) • #define GPIO_A2 MAKE_GPIO_NUM(PORTA_OFS, 2) • #define GPIO_A3 MAKE_GPIO_NUM(PORTA_OFS, 3) • 。。。 • #define MAKE_GPIO_NUM(p, o) ((p << GPIO_PORT_SHIFTT) | (o << GPIO_OFS_SHIFT))

  10. MIZI提供的S3C2410.H • set_gpio_ctrl(x)     • 功能:配置端口引脚的功能,设置IO口控制寄存器和上拉寄存器 • 用法:set_gpio_ctrl(模式|上拉?|IO脚) • 模式|是否上拉|IO脚,在S3C2410.h中都有其定义好的名字。 • set_gpio_ctrl(GPIO_E11 | GPIO_PULLUP_DIS |GPIO_MODE_OUT);

  11. MIZI提供的S3C2410.H • write_gpio_bit(x, v) • 功能:把端口 对应的端口数据寄存器x位设置为v • write_gpio_bit(GPIO_E11, 0); • read_gpio_bit(x)     • 功能:把端口数据寄存器x位的状态 读入,函数返回值既是其状态 • read_gpio_bit(GPIO_G11);

  12. MIZI提供的S3C2410.H • write_gpio_reg(x, v) • 功能:把端口数据寄存器x 设置为v • read_gpio_reg(x)     • 功能:读取端口数据寄存器x,函数返回值既是其数据

  13. 键盘的硬件实现

  14. 键盘的硬件实现 • 4X4 矩阵键盘 • 四个输入引脚: • EINT0 -----( GPF0 )----INPUT • EINT2 -----( GPF2 )----INPUT • EINT11-----( GPG3 )----INPUT • EINT19-----( GPG11 )----INPUT • 四个输出引脚: • KEYSCAN0---( GPE11 )----OUTPUT • KEYSCAN1---( GPG6 )----OUTPUT • KEYSCAN2---( GPE13 )----OUTPUT • KEYSCAN3---( GPG2 )----OUTPUT

  15. 键盘的驱动实现 • 引入结构体key_info对按键进行描述 • static struct key_info { • int irq_no; //外部中断号 • unsigned int gpio_port; //输入端口,EINT • unsigned int gpio_port_kscan; //输出端口,OUTPUT • int key_no; //按键序号,或者名字 • } key_info_tab[16] = { • …… • }

  16. 键盘初始化程序 • static int __init matrix4_buttons_init(void) • { • 注册字符设备 register_chrdev(……); • 初始化按键对应的输出端口 buttons_io_port_init(); • 采用中断机制,注册中断号 request_irqs(); • }

  17. 键盘初始化程序 • /* 初始化kscan口为输出0 */ • static void buttons_io_port_init(void) • { • int i; • for(i=0; i < sizeof kscan / sizeof kscan[1]; i++) { • set_gpio_ctrl(kscan[i] | GPIO_PULLUP_DIS | GPIO_MODE_OUT); • write_gpio_bit(kscan[i], 0); • } • }

  18. 请求注册中断 • static int request_irqs(void) • { • for (i = 0; i < 使用中断个数; i++) { • 设置与外部中断号相对应的GPIO端口以及模式请求中断号,并注册中断响应函数。 • } • }

  19. 键盘驱动的卸载函数 • static void __exit matrix4_buttons_exit(void) • { • 释放中断 free_irqs(…); • 注销字符设备unregister_chrdev(…); • }

  20. 按键中断处理 buttons_irq • static void buttons_irq(int irq, void *dev_id, struct pt_regs *reg) • { • 设置GPIO为输入状态 • 键盘扫描 • 唤醒按键等待队列的进程 • 重新设置GPIO为输出 • 重新设置中断 • }

  21. 通过延时去键盘抖动 • 理想的情况下,当按键被按下时,I/O口电平被拉低,即逻辑0,当按键松开时,为逻辑1。 • 但实际机械的触点动作与微处理器快速的执行速度不匹配,导致开关被按下或松开时产生抖动,如同弹簧一样,不能立刻产生稳定的0或1。 • 常用的去抖动方法有硬件和软件两种,硬件可采用单稳态触发起、高通滤波器等硬件实现,但该方法一般要对每一路输入添加特殊的硬件,比较复杂。软件去抖动则简单多了,可通过增加延时和判断来解决。

  22. matrix4_buttons_fops • 由于按键不具有I/O功能,它只会在按下的时候产生中断,所以这里不需要实现open,read,write,ioctl等功能。 • 为了测试驱动,可以添加这些函数。

  23. 让我们一起努力!

More Related