<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>

新聞中心

EEPW首頁(yè) > 嵌入式系統 > 設計應用 > [ARM應用]按鍵中斷驅動(dòng)實(shí)例

[ARM應用]按鍵中斷驅動(dòng)實(shí)例

作者: 時(shí)間:2016-12-02 來(lái)源:網(wǎng)絡(luò ) 收藏

  1 實(shí)驗目的

本文引用地址:http://dyxdggzs.com/article/201612/341050.htm

  (1)了解按鍵原理及其與S3C2410的接口電路設計

  (2)了解S3C2410芯片的外部中斷處理機制

  (3)掌握驅動(dòng)的編寫(xiě)及測試過(guò)程

  2 實(shí)驗原理

  (1)按鍵的硬件原理

  在嵌入式系統中,按鍵的硬件原理比較簡(jiǎn)單,通過(guò)一個(gè)上拉電阻將處理器的外部中斷(或GPIO)引腳拉高,電阻的另一端連接按鍵并接地即可實(shí)現。如圖2-1所示:

    

[ARM應用]按鍵中斷驅動(dòng)實(shí)例 - Fantity Wei - Footprint

  圖

  2-1按鍵接口電路

  仔細看圖2-1,不難知道,當按鍵被按下時(shí),EINT0上將產(chǎn)生低電平,這個(gè)低電平將中斷CPU,CPU可以依據中斷判斷按鍵被按下。

  (2)按鍵“消抖”

  所有按鍵、觸摸屏等機械設備都存在一個(gè)固有的問(wèn)題,那就是"抖動(dòng)",按鍵從最初接通到穩定接通要經(jīng)過(guò)數毫秒乃至數十毫秒,其間可能發(fā)生多次"接通―斷開(kāi)"的過(guò)程。因此僅僅依據中斷被產(chǎn)生就認定有一次按鍵行為是很不準確的。如果不消除"抖動(dòng)"的影響,一次按鍵可能被理解為多次按鍵。

  消除按鍵抖動(dòng)影響的方法是:在判斷有鍵按下后,進(jìn)行軟件延時(shí)(如20ms,在延時(shí)過(guò)程中要屏蔽對應中斷),再判斷鍵盤(pán)狀態(tài),如果仍處于按鍵按下?tīng)顟B(tài),則可以判定該按鍵被按下。圖2-2是典型的包含消抖功能的處理流程。

    

[ARM應用]按鍵中斷驅動(dòng)實(shí)例 - Fantity Wei - Footprint

 

  圖2-2 處理流程

  3 實(shí)驗任務(wù)

  (1)編寫(xiě)按鍵中斷設備驅動(dòng)程序,驅動(dòng)程序中手動(dòng)定義設備名稱(chēng)及主設備號為213,實(shí)現與BUTTON設備相應的端口配置,中斷的申請,以及讀寫(xiě)設備的接口函數等。

  (2)將驅動(dòng)編譯成模塊,并實(shí)現模塊的加載及卸載。

  (3)編寫(xiě)驅動(dòng)的測試程序,在程序中實(shí)現打開(kāi)BUTTON設備和LED設備,主循環(huán)中不斷讀取按鍵的狀態(tài),當按鍵按下時(shí),控制LED亮一段時(shí)間(1S左右)后滅掉。

  4. 實(shí)驗步驟

  以下操作都在nfs文件系統目錄(/home/kernel/rootfs/rootfs)下進(jìn)行,因此先執行如下命令。獲取

  cd /home/kernel/rootfs/rootfs

  (1)編寫(xiě)led.c文件

  建立led目錄:

  mkdir usr/button

  進(jìn)入button目錄,在該目錄下建立兩個(gè)子目錄driver 和test ,前者用來(lái)存放驅動(dòng)程序,后者用來(lái)存放驅動(dòng)測試程序:

  cd usr/ button

  mkdir driver test

  進(jìn)入驅動(dòng)程序目錄,建立設備驅動(dòng)文件button.c:

  cd driver

  vi button.c

  按鍵驅動(dòng)程序如下button.c所示:

  /*************************** 頭文件 ***************************/

  #include

  #include

  #include

  #include

  #include

  #include

  #include

  #include

  #include

  #include

  #include

  #include

  #include

  #include

  #include

  #include

  //*********************** 定義設備結構體及相關(guān)宏 ***************************

  #define DEVICE_NAME "button" //定義設備名

  #define DEVICE_MAJOR 213 //手動(dòng)定義BUTTON設備的主設備號為213

  static int button_major = DEVICE_MAJOR ;

  #define BUTTON_IRQ IRQ_EINT0 //定義BUTTON對應S3C2410的外部中斷0

  #define BUTTON S3C2410_GPF0 //定義BUTTON對應S3C2410的GPF0端口

  #define BUTTON_EINT0 S3C2410_GPF0_EINT0

  #define BUTTON_INP S3C2410_GPF0_INP

  #define BUTTON_UP 0 //按鍵抬起狀態(tài)

  #define BUTTON_DOWN 1 //按鍵按下?tīng)顟B(tài)

  #define BUTTON_X 2 //不確定狀態(tài),本實(shí)例中可理解為抖動(dòng)狀態(tài)

  //定義BUTTON設備結構體

  struct button_dev

  {

  struct cdev cdev; //BUTTON設備對應一個(gè)字符設備結構體

  int status; //按鍵狀態(tài)標識:抬起、按下、抖動(dòng)

  };

  static struct button_dev dev;

  //***************************** 函數聲明 *********************************

  void s3c2410_button_s3c2410_button_InitIO(void); //初始化IO端口的函數

  /*

  ******************************s3c2410_button_InitIO**********************

  *描述 :初始化IO端口

  *參數 :無(wú)

  *返回值:無(wú)

  *************************************************************************

  */

  void s3c2410_button_InitIO(void)

  {

  s3c2410_gpio_cfgpin(BUTTON,BUTTON_EINT0); //配置按鍵中斷的端口為中斷功能

  }

  /*

  ******************************isr_button()*******************************

  *描述 :EINT0的中斷處理函數,設置按鍵狀態(tài)為BUTTON_X

  *參數 :irq :中斷號; dev_id;regs;

  *返回值:成功返回0

  *在linux/interrupt.h中定義了typedef irqreturn_t (*irq_handler_t)(int, void *);

  *************************************************************************

  */

  static irqreturn_t isr_button(int irq,void *dev_id,struct pt_regs *regs)

  {

  disable_irq(0); //禁止中斷

  dev.status = BUTTON_X;//將按鍵置為抖動(dòng)狀態(tài),說(shuō)明有按鍵中斷,但不一定有鍵按下

  enable_irq(0); //使能中斷

  return 0;

  }

  /*

  **************************s3c2410_button_open()**************************

  *描述 :打開(kāi)設備函數,向系統申請中斷

  *參數 :struct inode *inode,struct file *filp

  *返回值:失敗返回錯誤代碼ret,成功返回0

  *************************************************************************

  */

  static int s3c2410_button_open(struct inode *inode,struct file *filp)

  {

  int ret;

  ret=request_irq(BUTTON_IRQ,isr_button,IRQF_SAMPLE_RANDOM,DEVICE_NAME,NULL); //申請中斷

  if(ret) {//申請失敗

  printk("BUTTON_IRQ: could not register interruptn");

  return ret;

  }

  return 0;

  }

  /*

  ************************s3c2410_button_release()*************************

  *描述 :注銷(xiāo)設備函數,實(shí)現中斷釋放

  *參數 :struct inode *inode,struct file *filp

  *返回值:0

  *************************************************************************

  */

  static int s3c2410_button_release(struct inode *inode,struct file *filp)

  {

  free_irq(BUTTON_IRQ,NULL); //釋放中斷

  return 0;

  }

  /*

  **************************3c2410_button_ioctl()**************************

  *描述 :IO控制函數,本實(shí)例中不做任何事

  *參數 :cmd: 用戶(hù)定義的IO控制命令; arg: 傳遞用戶(hù)參數

  *返回值:0

  *************************************************************************

  */

  static int s3c2410_button_ioctl(struct inode *inode,struct file *filp,

  unsigned int cmd,unsigned long arg)

  {

  return 0;

  }

  /*

  **************************s3c2410_button_read()**************************

  *描述 :讀函數,讀取按鍵的狀態(tài)

  *參數 :buffer: 用來(lái)存儲按鍵狀態(tài);

  count: 用來(lái)記錄用戶(hù)讀取了多少個(gè)字符

  *返回值:count:用戶(hù)讀取的字符數

  *************************************************************************

  */

  static ssize_t s3c2410_button_read(struct file *filp,char *buffer,size_t count,loff_t *ppos)

  {

  int ret = count ;

  if(dev.status = BUTTON_X){//如果按鍵狀態(tài)是BUTTON_X,說(shuō)明有按鍵中斷產(chǎn)生。

  msleep(20); //延時(shí)20毫秒去除按鍵抖動(dòng)

  disable_irq(0); //禁止中斷

  s3c2410_gpio_cfgpin(BUTTON,BUTTON_INP); //配置按鍵中斷的端口為輸入功能

  if(!s3c2410_gpio_getpin(BUT

  if(!s3c2410_gpio_getpin(BUTTON)){//讀取端口的值,如果是0說(shuō)明按鍵按下

  dev.status = BUTTON_DOWN;

  }

  else dev.status = BUTTON_UP; //如果為1,說(shuō)明只是按鍵抖動(dòng)

  //重新配置按鍵中斷的端口為中斷功能

  s3c2410_gpio_cfgpin(BUTTON,S3C2410_GPF0_EINT0);

  enable_irq(0); //使能中斷

  }

  put_user(dev.status,(int *)buffer); //將按鍵狀態(tài)提交給用戶(hù)

  return ret;

  }

  /*

  **************************3c2410_button_write()**************************

  *描述 :寫(xiě)操作函數,本實(shí)例中不做任何事

  *參數 :

  *返回值:count

  *************************************************************************

  */

  static ssize_t s3c2410_button_write(struct file *filp,char *buffer,size_t count,loff_t *ppos)

  {

  int ret = count;

  return ret;

  }

  /*

  **************************s3c2410_button_fops****************************

  *描述 :文件操作結構體,實(shí)現 s3c2410_button_open()等函數與open()等系統調用的連接

  *參數 :

  *返回值:

  *************************************************************************

  */

  static struct file_operations s3c2410_button_fops = {

  .owner = THIS_MODULE,

  .open = s3c2410_button_open,

  .release = s3c2410_button_release,

  .ioctl = s3c2410_button_ioctl,

  .read = s3c2410_button_read,

  .write = s3c2410_button_write,

  };

  /*

  **************************button_setup_cdev()****************************

  *描述 :安裝模塊的函數,在設備加載模塊里面調用

  *參數 :無(wú)

  *返回值:無(wú)

  *************************************************************************

  */

  static void button_setup_cdev(void)

  {

  int err,devno = MKDEV(button_major,0);

  cdev_init(&dev.cdev,&s3c2410_button_fops);

  dev.cdev.owner = THIS_MODULE;

  dev.cdev.ops = &s3c2410_button_fops;

  err = cdev_add(&dev.cdev,devno,1);

  if(err)

  printk("Error %d adding BUTTON%d",err);

  }

  /*


上一頁(yè) 1 2 下一頁(yè)

關(guān)鍵詞: ARM 按鍵中斷

評論


相關(guān)推薦

技術(shù)專(zhuān)區

關(guān)閉
国产精品自在自线亚洲|国产精品无圣光一区二区|国产日产欧洲无码视频|久久久一本精品99久久K精品66|欧美人与动牲交片免费播放
<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>