按鍵驅動程序(1)

作者:趙明,華清遠見嵌入式學院講師。

 

中斷編程基礎

  實際上,有很多Linux的驅動都是通過中斷的方式來進行內核和硬件的交互。中斷機制提供了硬件和軟件之間異步傳遞信息的方式。硬件設備在發生某個事件時通過中斷通知軟件進行處理。中斷實現了硬件設備按需獲得處理器關注的機制,與查詢方式相比可以大大節省CPU資源的開銷。

  在此將介紹在驅動程序中用於申請中斷的requeST_IRq()調用,和用於釋放中斷的free_irq()調用。request_irq()函數調用的格式如下所示:

  int request_irq(unsigned int irq,
                void (*handler)(int irq, void *dev_id, struct pt_regs *regs),
                unsigned lONg irqflags, const char * devname, oid *dev_id);

  其中irq是要申請的硬件中斷號。在Intel平臺,範圍是0~15。

  參數handler爲將要向系統註冊的中斷處理函數。這是一個回調函數,中斷髮生時,系統調用這個函數,傳入的參數包括硬件中斷號、設備id以及寄存器值。設備id就是在調用request_irq()時傳遞給系統的參數dev_id。

  參數irqflags是中斷處理的一些屬性,其中比較重要的有SA_INteRRUPT。這個參數用於標明中斷處理程序是快速處理程序(設置SA_INTERRUPT)還是慢速處理程序(不設置SA_INTERRUPT)。快速處理程序被調用時屏蔽所有中斷。慢速處理程序只屏蔽正在處理的中斷。還有一個SA_SHIRQ屬性,設置了以後運行多個設備共享中斷,在中斷處理程序中根據dev_id區分不同設備產生的中斷。

  參數devname爲設備名,會在/dev/interrupts中顯示。

  參數dev_id在中斷共享時會用到。一般設置爲這個設備的device結構本身或者NULL。中斷處理程序可以用dev_id找到相應的控制這個中斷的設備,或者用irq2dev_map()找到中斷對應的設備。

  釋放中斷的free_irq()函數調用的格式如下所示。該函數的參數與request_irq()相同。

  void free_irq(unsigned int irq, void *dev_id);

按鍵工作原理

  LED蜂鳴器是最簡單的GPIO的應用,都不需要任何外部輸入或控制。按鍵同樣使用GPIO接口,但按鍵本身需要外部的輸入,即在驅動程序中要處理外部中斷。按鍵硬件驅動原理圖如圖1所示。在圖1的4 X 4矩陣按鍵(K1~K16)電路中,使用4個輸入/輸出端口(EINT0、EINT2、EINT11和EINT19)和4個輸出端口(KSCAN0~KSCAN3)。


  圖1 按鍵驅動電路原理圖

  按鍵驅動電路使用的端口和對應的寄存器如表11-18所示。

  表1 按鍵電路的主要端口

管腳

端口

輸入/輸出

EINT0

EINIT0/GPF0

輸入/輸出

EINT2

EINT2/GPF2

輸入/輸出

EINT11

EINT11/GPG3

輸入/輸出

EINT19

EINT19/GPG11

輸入/輸出

管腳

端口

輸入/輸出

KEYSCAN0

GPE11

輸出

KEYSCAN1

GPG6

輸出

KEYSCAN2

GPE13

輸出

KEYSCAN3

GPG2

輸出

 

  因爲通常中斷端口是比較珍貴且有限的資源,所以在本電路設計中,16個按鍵複用了4箇中斷線。那怎麼樣才能及時而準確地對矩陣按鍵進行掃描呢?

  某個中斷的產生表示,與它所對應的矩陣行的4個按鍵中,至少有一個按鍵被按住了。因此可以通過查看產生了哪個中斷,來確定在矩陣的哪一行中發生了按鍵操作(按住或釋放)。例如,如果產生了外部2號線中斷(EINT2變爲低電平),則表示K7、K8、K9和K15中至少有一個按鍵被按住了。這時候4個EINT端口應該通過GPIO配置寄存器被設置爲外部中斷端口,而且4個KSCAN端口的輸出必須爲低電平。

  在確定按鍵操作所在行的位置之後,我們還得查看按鍵操作所在列的位置。此時要使用KSCAN端口組,同時將4個EINT端口配置爲通用輸入端口(而不是中斷端口)。在4個KSCAN端口中,輪流將其中某一個端口的輸出置爲低電平,其他3個端口的輸出置爲高電平。這樣逐列進行掃描,直到按鍵所在列的KSCAN端口輸出爲低電平,此時按鍵操作所在行的EINT管腳的輸入端口的值會變成低電平。例如,在確認產生了外部2號中斷之後,進行逐列掃描。若發現在KSCAN1爲低電平時(其他端口輸出均爲高電平),GPF2(EINT2管腳的輸入端口)變爲低電平,則可以斷定按鍵K8被按住了。

  以上的討論都是在按鍵的理想狀態下進行的,但實際的按鍵動作會在短時間(幾毫秒至幾十毫秒)內產生信號抖動。例如,當按鍵被按下時,其動作就像彈簧的若干次往復運動,將產生幾個脈衝信號。一次按鍵操作將會產生若干次按鍵中斷,從而會產生抖動現象。因此驅動程序中必須要解決去除抖動所產生的毛刺信號的問題。

  “本文由華清遠見http://www.embedu.org/index.htm提供”



  來源:華清遠見
發佈了18 篇原創文章 · 獲贊 12 · 訪問量 9萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章