嵌入式按鍵驅動 支援短按 長按 雙擊 中斷方式

2021-07-25 07:18:26 字數 2894 閱讀 9147

概述:

1:本篇利用按鍵中斷輸入方式,當按鍵觸發,中斷處理函式置按鍵掃瞄標誌位為1,開始按鍵鍵值掃瞄,完成後,主程式根據鍵值(短按、長按、雙擊),完成相應的動作;

2:當k1按鍵短按:led1閃爍;當k1按鍵長按,led2閃爍;當k1按鍵雙擊,led3閃爍;

3:優點:相比於輪詢掃瞄按鍵鍵值的方式,按鍵響應速度更快,節約cpu資源;

4:參考資料:stm32中文參考手冊(exit的有關說明)、cortex-m3權威指南(nvic的有關說明)

5:開發板:stm32f103zert 奮鬥開發板v5 開發環境:keil mdk5

stm32外部中斷配置

1: 設定中斷分組

設定中斷優先順序之前,一定要設定中斷分組,本**中有sysclk中斷和按鍵外部中斷,設定中斷中斷分組為2,2位主優先順序和2位次優先順序,需設定內部sysclk中斷的優先順序高於按鍵中斷的優先順序,內部中斷使用nvic_setpriority()函式設定,具體函式參考core_cm3.h檔案,外部中斷優先順序在nvic_init()函式中設定;

2:完成外部中斷線路對映

使用gpio_extilineconfig()函式完成中斷線路的對映;

3:nvic暫存器初始化

完成對應中斷的使能和優先順序設定,使用nvic_init()庫函式完成初始化。注意:一定要給nvic_initstructure結構體的成員賦值,因為nvic_inittypedef結構體是在函式內部定義的,並且沒有賦初值,如果不設定的話,結構體中的成員使用編譯器預設的初值,有可能會出現錯誤,因為中斷優先順序很重要,如果按鍵中斷的優先順序高於sysclk中斷,按鍵處理函式中的按鍵防抖會死迴圈,具體見下面程式;

4:exit暫存器初始化

使能響應的外部中斷,並且設定中斷的觸發方式,使用exti_init()函式完成初始化;

5:程式進行了2次防抖,一次是在按鍵中斷處理函式中,一次是在主程式按鍵掃瞄中;

#include "stm32f10x.h"

#include "key_board.h"

#include "rcc_driver.h"

#include "led_driver.h"

#include "sysclk_driver.h"

volatile

unsigned 

intled_flash_timing = 0;  

volatile

unsigned 

intget_keyvalue_timing = 0;  

bool

led1_flag = 0;  

bool

led2_flag = 0;  

bool

led3_flag = 0;  

unsigned char

i = 0;  

intmain()  

if(led_flash_timing > 150)  

else

}  else

led3_off;  

if(led2_flash_flag == 1)    

//led2閃爍

else

}  else

led2_off;  

if(led1_flash_flag==1) 

//led1閃爍

else

}  else

led1_off;  

}  }  

}  key_board.c

[cpp]view plain

copy

#include "key_board.h"

volatile

unsigned 

intdelay_timing = 0;  

/*記錄按鍵按下時間 時間小於1.5s,按鍵為短按;時間大於1.5s,按鍵為長按*/

volatile

unsigned 

intkey1_timing = 0;  

/*記錄兩次短按之間的時間間隔*/

volatile

unsigned 

intkey1_doublepress_timing = 0;  

/*定義按鍵鍵值結構體*/

key_value k1_value;  

/*k1按鍵短按標誌位*/

bool

///*k1按鍵長按標誌位*/

/*k1按鍵雙擊標誌位*/

bool

/*led1閃爍時間標誌位,主函式檢測到此標誌位為1時,led1開始閃爍,否則,結束閃爍*/

bool

led1_flash_flag = 0;  

/*3個led全部閃爍標誌位,主函式檢測到此標誌為1時,三個led燈開始同時閃爍,否則結束閃爍*/

bool

led2_flash_flag = 0;  

/*流水燈事件標誌位*/

bool

led3_flash_flag = 0;  

/*獲取鍵值標誌*/

volatile

bool

get_keyvalue_flag = 0;  

/*按鍵初始化

*k1=gpioc5 設定gpioc5為上拉輸入

*/void

key_init(

void

)  {  

exti_inittypedef   exti_initstructure;  

nvic_inittypedef   nvic_initstructure;  

/*按鍵對應gpio口初始化*/

gpio_inittypedef gpio_initstruct;  

gpio_initstruct.gpio_mode = gpio_mode_ipu;  

gpio_initstruct.gpio_pin  = gpio_pin_5;  

嵌入式linux之按鍵驅動程式

1.寫出框架 2.硬體操作 操作虛擬位址ioremap 1.重要函式 trap init init irq asm do irq中斷總入口 分辨中斷,處理中斷,清中斷。讀一下wait event interruptible 的原始碼,不難發現這個函式先將 當前程序的狀態設定成task interru...

嵌入式 按鍵燈控制

實驗結果 按左鍵led燈向左亮,按右鍵led燈向右亮 void irq int int void 宣告中斷服務函式 int flag 0 定義乙個標誌位 void led y void 小燈自左向右依次亮滅 void led z void 小燈自右向左依次亮滅 void led m void 中斷程...

嵌入式linux IIC驅動

linux驅動和裝置隔離,驅動分層,iic驅動框架分為兩部分 1.1 iic匯流排驅動 platform是虛擬匯流排,針對沒有匯流排的裝置實現,匯流排 裝置 驅動框架,iic不用虛擬,可直接用匯流排bus。iic匯流排驅動有兩個重要資料結構 i2c adapter,i2c algorithm。i2c...