1. 程式人生 > >韋東山嵌入式Linux學習筆記之——第12課第8節 字元裝置驅動程式之定時器防抖動

韋東山嵌入式Linux學習筆記之——第12課第8節 字元裝置驅動程式之定時器防抖動

注:本文部分內容摘自《魚樹學員筆記》。

當按鍵按得比較快的時候,這裡出現了兩次中斷值,也即產生了抖動。

這裡產生了“抖動”,按鍵是機械開關,按下鬆開時裡面的金屬彈片可能抖動了好幾次。這種抖動產生了多次“脈衝”導致多次中斷。

方法:

使用定時器來防抖動。

定時器有兩個概念:

① 超時時間:

② 時間到了之後的“處理函式”。

可以在中斷處理中,如定時 10ms 後處理確定按鍵值上報。

之後再產生中斷:

在中斷中加定時器,當遇到 A 中斷時加一個 10ms 的定時器,過了 10ms 後就去執行“處理函式”(確定按鍵值上報)。因為機械的抖動會非常快,沒等到 10ms 後的處理,這時因為抖動又來了一箇中斷 B,這時中斷 B 把之前的那個定時器修改了。所以 A 中斷的定時器就取消了。最後又來了一箇中斷 C,同樣會修改掉 B 中斷的定時器。上圖中是假設抖動時產生了 3 箇中斷,所以對於同一個“定時器”,最終中斷 C 的定時器沒有被修改,所以 10ms 後由中斷 C 的處理函式上報了按鍵值。最後這個 10ms 是從抖動 C 處開始。這樣 3 個抖動的中斷只會導致最後處理一個“上報按鍵值”(定時器過後的處理函式只會執行一次)。以上便是用定時器消除抖動的原理。因為是修改同一個定時器,所以前面的定時又取消,相當於把“鬧鐘”時間往後調整時,最終只要響一次鬧鈴。

1. 在核心程式碼中查詢add_timer 的用法。

① 首先定義一個timer_list 型別的靜態結構體變數buttons_timer:

② 然後初始化該結構體,並定義按鍵定時器函式buttons_timer_function

注意:這裡的buttons_timer_function定時器中斷處理函式需要我們自己去定義。函式的原型為:

這裡的buttons_timer_function函式返回值為void,引數是初始化結構體時傳入的data引數。

這樣定時器就算定義完畢了,其中定時器的兩個必要條件超時時間和處理函式,其中處理函式已經定義好了,超時時間在後面的中斷服務程式中加入

要啟用定時器,還必須通過add_timer()函式將定義好的定時器加入到核心中,主要任務是告訴核心,當定時器中設定好的超時時間到了之後,核心就會自動呼叫buttons_timer_function函式。

2. 修改中斷處理函式

將之前中斷處理函式中的按鍵處理內容全部轉移到按鍵定時器函式 buttons_timer_function 中來完成。

② 在之前的中斷服務程式中只需要修改定時器的超時時間即可。

注意:這裡的超時時間就是我們在前面所提到的最終鬧鐘到來的時間。

mod_timer的函式原型為:

mod_timer函式中的jiffies引數:

定時器的定義和觸發時間: 定時器的超時時間就是基於jiffies

來設定的。

jiffies 是一個全域性變數,系統每隔10ms,該值就會改變併產生一個系統時鐘中斷,在中斷中該值就會累加(jiffies+1)。

這裡定義的HZ的值為100,含義就是1秒的時間計數100次,那麼計數一次的時間就是10ms,因此jiffies這個引數這裡就加了HZ/100(相當於jiffies+1),剛好是10ms。如果沒有按鍵按下,系統不會觸發中斷也就不會往後推遲時間,那麼一旦在這期間過了10ms,系統就會去呼叫那個按鍵定時器函式buttons_timer_function

接下來再定義一個發生中斷時候的引腳描述結構體

(該結構體指標是全域性變數)

用來記錄發生中斷時候的裝置號

另外還有一個問題需要去考慮,就是在入口函式中沒有設定定時器的超時時間,也就是說開始的超時時間就是0,那麼通過add_timer函式將定時器放進核心以後,一旦進入系統時鐘的中斷,jiffies這個引數的值就會大於0,就會隨即呼叫按鍵定時器函式buttons_timer_function,但是這時候並沒有按鍵中斷產生。

因此要在按鍵定時器處理函式中加入判斷:如果是空,則直接返回不做處理。

至此,按鍵定時器防抖動的程式就算是寫完了。

跟以前的函式做一個簡單的對比:

before:只要有按鍵按下就會進入中斷處理函式buttons_irq,在該函式中獲取引腳值和按鍵值,之後喚醒休眠的程序,最後傳送訊號。

now:為了防抖動,現在只要有按鍵按下進入中斷處理函式buttons_irq中,首先獲取裝置號,然後修改定時器的超時時間為10ms以後,之後便直接返回而不採取任何操作。

根據這個原理圖我們可以很容易理解,如果按鍵有抖動,不斷進入中斷處理函式,那麼在中斷中就會不斷將系統時鐘的超時時間向後推遲10ms,一旦抖動不再發生(注意:一般情況下抖動都小於10ms),過了系統定時器超時時間(10ms),那麼就會進入按鍵定時器處理函式中,這時候才會跟以前一樣獲取引腳值和按鍵值,之後喚醒休眠的程序,最後傳送訊號。

相關推薦

東山嵌入式Linux學習筆記——128 字元裝置驅動程式定時抖動

注:本文部分內容摘自《魚樹學員筆記》。 當按鍵按得比較快的時候,這裡出現了兩次中斷值,也即產生了抖動。 這裡產生了“抖動”,按鍵是機械開關,按下鬆開時裡面的金屬彈片可能抖動了好幾次。這種抖動產生了多次“脈衝”導致多次中斷。 方法: 使用定時器來防抖動。

使用u-boot的tftp下載功能燒寫程式到Nand Flash ——東山嵌入式Linux學習筆記09

本文實驗環境: 1. windows 7(64bit) 2. JZ2440(V2) (2)啟動軟體tftpd32,選擇要下載的程式所在的目錄 (3)假設下載檔案leds.bin,在u-boot的命令列,輸入 tftp 30000000 le

字元裝置驅動程式非同步通知

非同步通知:      驅動程式的所謂非同步通知,指的是應用程式不是主動對驅動程式進行操作,而是驅動程式查詢到有事件發生或者有資料發生變化的時候通知應用程式。角色發生了變化,應用程式由主動改為被動執行。 比如按鍵驅動: 1、要不斷進行查詢引腳狀

開發板的I/O在哪裡——東山嵌入式Linux視訊學習筆記01

一般來說,串列埠就是開發板的I/O(輸入輸出)介面。我們可以通過串列埠向板子傳送命令,也可以通過串列埠把板子的狀態資訊打印出來。 板載串列埠和PC的連線 如果板子上有串列埠,且電腦上也有串列埠,那直接用串列埠線相連就可以。對於沒有串列埠的膝上型電腦,可以

用OpenJTAG燒寫程式到Flash—— 東山嵌入式Linux視訊學習筆記03

說明:本文僅在Windows環境下實驗。 韋東山的JZ2440(v2),可以選擇從Nor Flash啟動,也可以選擇從Nand Flash啟動,不管從哪裡啟動,都需要Flash上有程式,沒有程式的話,板子就是一塊磚頭。 按照常規思維,板子上應該有一個Boot

嵌入式Linux學習筆記三天(檔案程式設計)

                                                  嵌入式Linux學習筆記第三天           ——檔案程式設計                  嵌入式Linux檔案程式設計有兩種方式:系統呼叫和庫函式。常用的檔案

嵌入式Linux學習筆記(三)檔案程式設計

一、系統呼叫-建立 int creat(const char *filename,mode_t mode) filename:要建立的檔名(包含路徑,預設為當前路徑) mode:建立模式 常見建立模式: S_IRUSR 可讀

嵌入式Linux學習筆記(1)

一、基本概念 1、檔案系統:對計算機資料的分類儲存。 2、檔案和目錄:對資料的一種分類。 3、/:(1)作根目錄名(處於開頭);(2)作分割符(不在開頭)。 4、路徑: (1)絕對路徑:從”/”目錄出發的路徑;如:/home/linux/截圖軟體。

嵌入式Linux學習筆記(三) 字元裝置驅動--LED的驅動開發

  在成功構建了一個能夠執行在開發板平臺的系統後,下一步就要正式開始應用的開發(這裡前提是有一定的C語言基礎,對ARM體系的軟/硬體,這部分有疑問可能要參考其它教程),根據需求仔細分解任務,可以發現包含的外設有LED,BEEP,RS232,六軸感測(SPI介面),光環境感測器(I2C),音訊輸出, RTC等,

Linux學習筆記4月12日任務

apache php httpd 默認虛擬主機 11.14/11.15 Apache和PHP結合11.16/11.17 Apache默認虛擬主機虛擬主機,實現一臺服務器運行多個域名,多個網站;設置兩個域名網站abc.com和111.com,並創建網站首頁;測試網站#curl -x 192.16

從零開始寫linux字元裝置驅動程式(一)(基於友善臂tiny4412開發板)

從這篇博文開始,我將開始手把手教會大家寫linux裝置驅動程式這是開篇,如何來寫第一個字元裝置驅動程式。首先,寫一個最簡單的字元裝置驅動程式需要什麼?或者說我們需要了解什麼?1、每一個字元裝置至少需要有一個裝置號2、裝置號 = 主裝置號 + 次裝置號3、同一類裝置的主裝置號一

16章 驅動開發字元裝置驅動程式框架

16.1 字元裝置驅動程式框架簡介 我們在學習 C 語言的時候,知道每個應用程式的入口函式,即第一個被執行的函式是 main函式,那麼,我們自己的驅動程式,哪個函式是入口函式呢? 在寫驅動程式的時候,如果函式的名字可以任意取,常常為 xxxx_init(),

linux字元裝置驅動程式scull例項

這個例子還是比較完整的講述了字元驅動開發的過程,尤其字元驅動程式的設計流程,包括測試在內。 【1.系統環境】 該驅動程式在UBUNTU10.04LTS編譯通過,系統核心為linux-2.6.32-24(可使用uname -r 命令來檢視當前核心的版本號) 由於安裝UBUNTU10.04LTS時,沒有安裝LI

字元裝置驅動程式——按鍵中斷互斥阻塞操作

一、互斥操作 在程式設計中,引入了物件互斥鎖的概念,來保證共享資料操作的完整性。每個物件都對應於一個可稱為" 互斥鎖" 的標記,這個標記用來保證在任一時刻,只能有一個執行緒訪問該物件。 實現方式 原子操作 原子操作指的是在執行過程中不會被別的程式碼路徑所中斷的操作。 常用

字元裝置驅動程式——按鍵中斷非同步通知

一、驅動程式的實現 1、定義static struct fasync_struct *newdrv_async; 2、加入 static struct file_operations new_drv_fops = { .fasync =new_drv_fasync, }; static

WIN7重灌系統缺少所需的CD/DVD驅動器裝置驅動程式

相信大家遇到的問題都是:載入驅動程式:      缺少所需的CD/DVD驅動器裝置驅動程式。原因:使用的U盤為高於USB2.0版本的解決方法:1.使用usb2.0介面的U盤重新制作啟動盤;2.為3.0U盤裝入USB3.0驅動,步驟如下:第一步:首先製作好啟動盤第二步:隨後在h

Linux字元裝置驅動程式的一個簡單示例

一.原始碼: // memdev.c #define MEMDEV_MAJOR 254 /*預設的mem的主裝置號*/ #define MEMDEV_NR_DEVS 2 /*裝置數*/ #define MEMDEV_SIZE 4096 /*mem裝置描述結構體

字元裝置驅動同步互斥阻塞

先了解幾個概念:臨界資源:一次只允許一個執行單元使用的資源稱為臨界資源。比如多臺電腦都可以使用同一臺印表機,但是,一個時刻只能有一臺電腦來控制他進行列印,所以印表機在這裡就是臨界資源。臨界區:訪問共享資源的程式碼區域。就是執行單元訪問共享資源的那段程式碼就對啦。併發:就是幾

東山091 u-boot分析編譯體驗“學習筆記

Windows系統啟動過程,PC上電 => 進入BIOS(引導作業系統)=> windows => 識別C,D等的硬碟 => 執行應用程式 嵌入式系統啟動過程,上電 => bootloader(引導核心)=> LINUX => 掛

嵌入式Linux學習七步曲三篇 Linux系統bootlaoder移植】全面解析PowerPC架構下的扁平裝置樹FDT

全面解析PowerPC架構下的扁平裝置樹FDT Sailor_forever  sailing_9806#163.com (本原創文章發表於Sailor_forever 的個人blog,未經本人許可,不得用於商業用途。任何個人、媒體、其他網站不得私自抄襲;網路媒體轉載請