按键中断 定时器

按键中断,定时器消抖点亮LED  2011-08-25 10:42:14|  分类: linux驱动源码 |  标签: |字号大中小 订阅 .

/**********************头文件等的使用*******************************/
#include <linux/module.h> //一定要
#include <linux/kernel.h> //printk
#include <linux/irq.h>   //中断IRQ_EINT等的定义
#include <linux/interrupt.h> //request_irq,free_irq等的使用
#include <linux/fs.h>  //file_operations
#include <linux/init.h>  //__init等的使用
#include <linux/cdev.h>  //cdev注册
#include <linux/errno.h> //错误信息
#include <linux/types.h> //size_t和ssize_t等的使用
#include <linux/device.h> //class_create创造


#include <mach/regs-gpio.h> //所以的gpio端口的定义都在这里
#include <mach/hardware.h> //setpin等的使用

#include <asm/uaccess.h> //copy_to_user等的使用
/


/********************全局变量,常量等的使用**************************/
#define  BUTTON_MAJOR 19   //主设备号
#define  BUTTON_NAME "zheng_he_xiang" //设备名字
#define  BUTTON_NUM 4   //键盘数量
#define  BUTTON_ON 1   //键盘被按下
#define  BUTTON_OFF 0   //键盘没被按下
#define  BUTTON_DELAY (HZ/50)   //延时时间
#define  LED_ON  0   //灯亮
#define  LED_OFF  1   //灯灭
//
static int button_major=BUTTON_MAJOR;   //主设备号

//

/************************结构体的定义******************************/
struct button_dev
{
 struct cdev cdev; //cdev
 
};
//

static struct button_dev *button_devp; //定义pointer

//

struct button_irq_desc
{
 unsigned int irq;  //中断号
 unsigned int button_pin;  //按键端口
 unsigned int button_pin_setting;//按键端口设置

 unsigned int number;  //按键值

 char *name;   //该按键中断的名字

 unsigned int led_pin;  //led所在的端口
 unsigned int led_pin_setting; //led所在端口的设置

 unsigned int key_status;
};
/
static struct button_irq_desc button_number[]=
{
 {IRQ_EINT0,S3C2410_GPF0,S3C2410_GPF0_EINT0,0,"Key0",S3C2410_GPB5,S3C2410_GPB5_OUTP,0},
 {IRQ_EINT1,S3C2410_GPF1,S3C2410_GPF1_EINT1,1,"Key1",S3C2410_GPB6,S3C2410_GPB6_OUTP,0},
 {IRQ_EINT2,S3C2410_GPF2,S3C2410_GPF2_EINT2,2,"Key2",S3C2410_GPB7,S3C2410_GPB7_OUTP,0},
 {IRQ_EINT4,S3C2410_GPF4,S3C2410_GPF4_EINT4,3,"KEy4",S3C2410_GPB8,S3C2410_GPB8_OUTP,0},
};     //数组定义
/
static struct timer_list button_timer[BUTTON_NUM];//定时器设置


自动加载节点
struct class *button_class;//自动加载节点

 

/****************************************定时器中断处理函数***********************************/

static void button_timer_handle(unsigned long data)
{
 int ret=0;
 unsigned int num=(unsigned int)data;

 printk("num is %d\n",num);
 
 ret=s3c2410_gpio_getpin(button_number[num].button_pin);
 printk("ret is %d\n",ret);

 if(ret==0)
 {
  s3c2410_gpio_setpin(button_number[num].led_pin,LED_ON);
 }
 
 if(ret>0)
 {
  s3c2410_gpio_setpin(button_number[num].led_pin,LED_OFF);
 }
 

 
 
}

/**************************************按键中断处理函数**************************************/

static irqreturn_t button_interrupt(int irq,void *dev_id)
{
 struct button_irq_desc *button=(struct button_irq_desc *)dev_id;//把参数给button
 
 int ret;

 ret=s3c2410_gpio_getpin(button->button_pin);
 del_timer(&button_timer[button->number]);
 setup_timer(&button_timer[button->number],button_timer_handle,button->number);
 button_timer[button->number].expires=jiffies+BUTTON_DELAY;
 add_timer(&button_timer[button->number]);
 if(ret)
 {
  //s3c2410_gpio_setpin(button->led_pin,LED_OFF);
  button->key_status=0;
  printk("LED_ON  key_status is %d\n",button->key_status);
 }
 
 else
 {
  //s3c2410_gpio_setpin(button->led_pin,LED_ON);
  button->key_status=1;
  printk("LED_OFF key_status is %d\n",button->key_status);
 }
 
 
 
 
 
 printk("EN the button..num is %d\n",button->number);
 return IRQ_HANDLED;
}
///

/*******************************************打开函数*****************************************/
static int button_open(struct inode *inode,struct file *file)
{
 //file->private_data=button_devp;//给私有参数
 
 int i;
 int ret;//返回值
 local_irq_disable();


 printk("local_irq_disable\n");
 for(i=0;i<sizeof(button_number)/sizeof(button_number[0]);i++)
 {

  /***************定时器初始化****************/
  setup_timer(&button_timer[i],button_timer_handle,i);
  button_timer[i].expires=jiffies+BUTTON_DELAY;
  //add_timer(&button_timer[i]);
 
  /*****************端口初始化****************/
  s3c2410_gpio_cfgpin(button_number[i].button_pin,button_number[i].button_pin_setting);
  s3c2410_gpio_cfgpin(button_number[i].led_pin,button_number[i].led_pin_setting);
  s3c2410_gpio_setpin(button_number[i].led_pin,LED_OFF);//关灯

 /*****************初始化中断*****************/
 
  ret=request_irq(button_number[i].irq,button_interrupt,IRQ_TYPE_EDGE_BOTH,button_number[i].name,&button_number[i]);
  if(ret)
  {
   break;
  }
 }
 
 
 if(ret)
 {
  i--;
  for(;i>0;i--)
  {
   free_irq(button_number[i].irq,&button_number[i]);
   printk("free irq err\n");
  }
  return ret;
 }
 local_irq_enable();

 return 0;
}
//

/*********************************************关闭函数*********************************************/
static int button_close(struct inode *inode,struct file *file)
{
 
 int i;

 for(i=0;i<sizeof(button_number)/sizeof(button_number[0]);i++)
 {
  del_timer(&button_timer[i]);//删除中断
  free_irq(button_number[i].irq,&button_number[i]);
 }

 return 0;
}

 

/*********************************************结构体********************************************/
static const struct file_operations button_fops=
{
 .owner=THIS_MODULE,
 .open=button_open,
 .release=button_close,

};

/

/****************************cdev注册函数***************************************/
static void button_setup_cdev(struct button_dev *dev,int index)
{
 int err;
 dev_t devno=MKDEV(button_major,index);

 cdev_init(&dev->cdev,&button_fops);
 dev->cdev.owner=THIS_MODULE;
 dev->cdev.ops=&button_fops;
 
 err=cdev_add(&dev->cdev,devno,1);
 if(err)
 {
  printk(KERN_NOTICE "cdev err");
 }
}

 

 

/**************************************模块加载函数***********************************/
static __init int button_init(void)
{
 int result;
 dev_t devno=MKDEV(button_major,0);

 if(button_major)
 {
  result=register_chrdev_region(devno,1,BUTTON_NAME);
 }
 else
 {
  result=alloc_chrdev_region(&devno,0,1,BUTTON_NAME);
  button_major=MAJOR(devno);
 }
 if(result<0)
 {
  return result;
 }
 printk("region ok ...\n");

 button_devp=kmalloc(sizeof(struct button_dev),GFP_KERNEL);
 if(!button_devp)
 {
  result=-ENOMEM;
  goto fail_malloc;
 }
 printk("kmalloc ok ...\n");

 memset(button_devp,0,sizeof(struct button_dev));//清0

 button_setup_cdev(button_devp,0);
 
/
 button_class = class_create(THIS_MODULE, BUTTON_NAME);
      if(IS_ERR(button_class))
      {
          printk("Err: failed in creating class.\n");
          return -1;
      }

  /* register your own device in sysfs, and this will cause udev to create corresponding device node */
        device_create( button_class, NULL, MKDEV(button_major, 0), NULL, BUTTON_NAME );
 printk("device ok ...\n");
//


 return 0;

fail_malloc:unregister_chrdev_region(devno,1);
 return result;
}
/

/************************************卸载函数**********************************/

static void __exit button_exit(void)
{
 cdev_del(&button_devp->cdev);
 kfree(button_devp);
 unregister_chrdev

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值