日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

PIC单片机 按键检测识别

發布時間:2025/4/5 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 PIC单片机 按键检测识别 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

目錄

      • 按鍵和PIC單片機
        • 一、按鍵
        • 二、按鍵的物理連接與檢測
        • 三、PIC16F18854單片機
      • 按鍵檢測及顯示實驗
          • 按鍵排布
          • 預期效果
          • 總體流程
          • 中斷服務程序
          • PIC匯編程序

按鍵和PIC單片機

一、按鍵

按鍵是嵌入式系統基本的人機交互手段,其使用步驟包括:檢測連通、消抖、行為判斷

?

二、按鍵的物理連接與檢測

簡單按鍵

缺點:占用端口引腳太多,一個按鍵就占一個引腳。

?

行列掃描按鍵

  • 行為input,列為output

  • 每個列依次接地,同時其他列高阻態(建議不用邏輯1,防止短路),觀察哪一/些行為0,就能鎖定到被按下的按鍵

  • 有多個按鍵同時被按下時,程序可能會錯誤判斷按鍵,不可信

  • 上面這種對比簡單按鍵并沒有優勢,還是太占用引腳

  • ?

    行列掃描的擴展

  • 二極管限制了電流的流向,通過控制兩個引腳的輸入輸出方向來判斷不同按鍵。
  • 但是因為每個按鍵都加入了一個二極管,成本增加且占用面積。
  • ?

    全掃描

    行列之間兩兩一個,行行、列列間也是兩兩一個。

    ?

    簡單按鍵+全掃描

    要求7~10與1~6不能同時檢測,因為兩組之間彼此干擾。因此必須先檢測7~中有沒有按下,沒有的話再檢測1~6。檢測到有一個按下后就結束,不能檢測多個同時按下的情況,不準確。

    ?

    ?

    三、PIC16F18854單片機

    按鍵檢測及顯示實驗

    按鍵排布

    ??簡單按鍵+全掃描,四根線對應連接到PIC單片機的4個引腳,最后一根接地。

    ?

    預期效果

    ??4位數碼管顯示按鍵編號、行為、按動次數

    ?

    總體流程

    ??數碼管片選與段選各自維護一個查找表,在主程序中循環對數碼管進行片選、段選、延時,其中段選時按照顯示緩沖區內容執行。定時器中斷周期設置為5ms,中斷服務程序提供:連通檢測、消抖、狀態轉換、顯示驅動服務。其中關鍵部分是中斷服務程序的設計。

    ?

    ?

    中斷服務程序

    ??中斷服務程序分為4個模塊,模塊間充分解耦,其間只有個別變量在整個流程中進行傳遞,其他大部分變量都是各個模塊自身的局部變量。

    ?

    1、連通檢測

    step1:單片機4個引腳弱上拉,依次檢查4個引腳有無0電平,即7~10號按鍵有無按下,若無則進入step2。

    step2:4個引腳兩兩間有6個按鍵,依次檢測一遍,若只有1對為連通則說明僅一個按鍵按下,若有多對連通則為多按鍵被按下。

    最后將檢測到的連通狀態cur_key傳入消抖模塊。

    代碼流程圖:

    ?

    2、消抖模塊

    ??檢測連通檢測模塊傳入的cur_key與上次傳入的是否相同,若連著兩次相同則認為不是抖動,繼續傳入狀態轉換模塊;若不同,則認為是抖動造成的,把上次的key傳入狀態轉換模塊。本質是要求同一按鍵連按10ms才認為是按下而不是抖動。

    代碼流程圖:

    ?

    3、狀態轉換

    ??狀態轉換模塊功能是,根據消抖模塊傳入的cur_key來改變當前狀態tatus,并且把相對應事件event和cur_key一起傳入給后面的顯示驅動模塊。“輸入——狀態改變——輸出”的運行邏輯正是一個狀態機。

    state\actionMULTIKEYUPTIMEOUTSAMEOTHER
    CLICKinit(single)waitpress(press)clickinit(single)
    WAITinit(single)waitinit(single)double(double)click(single)
    PRESSinit(press_up)init(press_up)-same(press)init(press_up)
    INITinitinit-clickclick
    DOUBLEinitinit-doubleinit

    代碼流程圖:

    ?

    4、顯示驅動

    ??根據狀態轉換模塊傳來的event和cur_key調制主程序段選時使用的顯示緩存區,從而在數碼管顯示按鍵狀態和相應信息。

    代碼流程圖:

    ?

    ?

    PIC匯編程序
    #include <xc.inc>psect intentry, class=CODE, delta=2psect reset_vec, class=CODE, delta=2psect eeprom_data,class=EEDATA,delta=2,space=3,noexecpsect powerup, class=CODE, delta=2psect cinit,class=CODE,delta=2psect functab,class=ENTRY,delta=2psect idloc,class=IDLOC,delta=2,noexecglobal _main, reset_vecpsect config, class=CONFIG, delta=2 #ifndef BOOTLOADERdw 0xDFECdw 0xF7FFdw 0xFFBFdw 0xEFFEdw 0xFFFF #endifpsect reset_vec reset_vec:ljmp _main;GLOBAL VARIABLESpsect CommonVar, class=COMMON, space=1, delta=1 ;main dis_cache: ds 4 delay1: ds 1 delay2: ds 1 ;debounce last_result: ds 1 count: ds 1 ;status_trans action: ds 1 state: ds 1 event: ds 1 wait_count: ds 1 click_count: ds 1 last_key: ds 1 ;connection_check index: ds 1 ;global cur_key: ds 1psect udata i: ds 1 j: ds 1 led_select: ds 1 workplace2: ds 1 dis_last_key: ds 1 dis_count: ds 2 swap: ds 1 press_count:ds 1;STATIC TABLEpsect Table, class=CODE, delta=2 event_table: MOVWF PCL IRP event,1,0,3,0,1,1,0,1,2,1,4,4,0,3,4RETLW event ENDMaction_table: MOVWF PCL IRP row_click,0b1111,0b101,0b1010,0b0,0b1111RETLW row_click ENDM IRP row_wait,0b1111,0b101,0b1111,0b10100,0b0RETLW row_wait ENDM IRP row_press,0b1111,0b1111,0xff,0b1010,0b1111RETLW row_press ENDM IRP row_init,0b1111,0b1111,0xff,0b0,0b0RETLW row_init ENDM IRP row_double,0b1111,0b1111,0xff,0b10100,0b1111RETLW row_double ENDMseq_table:ADDWF PCL,f IRP seq_num,0b00111111,0b00000110,0b01011011,0b01001111,0b01100110,0b01101101,0b01111101,0b00000111,0b01111111,0b01101111,0b01110111RETLW seq_num ENDMcode_table:MOVWF PCL IRP code_num,0b00000111,0b00001011,0b00001101,0b00001110RETLW code_num ENDMkey_table: ADDWF PCL,F IRP key_num,5,1,2,3,4,6RETLW key_num ENDM;INTERRUPT SERVICEpsect intentry intentry:;clear the signal bitBANKSEL PIR0BCF PIR0,5;init the TMR0 offsetBANKSEL TMR0L;MOCLW 0xfec0cMOVLW 0xecMOVWF TMR0HMOVLW 0x78MOVWF TMR0Lconnection_check:CLRF cur_keyBANKSEL iMOVLW 1MOVWF iCLRF indexBANKSEL TRISBMOVLW 0x0fMOVWF TRISBBANKSEL WPUBMOVLW 0x0fMOVWF WPUB jedge_i_16:BANKSEL iBTFSS i,4GOTO i_unequ_16GOTO i_equ_16i_unequ_16:BANKSEL iMOVF i, WBANKSEL PORTBANDWF PORTB, WBANKSEL workplace2MOVWF workplace2MOVF workplace2,fBTFSS STATUS,2 GOTO branch1_portb_unequ_0GOTO branch1_portb_equ_0i_equ_16:MOVF cur_key, fBTFSS STATUS,2GOTO trunk_curkey_unequ_0GOTO trunk_curkey_equ_0branch1_portb_equ_0:MOVF cur_key,fBTFSS STATUS,2GOTO branch1_curkey_unequ_0GOTO branch1_curkey_equ_0branch1_portb_unequ_0:BANKSEL iLSLF i, fINCF index,fGOTO jedge_i_16branch1_curkey_unequ_0:MOVLW 255MOVWF cur_keyGOTO trunk_curkey_unequ_0branch1_curkey_equ_0:MOVLW 7ADDWF index, WMOVWF cur_keyGOTO branch1_portb_unequ_0trunk_curkey_unequ_0:GOTO debouncetrunk_curkey_equ_0:BANKSEL iMOVLW 1MOVWF iMOVLW 2MOVWF jCLRF index jedge_i_8:BTFSS i, 3GOTO i_unequ_8GOTO i_equ_8i_unequ_8:MOVF j, wBTFSS j, 4GOTO j_unequ_16GOTO j_equ_16i_equ_8:GOTO trunk_curkey_unequ_0j_unequ_16:BANKSEL jCOMF j, WBANKSEL TRISBMOVWF TRISBBANKSEL WPUBMOVWF WPUBBANKSEL PORTBMOVWF PORTBBANKSEL iMOVF i, WBANKSEL PORTBANDWF PORTB, WBANKSEL workplace2MOVWF workplace2MOVF workplace2,FBTFSS STATUS,2 GOTO branch2_portb_unequ_0GOTO branch2_portb_equ_0j_equ_16:BANKSEL iLSLF i, fLSLF i, WMOVWF jGOTO jedge_i_8branch2_portb_equ_0:MOVF cur_key,F BTFSS STATUS,2 GOTO branch2_curkey_unequ_0GOTO branch2_curkey_equ_0branch2_portb_unequ_0:LSLF j, fINCF index, fGOTO i_unequ_8branch2_curkey_equ_0:;cur_key = key_table[index]MOVLW HIGH(key_table)MOVWF PCLATH MOVF index,WCALL key_tableMOVWF cur_keyGOTO j_equ_16branch2_curkey_unequ_0:MOVLW 255MOVWF cur_keyGOTO i_equ_8debounce:MOVF last_result, WXORWF cur_key, WBTFSC STATUS, 2GOTO deb_continue ;no shakeINCF count ;shakeMOVLW 2XORWF count, WBTFSS STATUS, 2GOTO deb_ignore ;not equMOVF cur_key, W;equMOVWF last_resultGOTO deb_continuedeb_ignore:MOVF last_result, WMOVWF cur_keyGOTO transferdeb_continue:CLRF countGOTO transfertransfer: ;key valueMULTI EQU 0xFFNOKEY EQU 0 ;action indexMULTIKEY EQU 0UP EQU 1TIMEOUT EQU 2SAME EQU 3OTHER EQU 4 ;state valueCLICK EQU 0WAIT EQU 5PRESS EQU 10INIT EQU 15DOUBLE EQU 20 ;constUPCOUNT EQU 60PRESSCOUNT EQU 100PRESSADD EQU 100 trans_judge_action:MOVLW MULTIXORWF cur_key, wBTFSC STATUS, 2GOTO action_multi ;multiMOVLW NOKEY ;continueXORWF cur_key, wBTFSC STATUS, 2GOTO action_up_timeout ;upMOVF last_key, w ;downXORWF cur_key, wBTFSC STATUS, 2GOTO action_same_timeout ;sameGOTO action_other ;other ; action_multi:MOVLW MULTIKEYGOTO do_transfer action_up_timeout:MOVLW WAITXORWF state, wBTFSS STATUS, 2GOTO action_up ;not waitINCF wait_count ;waitingMOVLW UPCOUNTXORWF wait_count, wBTFSS STATUS, 2GOTO action_upGOTO action_timeoutaction_up:MOVLW UPGOTO do_transfer action_same_timeout:MOVLW CLICKXORWF state, wBTFSS STATUS, 2GOTO action_sameINCF click_countMOVLW PRESSCOUNTXORWF click_count, wBTFSS STATUS, 2GOTO action_sameGOTO action_timeout action_same:MOVLW SAMEGOTO do_transfer action_timeout:MOVLW TIMEOUTGOTO do_transfer action_other:MOVLW OTHERGOTO do_transferdo_transfer:MOVWF actionCLRF eventMOVF state, waddlw 1ADDWF action, fMOVLW INIT+1SUBWF action, wBTFSC STATUS, 0GOTO change_state ;no carry -> state+action+1>=INIT+1movlp high(event_table)MOVLW low(event_table)ADDWF action, wBTFSC STATUS, 0INCF PCLATHCALL event_table ;get next stateMOVWF event change_state:movlp high(action_table)MOVLW low(action_table)ADDWF action, wBTFSC STATUS, 0INCF PCLATHCALL action_table ;get next stateMOVWF stateclear_count_judge:MOVF event, fBTFSC STATUS, 2GOTO transfer_final ;event == 0clear_count:CLRF wait_countCLRF click_counttransfer_final:banksel swapMOVF last_key, wMOVWF swapMOVWF cur_key, wBTFSS STATUS, 2MOVWF last_keyMOVF swap, wMOVWF cur_keydisplay:MOVF event, fBTFSC STATUS, 2RETFIEbanksel dis_last_keyMOVF dis_last_key, WXORWF cur_key, WBTFSC STATUS, 2GOTO display_judge_event display_change:banksel dis_countCLRF dis_countCLRF dis_count+1MOVF cur_key, Wbanksel dis_last_keyMOVWF dis_last_key display_judge_event:banksel dis_countMOVLW 3SUBWF event, WBTFSS STATUS, 0GOTO event_1_2 ;if carry -> event<3MOVLW 3XORWF event, WBTFSC STATUS, 2GOTO event_3GOTO display_finalevent_1_2:MOVF event,WADDWF dis_count, FGOTO display_final event_3:INCF press_countMOVLW PRESSADDXORWF press_count, WBTFSC STATUS, 2GOTO event_3_add_countGOTO display_finalevent_3_add_count:INCF dis_countCLRF press_countdisplay_final:MOVF cur_key, WMOVWF dis_cacheMOVF event,WMOVWF dis_cache+1MOVLW 10SUBWF dis_count, WBTFSS STATUS, 0GOTO display_count ;if carry display_count_carry:INCF dis_count+1MOVLW 10SUBWF dis_count, FSUBWF dis_count+1, WBTFSC STATUS, 0CLRF dis_count+1 ;if no carry display_count:MOVF dis_count, WMOVWF dis_cache+3MOVF dis_count+1, WMOVWF dis_cache+2RETFIE;MAIN FUNCTION psect main,class=CODE,delta=2 ; PIC10/12/16 global _main _main:;Timer0 configuration BANKSEL T0CON0 MOVLW 0b00010000;set Timer0 in 16bit mode,post:1:8 MOVWF T0CON0 BANKSEL T0CON1 MOVLW 01000000;FOCS/4,synchronized to FOSC/4,pre:1:1 MOVWF T0CON1 BANKSEL TMR0L MOVLW 0xfe MOVWF TMR0H MOVLW 0x0c MOVWF TMR0L;init the TMR0 offset;interrupt configuration BANKSEL PIR0 BCF PIR0,5;clear the timer signal bit banksel INTCON BSF INTCON,0;INT enable BSF INTCON,7;global enable banksel PIE0 BSF PIE0,5;timer0_interrupt enable;start timing BANKSEL T0CON0 BSF T0CON0,7; enable Timer0;init PORTA / PORTB / PORTC BANKSEL PORTA CLRF PORTA ;Init PORTA BANKSEL LATA ;Data Latch CLRF LATA BANKSEL ANSELA CLRF ANSELA ;digital I/O BANKSEL TRISA CLRF TRISABANKSEL LATB ;Data Latch CLRF LATB BANKSEL ANSELB CLRF ANSELB ;digital I/OBANKSEL PORTC BANKSEL PORTC CLRF PORTC ;Init PORTC BANKSEL LATC ;Data Latch CLRF LATC BANKSEL ANSELC CLRF ANSELC ;digital I/O BANKSEL TRISC CLRF TRISC;init variables CLRF dis_cache CLRF dis_cache + 1 CLRF dis_cache + 2 CLRF dis_cache + 3 CLRF last_result CLRF count CLRF action MOVLW 15 MOVWF state CLRF wait_count CLRF click_count CLRF last_key CLRF index CLRF cur_key BANKSEL led_select CLRF led_select CLRF i CLRF j CLRF dis_last_key CLRF dis_count CLRF swap CLRF press_count CLRF workplace2;MAIN LOOP: ;code_sel MOVLW HIGH(code_table) MOVWF PCLATH MOVLW LOW(code_table) BANKSEL led_select ADDWF led_select, W BTFSS STATUS, 0 GOTO CALL_TABLE INCF PCLATH CALL_TABLE: ADDLW 1 CALL code_table BANKSEL PORTA MOVWF PORTA;seq_sel MOVLW HIGH(seq_table) MOVWF PCLATH ;w = dis_cache + offset MOVLW high(dis_cache) MOVWF FSR0H MOVLW low(dis_cache) BANKSEL led_select ADDWF led_select, w MOVWF FSR0L MOVF INDF0, w ;seq_table[dis_cache + offset] CALL seq_table MOVWF PORTC ;led_select = (led_select + 1) mod 4 BANKSEL led_select INCF led_select,f MOVLW 0b11 ANDWF led_select,f;delay MOVLW 2 MOVWF delay2 DELAY1: MOVLW 0xff MOVWF delay1 DECFSZ delay1,f GOTO $-1 DECFSZ delay2,f GOTO DELAY1;end seq_select CLRF PORTCGOTO LOOPend reset_vec

    總結

    以上是生活随笔為你收集整理的PIC单片机 按键检测识别的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 亚洲精品免费在线 | 超碰在线小说 | 久久久久成人片免费观看蜜芽 | 欧美六区 | 包射屋 | 蜜桃视频欧美 | 亚洲码无人客一区二区三区 | 国产女人在线观看 | 久久这里只有精品23 | 日本美女高潮 | 成人国产网站 | 美女91网站| 一级美女黄色片 | 午夜一区二区三区免费观看 | 伊人超碰在线 | 看a网站| 黄色一级播放 | 免费三片60分钟 | 亚洲精品久久久蜜桃 | 婷婷丁香九月 | 国产中文字幕一区二区 | 在线看片网址 | 91无套直看片红桃 | 麻豆av网 | 亚洲精品在线看 | 爱爱15p| 欧美 日韩 国产在线 | 欧美 日韩 国产 成人 在线 91 | 精品国产免费av | 亚洲成人aa | av啊啊 | 国产aⅴ爽av久久久久成人 | 欧美tv| 欲求不满在线小早川怜子 | 黄网址在线 | 花房姑娘免费全集 | 伊人国产在线视频 | 免费人妻精品一区二区三区 | 中文字幕精品一二三四五六七八 | 久久久久久综合网 | 禁断介护老人中文字幕 | 医生强烈淫药h调教小说视频 | 日韩精品在线观看免费 | 亚洲精品一区二区三 | 久久久久视 | 思思99re | 69色堂| 国产h视频在线 | 蜜臀视频在线播放 | 爱爱亚洲 | 国精品无码一区二区三区 | av漫画在线观看 | 成人性做爰aaa片免费看不忠 | 韩国主播青草200vip视频 | 三a大片 | 91九色pron| 久久久久久久久久网站 | 日韩最新 | 黑人巨大精品欧美一区二区蜜桃 | 日本不卡一二 | 国产免费一级视频 | 又污又黄又爽的网站 | 亚洲一区二区三区在线 | 国产一二三区精品 | 中文字幕a√ | 精品国产123 | 国产a∨精品一区二区三区仙踪林 | 91色视频在线| 国产欧美视频一区二区三区 | 一起操17c| 中国一区二区视频 | 久久国产精品区 | 久操免费在线视频 | 18xxxx日本| 男女激情网址 | 亚洲精品久久久中文字幕痴女 | 久久久久久草 | 看av网址| 苍井空亚洲精品aa片在线播放 | 国产真实乱 | 性爱免费在线视频 | 女性女同性aⅴ免费观女性恋 | 欧美综合自拍亚洲综合图片区 | 成年人在线视频免费观看 | 欧美另类高清videos的特点 | 欧美 亚洲 另类 激情 另类 | 国产剧情av在线播放 | 狠狠av | 亚洲伦理久久 | 午夜精品久久久久久久99热黄桃 | 亚洲五月花 | 人妻在线一区二区 | 蜜桃麻豆视频 | av老司机福利 | 日韩成人av在线 | 青青久在线 | 成人免费观看视频大全 | www.69视频| 色爽爽爽爽爽爽爽爽 |