s3c2440之按键中断驱动

发布者:温馨家园最新更新时间:2022-10-25 来源: csdn关键字:s3c2440  按键  中断驱动 手机看文章 扫描二维码
随时随地手机看文章

前言

本文记录的是S3C2440按键中断驱动程序,在查询方式按键驱动程序基础下修改。


一、代码

1.按键中断驱动程序

key_drv.c代码如下(示例):


#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include



static struct class *keydrv_class;

static struct class_device *keydrv_class_dev;


volatile unsigned long *GPFCON;

volatile unsigned long *GPFDAT;


volatile unsigned long *GPGCON;

volatile unsigned long *GPGDAT;


static DECLARE_WAIT_QUEUE_HEAD(button_waitq);


/* 中断事件标志, 中断服务程序将它置1,third_drv_read将它清0 */

static volatile int ev_press = 0;


struct pin_desc {

unsigned int pin;

unsigned int key_val;

};



static unsigned char key_val;

/* 键值: 按下时:0x01, 0x02, 0x03, 0x04 */

/* 键值: 松开时:0x81, 0x82, 0x83, 0x84 */

struct pin_desc pins_desc[4] = {

{S3C2410_GPF0, 0x01},

{S3C2410_GPF2, 0x02},

{S3C2410_GPG3, 0x03},

{S3C2410_GPG11, 0x04},


};


static irqreturn_t buttons_irq(int irq, void *dev_id) {

struct pin_desc * pindesc = (struct pin_desc *)dev_id;

unsigned int pinval;


pinval = s3c2410_gpio_getpin(pindesc->pin);

if(pinval){

/* 松开 */

key_val = 0x80 | pindesc->key_val;

} else {

/* 按下 */

key_val = pindesc->key_val;

}


ev_press = 1;                  /* 表示中断发生了 */

    wake_up_interruptible(&button_waitq);   /* 唤醒休眠的进程 */

return IRQ_RETVAL(IRQ_HANDLED);


}


static int key_drv_open(struct inode* inode, struct file *file){

/* 配置 GPF0,GPF2为输入引脚(置0) */

/* 配置 GPG3,GPG11为输入引脚(置0) */

request_irq(IRQ_EINT0,  buttons_irq, IRQT_BOTHEDGE, "S2", &pins_desc[0]);

request_irq(IRQ_EINT2,  buttons_irq, IRQT_BOTHEDGE, "S3", &pins_desc[1]);

request_irq(IRQ_EINT11, buttons_irq, IRQT_BOTHEDGE, "S4", &pins_desc[2]);

request_irq(IRQ_EINT19, buttons_irq, IRQT_BOTHEDGE, "S5", &pins_desc[3]);

return 0;

}


static ssize_t key_drv_read(struct file *file, char __user *buf, size_t size, loff_t *ppos) {

if(size != 1) {

return -EINVAL;

}


/* 如果没有按键动作, 休眠 */

wait_event_interruptible(button_waitq, ev_press);


/* 如果有按键动作, 返回键值 */

copy_to_user(buf, &key_val, 1);

ev_press = 0;

return 1;



}


int key_drv_close (struct inode* inode, struct file *file) {


free_irq(IRQ_EINT0,  &pins_desc[0]);

free_irq(IRQ_EINT2,  &pins_desc[1]);

free_irq(IRQ_EINT11, &pins_desc[2]);

free_irq(IRQ_EINT19, &pins_desc[3]);


return 0;

}


static struct file_operations key_drv_fops = {

.owner   = THIS_MODULE,

.open    = key_drv_open,

.read    = key_drv_read,

.release = key_drv_close,

};


int major;

static int key_drv_init(void) {

major = register_chrdev(0, "key_drv", &key_drv_fops); //注册驱动程序,告诉内核

keydrv_class = class_create(THIS_MODULE, "key_drv");


keydrv_class_dev = class_device_create(keydrv_class, NULL, MKDEV(major, 0), NULL, "buttons"); /* /dev/buttons */


GPFCON = (volatile unsigned long *)ioremap(0x56000050, 16); //物理地址映射成虚拟地址

GPFDAT = GPFCON + 1;


GPGCON = (volatile unsigned long *)ioremap(0x56000060, 16); //物理地址映射成虚拟地址

GPGDAT = GPGCON + 1;

return 0;

}


static void key_drv_exit(void) {

unregister_chrdev(major, "key_drv"); //卸载驱动

class_device_unregister(keydrv_class_dev);

class_destroy(keydrv_class);


iounmap(GPFCON); //解除映射关系

iounmap(GPGCON); //解除映射关系

}


module_init(key_drv_init);

module_exit(key_drv_exit);


MODULE_LICENSE("GPL"); //让linux识别定义的类


2.测试程序

keydrvtest.c代码如下(示例):


#include

#include

#include

#include


/* keydrvtest 

  */

int main(int argc, char **argv)

{

int fd;

unsigned char key_val;

fd = open("/dev/buttons", O_RDWR);

if (fd < 0)

{

printf("can't open!n");

}


while (1)

{

read(fd, &key_val, 1);

printf("key_val = 0x%xn", key_val);

//sleep(5);

}

return 0;

}


3.Makefile

keydrvtest.c代码如下(示例):


KERN_DIR = /home/book/work/system/linux-2.6.22.6


all:

make -C $(KERN_DIR) M=`pwd` modules 


clean:

make -C $(KERN_DIR) M=`pwd` modules clean

rm -rf modules.order


obj-m += key_drv.o


二、结果显示

在这里插入图片描述

关键字:s3c2440  按键  中断驱动 引用地址:s3c2440之按键中断驱动

上一篇:JZ2440挂载nfs
下一篇:s3c2440之外部中断

推荐阅读最新更新时间:2024-11-09 16:16

ok6410 按键测试c语言版程序
直接贴代码: /* name:led_key author:lvtory 硬件平台:ok6410 function: key1:实现从0-15二进制级数点亮led key2:实现初始化 key3-key6:按键对应点亮相应led 使用查询方式 create:2013.3.17 */ /**** led gpio NLED1-4 - GPM0-3 */ #define rGPMCON (*(volatile unsigned *)0x7F008820) #define rGPMDAT (*(volatile unsigned *)0x
[单片机]
单片机之89c52独立按键 -----学习笔记
一、按键介绍 轻触开关是一种电子开关。 使用:轻按开关按钮可使电路接通、松开,开关断开 二、独立开关工作原理 按键断开和闭合时,触点会存在抖动现象。 P0口:为了实现三态,采用OC(集电极悬空输出)输出,这种电路结构,只有下拉能力,高电平输出没有电流,在高电平时表现为高阻态;加上上拉电阻,就会失去高阻态,变成 1、0 两态(通俗的说就是加上上拉电阻的目的是控制高低电平,不加上拉电阻只用高电平(状态:1),呈高阻态,没有低电平(状态:0)。 NOT(非门):高电平通过变为低电平,低电平通过变为高电平。 2.1、消除按下/松开按键抖动的电路 三、代码 #include reg52.h typedef un
[单片机]
单片机之89c52独立<font color='red'>按键</font> -----学习笔记
S3C2440中断机制
1.中断原理图 2.中断过程 ①. 如果是不带子中断的内部中断:发生后SRCPND相应位置1,那么等待进一步处理。 ②.如果是带子中断的内部中断:发生后SUBSRCPND相应位置1,如果没有被INTSUBMSK屏蔽,那 么SRCPND相应位置1,等待进一步处理 ③.如果是外部中断:EINT0-EINT3发生后SRCPND相应位置1,如果没有被INTMSK屏蔽,那么等待进一步处理。EINT4-EINT23发生后EINTPEND相应位置1,如果没有被EINTMASK屏蔽,那么SRCPND相应位EINT4-7 或EINT8-23置1,如果没有被INTMSK屏蔽,等待进一步处理 三种中断都等待进一步处理了。接下来从SRCPND往
[单片机]
<font color='red'>S3C2440</font>的<font color='red'>中断</font>机制
ARM9_S3C2440学习(二)ARM状态下的寄存器组织
ARM状态下的寄存器组织见图2.3。ARM有37个32位长的寄存器,包括31个通用寄存器、1个当前程序状态寄存器CPSR(current program status register)、5个备份的程序状态寄存器SPSR(saved program status register)。这37个寄存器并不都是同时可见的。在任意时刻,只有16个通用寄存器(R0~R15)和一个或者两个状态寄存器(CPSR和SPSR)对处理器来讲是可见的。 1. 通用寄存器 31个通用寄存器用R0~R15表示,可以分为三类: ●未分组寄存器R0~R7。 ●分组寄存器R8~R14。 ●程序计数器PC(R15)。 (1)未分组寄存器R0~R7   在所有的
[单片机]
51单片机|8个按键控制8个LED灯实现8种功能
任务描述: S1:LED灯全亮; S2:D1、D3、D5、D7亮,然后D2、D4、D6、D8再亮; S3:D5、D6、D7、D8亮; S4:D1、D2、D3、D4亮; S5:D2、D4、D6、D8亮; S6:D1、D3、D5、D7亮; S7:D3、D4、D7、D8亮; S8:D1、D2、D5、D6亮。 硬件电路图: 程序: #include reg51.h void delay(unsigned char i); void main() { unsigned char ledctr; P3=0xff; while(1) { ledctr=P3; switch(ledctr) { case 0xff:P1
[单片机]
S3C2440串口通信基本功能的代码
功能:将通过串口接收到的内容再发送出去,在PC机上看到的现象就是在串口通信软件中输入什么就会实时地显示什么。 主文件:serial.c 1 //最常用的寄存器是ULCON、UCON、UBRDIV、UTRSTAT、UTXH、URXH这六个寄存器 2 #define ULCON0 (*(volatile unsigned *)0X50000000) //UART线控制寄存器 3 #define UCON0 (*(volatile unsigned *)0X50000004) //UART控制寄存器 4 #define UFCON0 (*(volatile unsigned *
[单片机]
S3C2440 按键中断方式汇编代码
SRCPND EQU 0X4A000000 INTMSK EQU 0X4A000008 INTPND EQU 0X4A000010 EINTMASK EQU 0X560000A4 EINTPEND EQU 0X560000A8 EXTINT1 EQU 0X5600008C EXTINT2 EQU 0X56000090 INTMOD EQU 0X4A000004 AREA INT_KEY,CODE,READONLY ENTRY CODE32 ResetEntry b Reset ; //0x04: 未定义指令中止模式的向量地址 HandleUndef b HandleUndef ; //0x08: 管理模式的向量地址,通过
[单片机]
AVR IO输入之独立按键检测程序
系统功能 使用AVR检测八个独立按键,一旦检测到按键被按,立马做出指示,非常牛! 硬件设计 关于AVR的I/O结构及相关介绍详见Datasheet,这里仅对作部分简单介绍,下面是AVR的I/O引脚配置表: AVR主控电路原理图 LED控制电路原理图 独立按键电路原理图 软件设计 下面部分从TXT拷出,拷到网页,代码部分缺省了很多空格,比较凌乱,请谅解! //目标系统: 基于AVR单片机 //应用软件: ICC AVR /*01010101010101010101010101010101010101010101010101010101010101010101 ------------------------
[单片机]
AVR IO输入之独立<font color='red'>按键</font>检测程序
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
随便看看

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved