键盘中断驱动实验

合集下载

嵌入式中断按键实验报告

嵌入式中断按键实验报告

嵌入式中断按键实验报告本实验的目的是学习如何在嵌入式系统中使用中断来处理按键输入。

通过该实验,我们可以掌握如何配置和使用中断,以及如何编写中断服务程序来处理按键输入。

实验材料:1. 嵌入式开发板2. 按键模块3. 电源适配器实验步骤:1. 将按键模块连接到嵌入式开发板的GPIO引脚上,确保连接正确。

2. 打开开发板的开关,给开发板供电。

3. 在开发板上配置GPIO引脚作为中断输入,并使能中断。

4. 编写中断服务程序来处理按键输入。

当按键被按下时,中断服务程序将被调用,并执行相应的操作。

5. 在主程序中初始化中断服务程序,并进入一个无限循环。

在该循环中,可以进行其他的操作,并等待按键中断的发生。

实验结果:在实验中,我们成功地配置并使用了中断来处理按键输入。

当按键被按下时,中断服务程序被调用,并执行了相应的操作。

讨论与分析:通过该实验,我们学习到了中断的基本原理和使用方法。

中断是一种非常重要的机制,可以使嵌入式系统更高效地响应外部事件。

在实际的嵌入式应用中,按键输入是非常常见的操作,使用中断可以很好地处理按键输入,提高系统的响应速度和可靠性。

然而,中断也存在一些问题。

首先,中断处理需要一定的时间,在高速的系统中,中断的处理时间可能会影响到系统的性能。

另外,当系统存在多个中断源时,中断处理的优先级和调度也需要仔细设计,以确保系统的正常运行。

总结:通过本实验,我们成功地学习了嵌入式系统中使用中断处理按键输入的方法。

中断是一种重要的机制,可以使系统更高效地响应外部事件。

通过合理地设计和使用中断,可以提高系统的性能和可靠性。

在实际的嵌入式应用中,我们应该根据具体的需求和系统条件来选择最合适的中断处理方法,并进行适当的优化和调试。

键盘中断微机实验报告

键盘中断微机实验报告

键盘中断微机实验报告1. 引言键盘中断是计算机硬件系统中常见的一种输入设备中断方式,其功能是在用户通过键盘输入时,中断处理器正常运行的流程,将键盘输入的数据传递给操作系统供其处理。

本次实验旨在通过搭建一个简单的键盘中断实验系统,加深对键盘中断原理及操作的理解。

2. 实验原理2.1 键盘中断键盘中断是一种异步的硬件中断方式,即键盘通过给中断控制设备发送中断请求信号,从而将中断信息传递给CPU。

一旦发生键盘中断,CPU将停止当前执行的任务,跳转到事先设置好的中断处理程序,处理键盘中断事件。

2.2 实验系统本次实验使用Intel 8086微处理器、键盘控制器8042和键盘作为实验系统的主要硬件设备。

系统的基本结构如下图所示:![实验系统结构图](- 键盘:作为输入设备,接收用户的键盘输入。

- 键盘控制器8042:负责控制键盘与计算机之间的数据传输。

- CPU:处理器负责执行键盘中断的相关指令。

3. 实验步骤3.1 搭建实验系统首先,需要将键盘控制器8042插入到计算机的适当位置,并将键盘连接到控制器上。

确保硬件的连接正确无误。

3.2 编写中断处理程序在编程方面,我们使用汇编语言编写键盘中断的处理程序。

具体而言,我们需要完成以下任务:- 将中断向量表中对应键盘中断的入口地址设置为我们编写的处理程序的入口地址。

- 编写处理键盘中断的程序代码,实现对键盘输入数据的接收和处理。

3.3 设置中断控制器在实验中,要进行正确的中断处理,还需要设置中断控制器8042。

具体而言,我们需要完成以下任务:- 将中断请求线IRQ1(对应键盘中断)与中断控制器连接。

- 打开中断屏蔽位,以允许中断请求通过。

3.4 运行实验程序完成前述步骤后,我们可以运行实验程序,测试键盘中断的正常工作。

当用户按下键盘时,键盘中断会触发,并将键盘输入的数据传递给中断处理程序进行处理。

4. 实验结果与分析经过测试,我们发现实验系统能够正确地接收和处理键盘输入的数据。

实验 8-2 键盘中断驱动实验

实验 8-2 键盘中断驱动实验

实验8-2 键盘中断驱动实验【实验目的】掌握键盘原理。

熟悉驱动的中断机制。

【实验步骤】第一步:利用vi编辑器,编写一个Keypad.c驱动代码;1、增加驱动所需的头文件和变量#include<linux/module.h>#include<linux/kernel.h>#include<linux/init.h>#include<linux/delay.h>#include<linux/poll.h>#include<linux/spinlock.h>#include<asm/hardware.h>#include<asm/arch-pxa/pxa-regs.h>MODULE_LICENSE("GPL");#define DEVICE_NAME "emdoor_kbd"#define KEYVALUE_HAVE 1#define KEYVALUE_NO 0#define KPC_DIR 1<<5#define KPC_MAT 1<<22static int Emdoor_kbd_fasync(int, struct file* ,int); typedef unsigned char KBD_RET;struct fasync_struct * fasync;//键盘结构体定义typedef struct {KBD_RET kbd_buff; /* protect against overrun */ unsigned int kbd_status;wait_queue_head_t wq;spinlock_t lock;} KBD_DEV;2、实现键盘驱动读操作函数static ssize_t Emdoor_kbd_read(struct file *filp, char *buffer, size_t count, loff_t *ppos){KBD_DEV * kbd=filp->private_data;KBD_RET kbd_ret;while(1){if(kbd->kbd_status==KEYVALUE_HAVE){kbd_ret = kbd->kbd_buff;copy_to_user(buffer, &kbd_ret, sizeof(KBD_RET));kbd->kbd_status=KEYVALUE_NO;return sizeof(KBD_RET);}else{if (filp->f_flags & O_NONBLOCK)return -EAGAIN;interruptible_sleep_on(&(kbd->wq));if (signal_pending(current))return -ERESTARTSYS;}}return sizeof(KBD_RET);}3、实现键盘驱动中断服务例程static void Emdoor_isr_kbd(int irq, void *dev_id, struct pt_regs *reg){printk(KERN_EMERG"Emdoor_isr_kbd,Interrupt\n");int kpc_value;KBD_DEV * kbd = (KBD_DEV *) dev_id;spin_lock_irq(&(kbd->lock));kpc_value=KPC;if(kpc_value&KPC_MAT) {kbd->kbd_buff=KPAS&0xFF;if(kbd->kbd_buff!=0xFF){switch(kbd->kbd_buff){case 0x0: kbd->kbd_buff=5; break;case 0x1: kbd->kbd_buff=6; break;case 0x2: kbd->kbd_buff=7; break;case 0x5: kbd->kbd_buff=8; break;case 0x10: kbd->kbd_buff=9; break;case 0x11: kbd->kbd_buff=10; break;case 0x12: kbd->kbd_buff=11; break;case 0x15: kbd->kbd_buff=12; break;case 0x20: kbd->kbd_buff=13; break;case 0x21: kbd->kbd_buff=14; break;case 0x22: kbd->kbd_buff=15; break;case 0x25: kbd->kbd_buff=16; break;default: break;}kbd->kbd_status=KEYVALUE_HAVE;}}else if(kpc_value&KPC_DIR){kbd->kbd_buff=KPDK&0xFF;if(kbd->kbd_buff!=0x0){switch(kbd->kbd_buff){case 0x40: kbd->kbd_buff=1; break;case 0x2: kbd->kbd_buff=2; break;case 0x4: kbd->kbd_buff=3; break;case 0x20: kbd->kbd_buff=4; break;default: break;}kbd->kbd_status=KEYVALUE_HAVE;}}if ( fasync )kill_fasync( &(fasync), SIGIO, POLL_IN );wake_up_interruptible(&(kbd->wq));spin_unlock_irq(&(kbd->lock));}4、实现键盘驱动设备打开操作函数static int Emdoor_kbd_open(struct inode *inode, struct file *filp) {int ret;printk(KERN_EMERG " Emdoor_kbd_open!\n");KBD_DEV * kbd;kbd =(KBD_DEV *) kmalloc(sizeof(KBD_DEV ), GFP_KERNEL);KPC=KPC_ASACT | (3<<26) | (7<<23 ) | KPC_IMKP | KPC_MS6 |KPC_MS5 |KPC_MS4 | KPC_MS3 | KPC_MS2 | KPC_MS1 | KPC_MS0 | KPC_ME |KPC_MIE | (7<<6) | KPC_DE | KPC_DIE;init_waitqueue_head(&(kbd->wq));pxa_gpio_mode(94 | GPIO_ALT_FN_1_IN);//KP_DKIN<1>pxa_gpio_mode(95 | GPIO_ALT_FN_1_IN);//KP_DKIN<2>pxa_gpio_mode(98 | GPIO_ALT_FN_1_IN);pxa_gpio_mode(99 | GPIO_ALT_FN_1_IN);pxa_gpio_mode(100 | GPIO_ALT_FN_1_IN);pxa_gpio_mode(101 | GPIO_ALT_FN_1_IN);pxa_gpio_mode(102 | GPIO_ALT_FN_1_IN);pxa_gpio_mode(103 | GPIO_ALT_FN_2_OUT);//KP_MKOUT<0>pxa_gpio_mode(104 | GPIO_ALT_FN_2_OUT);//KP_MKOUT<1>pxa_gpio_mode(105 | GPIO_ALT_FN_2_OUT);//KP_MKOUT<2>pxa_gpio_mode(108 | GPIO_ALT_FN_2_OUT);//KP_MKOUT<5>kbd->kbd_status=KEYVALUE_NO;filp->private_data=kbd;ret = request_irq(IRQ_KEYPAD, Emdoor_isr_kbd, SA_INTERRUPT, DEVICE_NAME, kbd);if (ret){printk(KERN_EMERG " Interrupt init=%x!!!!\n",ret);return ret;}return 0;}5、实现键盘驱动select和poll操作函数static unsigned int Emdoor_kbd_poll(struct file *filp,struct poll_table_struct *wait){printk(KERN_EMERG " Emdoor_kbd_poll!\n");KBD_DEV * kbd=filp->private_data;poll_wait(filp,&(kbd->wq),wait);return (kbd->kbd_status==KEYVALUE_HAVE) ? (POLLIN|POLLRDNORM): 0 ;}static int Emdoor_kbd_release(struct inode *inode, struct file *filp){printk(KERN_EMERG " Emdoor_kbd_release!\n");KBD_DEV * kbd = filp->private_data;KPC=0x0;Emdoor_kbd_fasync(-1, filp, 0);kfree(kbd );free_irq(IRQ_KEYPAD, kbd);return 0;}6、实现键盘驱动非阻塞访问操作函数static int Emdoor_kbd_fasync(int fd, struct file * file, int mode) {return fasync_helper(fd, file, mode, &(fasync) );}7、键盘驱动文件结构体定义static struct file_operations Keypad_fops = {open: Emdoor_kbd_open,read: Emdoor_kbd_read,release: Emdoor_kbd_release,poll: Emdoor_kbd_poll,fasync: Emdoor_kbd_fasync,owner: THIS_MODULE,};8、键盘驱动初始化函数定义static int __init Emdoor_kbd_init(void){printk(KERN_EMERG " Emdoor_kpd initialized\n");int ret;ret = register_chrdev(62, DEVICE_NAME, &Keypad_fops);if (ret < 0) {printk(DEVICE_NAME " can't get major number\n");return ret;}free_irq(IRQ_KEYPAD,NULL);udelay(10);return 0;}9、键盘驱动退出函数定义static void __exit Emdoor_kbd_exit(void){printk(KERN_EMERG " Emdoor_kpd exit\n");unregister_chrdev(62, DEVICE_NAME);}module_init(Emdoor_kbd_init);module_exit(Emdoor_kbd_exit);MODULE_AUTHOR("Ben.li@");MODULE_DESCRIPTION("This is a Keypad driver demo");第二步: 利用vi编辑器,编写一个用于编译Keypad驱动的Makefile# Makefile for the Keypad. #CFLAGS +=$(DEBFLAGS) -Wallifneq ($(KERNELRELEASE),)obj-m :=Keypad.oelseKERNELDIR ?=/root/work/linux-2.6.9PWD :=$(shell pwd)ALL:$(MAKE) $(CFLAGS) -C $(KERNELDIR) M=$(PWD) modulesendifclean:rm -fr *.o *.ko *~ core .depend .*.cmd *.mod.c .tmp_versions第三步:运行make编译命令,用ls命令查看编译后的结果,在该目录中应生成Keypad.ko模块文件,利用file命令查看Keypad.ko文件的格式,应为ARM 格式的ELF文件。

实验二 按键中断实验

实验二  按键中断实验

实验二按键中断实验一、实验目的了解中断的含义二、实验内容板子加电后,按动板子上K1-K3按键,可控制对应的LED1-LED3的亮灭,该实验学习了外部中断(EXTI)程序的编制及控制流程。

三、实验仪器、设备计算机、开发板、keil软件四、硬件设计在开发板上V6、V7、V8分别与MCU的PB5、PD6、PD3相连,如下图所示键盘部分如下图所示:例程所用到的列扫描线:PC5,PC2,PC3。

例程所用到的行扫描线(EXTI中断线):PE2。

五、实验要求和步骤开发板上有3个蓝色状态指示灯V6(LED1),V7(LED2),V8(LED3),通过对应的按键K1-K3,控制LED的亮灭,将PE2引脚配置为外部中断,当其上出现下降沿时产生一个中断,根据扫描PC5,PC2,PC3来判别是哪个按键按下。

首先我们了解一下什么是外部中断/事件控制器(EXTI)。

外部中断/事件控制器由19个产生事件/中断要求的边沿检测器组成。

每个输入线可以独立地配置输入类型(脉冲或挂起)和对应的触发事件(上升沿或下降沿或者双边沿都触发)。

每个输入线都可以被独立的屏蔽。

挂起寄存器保持着状态线的中断要求。

EXTI控制器的主要特性如下:每个中断/事件都有独立的触发和屏蔽每个中断线都有专用的状态位支持多达19 个中断/事件请求检测脉冲宽度低于APB2 时种宽度的外部信号如要产生中断,中断线必须事先配置好并被激活。

这是根据需要的边沿检测通过设置2个触发寄存器,和在中断屏蔽寄存器的相应位写“1”到来允许中断请求。

当需要的边沿在外部中断线上发生时,将产生一个中断请求,对应的挂起位也随之被置1。

通过写“1”到挂起寄存器,可以清除该中断请求。

为产生事件触发,事件连接线必须事先配置好并被激活。

这是根据需要的边沿检测通过设置2个触发寄存器,和在事件屏蔽寄存器的相应位写“1”到来允许事件请求。

当需要的边沿在事件连线上发生时,将产生一个事件请求脉冲,对应的挂起位不被置1。

嵌入式KL25 键盘中断实验

嵌入式KL25  键盘中断实验

嵌入式KL25 键盘中断实验实验五键盘中断实验一、实验目的1.熟练运用CodeWarrior嵌入式开发系统环境、C语言、调试方式。

2.复习串行通信接口(SCI)的内容。

3.加强键盘中断基本原理及编程原理的理解。

4.理解“行扫描”法的原理并能进行键值识别和键值编码。

5.理解键盘接线原理图(如图5-1)。

二、知识要点本实验采用的是4×4矩阵式键盘(以下简称键盘)。

PTG4、PTD2、PTD3、PTD7分别接四根列线,定义为输入且上拉,PTG0~PTG3分别接四根行线,且定义为输出。

行扫描法是使键盘的某一行输出为低电平,其余行为高电平,然后读取列值,如果列值中有某位为低电平,则表明该行和列交点处的键被按下;若为全高则再扫描下一行,直至扫描完全部的行线为止。

这样就可以确定是哪一行哪一列交点的键被按下。

MCU与键盘接线原理图:键盘的c语言编程:1)初始化,先按IO口方式初始化,即定义列线为输入且上拉,行线为输出,然后依输入口的键盘功能初始化相应的寄存器。

2)定义键值表3)扫描一次,读取键值4)获得键盘定义值行扫描法是使键盘的某一行输出为低电平,其余行为高电平,然后读取列值,如果列值中有某位为低电平,则表明该行和列交点处的键被按下;若为全高则再扫描下一行,直至扫描完全部的行线为止。

这样就可以确定是哪一行哪一列交点的键被按下。

设置键盘中断允许寄存器,当键盘有键被按下时,立即产生中断,中断程序处理按键事件,比如确定哪个键被按下,然后转换为该键的定义值。

键盘的键面标示码(即定义值)与MCU 识别的键值对应关系通过列表对应起来,即键盘定义表对应表示。

当通过“行扫描”法获得某个键的键值时,通过查表法就可以得到它的定义值。

该键盘中断方式程序的主程序主体是一个死循环,且是一个空循环体,所有处理的过程代码放在中断程序中。

三、演示性实验在光盘资料中提供读者键盘实例程序文件夹。

编程采用规范要求编写,将键盘独立成一个构件,如C 语言中,形成key.h 头文件和key.c 源文件。

按键的中断的实验

按键的中断的实验

按键的中断编程实验
一.实验目的
1.掌握用C51对外不中断设置的方法
2.掌握按键用C51进行识别的方法
二.实验要求
1.基本要求
(1)能够对有关中断的各个寄存器进行设置
(2)能够用C51编写中断服务程序,当每按一下按键,在中断服务程序中实现数码管上显示数据从0以步进为1的步调增加。

2.扩展要求
(1)用实验板上的上下左右按键做一个秒表,其中做按键作为启动按键,上按键作为清零按键,右按键作为停止按键。

三.实验电路原理图
电路图如下图(1)
四.实验原理简介
(1)每进入中断一次实现数码管上显示数据加1,且按按键时蜂鸣器发声。

(2) 配合上下左右按键做一秒表,要求按左键的话秒表启动,按右键的
话秒表停止,按上键的话秒表清零。

C8
C9
(移)(加)(移)(减)
IN4148X4
图(1)。

《键盘中断实验》课件

《键盘中断实验》课件

中断控制器
控制计算机系统中断的硬 件设备,负责处理外部设 备的中断请求。
实验原理说明
键盘中断
当用户按下键盘上的键时,键盘会产 生一个中断信号,发送给中断控制器 。
中断返回
中断处理程序执行完毕后,中断控制 器恢复被中断的程序执行,继续执行 后续指令。
中断处理
中断控制器接收到键盘中断信号后, 会暂停当前执行的程序,保存程序执 行现场,转而执行相应的中断处理程 序。
异常(Exception):由处理器内部产生的异常事件,例如除以零或访问无效内存地 址。
02
键盘中断实验原理
BIG DATA EMPOWERS TO CREATE A NEW
ERA
实验设备介绍
01
02
03
实验设备
计算机、键盘、中断控制 器
键盘
用于输入字符和命令的外 部设备,通过电缆连接到 计算机。
实验步骤概述
准备实验设备
连接好键盘与计算机,开 启计算机。
观察现象
在程序运行过程中按下键 盘上的键,观察计算机的 反应。
分析结果
根据实验现象,分析键盘 中断的产生和处理过程。
03
实验操作过程
BIG DATA EMPOWERS TO CREATE A NEW
ERA
实验环境搭建
准备实验设备
计算机、键盘、数据采 集卡、信号放大器等。
代码优化
根据测试结果,对代码进行优化和 改进,提高其稳定性和效率。
实验结果分析
数据整理
对采集到的实验数据进行整理和 分析,提取出有用的信息。
结果对比
将实验结果与理论值进行对比, 分析误差产生的原因。
结果讨论
根据实验结果,讨论键盘中断对 计算机性能的影响,并提出改进

键盘中断实验(1)

键盘中断实验(1)

南通大学实验报告院系:计算机科学与技术姓名:课程名称:接口技术成绩:学号:1213022013指导教师:李跃华同组实验者:实验日期:2014-5-7实验名称:键盘中断实验一.实验目的1.熟练运用CodeWarrior 嵌入式开发系统环境、C 语言、调试方式。

2.复习串行通信接口(SCI)的内容。

3.加强键盘中断基本原理及编程原理的理解。

4.理解“行扫描”法的原理并能进行键值识别和键值编码二.实验内容键盘的c 语言编程:1)初始化,先按IO 口方式初始化,即定义列线为输入且上拉,行线为输出,然后依输入口的键盘功能初始化相应的寄存器。

2)定义键值表3)扫描一次,读取键值4)获得键盘定义值行扫描法是使键盘的某一行输出为低电平,其余行为高电平,然后读取列值,如果列值中有某位为低电平,则表明该行和列交点处的键被按下;若为全高则再扫描下一行,直至扫描完全部的行线为止。

这样就可以确定是哪一行哪一列交点的键被按下。

2. 软件设计三程序流程图四编程1.内核定时器中断void tpm0_isr(void){static uint_32 TPMCounter = 0; //计时器uint_8 value; //键盘变量static uint_8 LEDindex=0; //位选口声明uint_8 LEDDataBuffer[4]; //LED显示缓冲区uint_8 i;//LED缓冲区赋值LEDDataBuffer[0]='0';LEDDataBuffer[1]='2';LEDDataBuffer[2]='3';LEDDataBuffer[3]='5';//LCD显示缓冲区,其中.表示按下的数字uint_8 kbv[32]="The keyboard you just input is .";if((TPM_SC_REG(TPM0_BASE_PTR) & TPM_SC_TOF_MASK) == TPM_SC_TOF_MASK) {TPMCounter++;}BSET(TPM_SC_TOF_SHIFT,TPM_SC_REG(TPM0_BASE_P TR)); //中断置标志位写1清0//处理LED部分LEDindex++;//位选位+1if (LEDindex>=4) LEDindex=0; //大于4位选口置0i=LEDchangeCode(LEDDataBuffer[LEDindex]-'0');//转码LEDshow1(LEDindex,i);//显示LEDif(TPMCounter>100){TPMCounter = 0;//键盘得到扫描值value = KBScanN(2);//扫描键值,存于value中if(KBDef(value) != 0xff) //发送键值{//修改.成为按键值kbv[31] = KBDef(value);//通过LCD显示出来LCDShow(kbv);uart_send_string(UART_2,kbv);//键盘发送信息}}}2.程序的入口int main(void){//1.声明主函数使用的局部变量uint_8 * g_DispalyInit;//2.关总中断enter_critical();//3.初始化底层模块uart_init (UART_1,BUSCLK, 9600); //串口1初始化, 总线时钟24000Khz,波特率9600LEDInit();//LED初始化LCDInit();//LCD初始化KBInit(); //键盘初始化tpm_init(TPM0,TPM_CLKSRC_PLL,1000);//初始化TPM模块,1ms中断一次//4.缓冲区赋值g_DispalyInit = (uint_8 *)"Wait Receiving..Soochow 2013.01.";//5.开中断tpm_enable_int(0);init_critical();//6.lcd显示初始字符LCDShow(g_DispalyInit);//================================= ================================== ========for(;;){}//============================================return 0;}四.实验小结在这次实验中主要让我们熟悉掌握gpio口通信的知识,在熟悉代码的前提下在主函数里初始化波特率何在中断函数里添加一个接收函数就可以。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

(6)实现键盘驱动非阻塞访问操作函数
static int Emdoor_kbd_fasync(int fd, struct file * file, int mode) { return fasync_helper(fd, file, mode, &(fasync) ); }
(7)键盘驱动文件结构体定义
(4)实现键盘驱动设备打开操作函数
static int Emdoor_kbd_open(struct inode *inode, struct file *filp) { int ret; printk(KERN_EMERG " Emdoor_kbd_open!\n"); KBD_DEV * kbd; kbd =(KBD_DEV *) kmalloc(sizeof(KBD_DEV ), GFP_KERNEL); KPC=KPC_ASACT | (3<<26) | (7<<23 ) | KPC_IMKP | KPC_MS6 | KPC_MS5 |KPC_MS4 | KPC_MS3 | KPC_MS2 | KPC_MS1 | KPC_MS0 | KPC_ME |KPC_MIE | (7<<6) | KPC_DE | KPC_DIE; init_waitqueue_head(&(kbd->wq)); pxa_gpio_mode(94 | GPIO_ALT_FN_1_IN);//KP_DKIN<1> pxa_gpio_mode(95 | GPIO_ALT_FN_1_IN);//KP_DKIN<2> pxa_gpio_mode(98 | GPIO_ALT_FN_1_IN); pxa_gpio_mode(99 | GPIO_ALT_FN_1_IN); pxa_gpio_mode(100 | GPIO_ALT_FN_1_IN); pxa_gpio_mode(101 | GPIO_ALT_FN_1_IN); pxa_gpio_mode(102 | GPIO_ALT_FN_1_IN); pxa_gpio_mode(103 | GPIO_ALT_FN_2_OUT);//KP_MKOUT<0> pxa_gpio_mode(104 | GPIO_ALT_FN_2_OUT);//KP_MKOUT<1> pxa_gpio_mode(105 | GPIO_ALT_FN_2_OUT);//KP_MKOUT<2> pxa_gpio_mode(108 | GPIO_ALT_FN_2_OUT);//KP_MKOUT<5> kbd->kbd_status=KEYVALUE_NO; filp->private_data=kbd;
kbd_ret = kbd->kbd_buff; copy_to_user(buffer, &kbd_ret, sizeof(KBD_RET)); kbd->kbd_status=KEYVALUE_NO; return sizeof(KBD_RET); } else{ if (filp->f_flags & O_NONBLOCK) return -EAGAIN; interruptible_sleep_on(&(kbd->wq)); if (signal_pending(current)) return -ERESTARTSYS; } } return sizeof(KBD_RET); }
MODULE_LICENSE("GPL"); #define DEVICE_NAME "emdoor_kbd" #define KEYVALUE_HAVE 1 #define KEYVALUE_NO 0 #define KPC_DIR 1<<5 #define KPC_MAT 1<<22 static int Emdoor_kbd_fasync(int, struct file* ,int); typedef unsigned char KBD_RET; struct fasync_struct * fasync; //键盘结构体定义 typedef struct { KBD_RET kbd_buff; /* protect against overrun */ unsigned int kbd_status; wait_queue_head_t wq; spinlock_t lock; } KBD_DEV;
ቤተ መጻሕፍቲ ባይዱ
(8)键盘驱动初始化函数定义
static int __init Emdoor_kbd_init(void) { printk(KERN_EMERG " Emdoor_kpd initialized\n"); int ret; ret = register_chrdev(62, DEVICE_NAME, &Keypad_fops); if (ret < 0) { printk(DEVICE_NAME " can't get major number\n"); return ret; } free_irq(IRQ_KEYPAD,NULL); udelay(10); return 0; }
8-2 键盘中断驱动实验
第 1 步:利用 vi 编辑器,编写一个 Keypad.c 驱动代码; (1)增加驱动所需的头文件和变量
#include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> #include #include #include #include #include <linux/delay.h> <linux/poll.h> <linux/spinlock.h> <asm/hardware.h> <asm/arch-pxa/pxa-regs.h>
static struct file_operations Keypad_fops = { open: Emdoor_kbd_open, read: Emdoor_kbd_read, release: Emdoor_kbd_release, poll: Emdoor_kbd_poll, fasync: Emdoor_kbd_fasync, owner: THIS_MODULE, };
(3)实现键盘驱动中断服务例程
static void Emdoor_isr_kbd(int irq, void *dev_id, struct pt_regs *reg) { printk(KERN_EMERG"Emdoor_isr_kbd,Interrupt\n"); int kpc_value; KBD_DEV * kbd = (KBD_DEV *) dev_id; spin_lock_irq(&(kbd->lock)); kpc_value=KPC; if(kpc_value&KPC_MAT) { kbd->kbd_buff=KPAS&0xFF; if(kbd->kbd_buff!=0xFF){ switch(kbd->kbd_buff){ case 0x0: kbd->kbd_buff=5; break; case 0x1: kbd->kbd_buff=6; break; case 0x2: kbd->kbd_buff=7; break; case 0x5: kbd->kbd_buff=8; break; case 0x10: kbd->kbd_buff=9; break; case 0x11: kbd->kbd_buff=10; break; case 0x12: kbd->kbd_buff=11; break; case 0x15: kbd->kbd_buff=12; break; case 0x20: kbd->kbd_buff=13; break; case 0x21: kbd->kbd_buff=14; break; case 0x22: kbd->kbd_buff=15; break; case 0x25: kbd->kbd_buff=16; break; default: break; } kbd->kbd_status=KEYVALUE_HAVE; }
(8)键盘驱动退出函数定义
static void __exit Emdoor_kbd_exit(void) { printk(KERN_EMERG " Emdoor_kpd exit\n"); unregister_chrdev(62, DEVICE_NAME); } module_init(Emdoor_kbd_init); module_exit(Emdoor_kbd_exit); MODULE_AUTHOR("Ben.li@"); MODULE_DESCRIPTION("This is a Keypad driver demo");
ret = request_irq(IRQ_KEYPAD, Emdoor_isr_kbd, SA_INTERRUPT, DEVICE_NAME, kbd); if (ret) { printk(KERN_EMERG " Interrupt init=%x!!!!\n",ret); return ret; } return 0; }
(2)实现键盘驱动读操作函数
static ssize_t Emdoor_kbd_read(struct file *filp, char *buffer, size_t count, loff_t *ppos) { KBD_DEV * kbd=filp->private_data; KBD_RET kbd_ret; while(1) { if(kbd->kbd_status==KEYVALUE_HAVE) {
相关文档
最新文档