需要用戶交互的嵌入式系統必須與接受用戶輸入的設備(如鍵盤、條形碼閱讀器或智能卡接受器)以及向用戶顯示信息的設備(如 LED 或 LCD 顯示屏)接口。本應用筆記使用MAXQ2000微控制器,介紹兩種典型器件的使用:4x4開關鍵盤和LCD顯示器。
概述
需要用戶交互的嵌入式系統必須與接受用戶輸入的設備(如鍵盤、條形碼閱讀器或智能卡接受器)以及向用戶顯示信息的設備(如 LED 或 LCD 顯示器)進行交互。本應用筆記介紹了兩種典型器件(4 x 4開關鍵盤和LCD顯示器)與MAXQ2000微控制器的使用。
本應用筆記的所有示例代碼均使用MAX-IDE開發環境,用MAXQ匯編語言編寫。該代碼針對MAXQ2000評估板(EV kit)板,使用以下附加硬件。
LCD—精電靜態3V液晶顯示器,部件號VI-502(包含在MAXQ2000評估板中)
鍵盤 - Grayhill 16 按鈕(4 行 x 4 列)鍵盤,部件號 96BB2-006-F
設計目標
我們的示例應用程序將通過接受來自鍵盤的輸入并顯示在LCD上輸入的字符來演示鍵盤和LCD顯示屏的基本用法。該應用程序將正確處理開關去抖動,以避免從單個按鍵注冊多個字符,并且它還允許在輸入后刪除字符。作為最后一項任務,鍵盤將支持LCD顯示屏的對比度調整。
與任何嵌入式設計一樣,應用應嘗試有效地利用MAXQ2000的資源。
中斷例程應使用盡可能少的堆棧空間。
工作寄存器的使用應保持在最低限度。
與 4x4 鍵盤接口
用于此示例應用程序的鍵盤由 16 個開關組成,這些開關組織在一個 4 x 4 網格中。(圖 1。
圖1.鍵盤開關布局。
這些開關以行和列矩陣連接在一起,如圖 2 所示。按下鍵盤開關將一行連接到一列線。例如,按下“3”鍵將第 1 行和第 3 列連接在一起。
圖2.鍵盤行/列矩陣。
鍵盤提供八個接口引腳,鍵盤矩陣的每一行和每列一個引腳。為了允許使用一根八連接器電纜從鍵盤連接到MAXQ2000評估板,通過評估板上的JU6接頭引腳連接器將鍵盤連接到端口引腳P5[0:7]和P1[0:2],如下表1所示。對于定制設計,鍵盤可以以最有效的方法連接到微控制器。
針 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
連接 | 第 1 行 | 第 2 行 | 第 3 行 | 第 4 行 | 科爾 1 | 科爾 2 | 科爾 3 | 科爾 4 |
端口銷 | P6.0 | P6.1 | P6.2 | P6.3 | P6.4 | P6.5 | P7.0 | P7.1 |
JU2 引腳 | 54 | 52 | 50 | 48 | 46 | 44 | 42 | 40 |
在本例中,將鍵盤連接到評估板時,應按如下方式配置電路板:
這些 DIP 開關必須關閉 — 所有 SW1 交換機、SW3.1、SW3.7、SW3.8、SW6.1、SW6.4、SW6.5、SW6.6、SW6.7 和 SW6.8。
打開跳線 JU5、JU6、JU8 和 JU9。
或者,在不進行修改的情況下運行示例應用程序時,可以關閉所有 DIP 開關以簡化設置;只有跳線 JU1、JU2、JU3 和 JU11 需要連接。
按列掃描
通過鍵盤的行和列排列,可以隨時讀取四個開關的狀態。這可以按每行或每列完成。
要在一列中讀取四個開關,必須將該列的行拉低,并將所有其他列三元組。接下來,必須在每行線上建立弱上拉。最后,將四行線連接到端口引腳輸入。默認為 HIGH 狀態時,當按下該行的開關時,行輸入將變為低電平。(圖 3。
圖3.鍵盤設置以讀取第 1 列開關。
類似地,可以通過將該行線拉低并在所有四列上設置輸入和弱上拉來讀取連續四個開關的狀態。行和列是可以互換的。
在我們的設置(表 2)中,四行線(鍵盤引腳 1 到 4)都連接到同一個輸入端口 (P6[3:0]),這使得一次讀取它們更容易。因此,示例應用程序將按列而不是按行掃描鍵盤。
連接到鍵盤的八個端口引腳線有四種設置狀態,每種狀態都允許讀取四個開關。當正在讀取的開關閉合時,所有輸入線都讀為低電平,當開關斷開時,所有輸入線都讀為高電平。
州 | P6.0 | P6.1 | P6.2 | P6.3 | P6.4 | P6.5 | P7.0 | P7.1 |
1 | 輸入 - 1 | 輸入 - 4 | 輸入 - 7 | 輸入-* | 低 | 三州 | 三州 | 三州 |
2 | 輸入 - 2 | 輸入 - 5 | 輸入 - 8 | 輸入 - 0 | 三州 | 低 | 三州 | 三州 |
3 | 輸入 - 3 | 輸入 - 6 | 輸入 - 9 | 輸入-# | 三州 | 三州 | 低 | 三州 |
4 | 輸入 - A | 輸入 - B | 輸入 - C | 輸入 - D | 三州 | 三州 | 三州 | 低 |
中斷驅動的狀態機
為了確保不會錯過按鍵,必須快速發送四列。此外,為了防止開關的彈跳觸點注冊多次按下,應用程序要求在注冊之前按住某個鍵一定時間。這兩個問題都可以同時解決,方法是將定時器驅動的中斷例程作為應用程序的核心。
RELOAD equ 0FF00h StartTimer: move IIR.3, #1 ; Enable interrupts for module 3 move IMR.3, #1 move T2V0, #RELOAD move T2R0, #0h move T2C0, #0h move Acc, T2CFG0 ; Set timer 0 to run from HFClk/128 and #08Fh or #070h move T2CFG0, Acc move T2CNA0.3, #1 ; Start timer 0 move T2CNA0.7, #1 ; Enable timer 0 interrupts ret
計時器的重新加載值(控制中斷觸發的頻率)應足夠短,以便捕獲所有按鍵,并且按鍵響應不會明顯緩慢。重新加載值也應該足夠長,以免占用過多的處理時間。上面顯示的值 0FF00h(大約每 2.4 毫秒一次)是通過實驗得出的。
一旦一組四個開關的柱線被驅動為低電平,則可能需要一定的時間才能通過按下的開關進行連接,以將其輸入線拉低。這個時間將受到開關的導通電阻以及一次按下柱上多少個開關的影響。為了避免在將柱線拉低和讀取四個開關之間延遲中斷服務例程,給定狀態的柱線將在前一種狀態下被驅動為低電平,如圖4所示。
圖4.鍵盤讀取狀態機。
由于MAXQ2000的中斷向量(IV)可以即時設置,因此可以將每個狀態的處理程序例程設置為下一個狀態的處理程序例程,從而將下一個狀態值保存在中斷向量寄存器中。
org 0000h Main: call InitializeLCD move PD6, #010h ; For state 1 move PO6, #00Fh ; For all states move PD7, #000h ; For state 1 move PO7, #000h ; For all states move IV, #State1 call StartTimer move IC, #1 ; Enable global interrupts jump $ State1: push PSF push Acc move Acc, PI6 and #000Fh ; Grab lowest four bits only sla4 move A[13], Acc move PD6, #020h ; For state 2 move PD7, #000h move T2V0, #RELOAD ; Set reload value move T2CNB0.1, #0 ; Clear interrupt flags move T2CNB0.3, #0 move IV, #State2 pop Acc pop PSF reti
其他四種狀態的處理程序例程類似,只是在 A[13] 保持寄存器中先前收集的開關位中略微調整為 OR。狀態例程使用三個工作累加器。
A[13] 保存通過鍵盤的電流傳遞上讀取的所有開關狀態的位數組。狀態 4 讀取完成后,此寄存器將包含以下位,其中 1 位表示打開(釋放)鍵開關,0 位表示關閉(按下)鍵開關。
位 15 | 位 14 | 位 13 | 位 12 | 位 11 | 位 10 | 位 9 | 位 8 | 位 7 | 位 6 | 位 5 | 位 4 | 位 3 | 位 2 | 位 1 | 位 0 |
* | 7 | 4 | 1 | 2 | 5 | 8 | 0 | 3 | 6 | 9 | # | D | C | B | 一個 |
<
A[14] 保存上一次通過狀態機的位數組。這由去抖代碼使用。
A[15] 保存最后一個位模式,該模式保持的時間足夠長,可以注冊為按鍵。這用于防止重復按鍵。
去抖動開關
達到狀態 4 并掃描所有鍵后,必須決定是否接受按下的任何鍵。
處理去抖動的一種簡單方法是為 4 個開關中的每一個保持一個計數器值。每次達到狀態 <> 并按下該鍵時,計數器都會遞增。如果未按下該鍵,計數器將遞減。當計數器達到某個值時,將注冊按鍵。為了防止按住鍵重復(通常在計算機鍵盤上允許,但在小鍵盤上不允許),必須允許計數器遞減到零(通過釋放鍵),然后才能再次注冊該鍵。
因為我們在單個寄存器中擁有所有 16 個鍵的狀態,所以有一個更簡單、內存占用更少的解決方案。應用程序將維護單個計數器值(保存在 LC[0] 中),該值最初將設置為去抖動常數。每次位模式與前一次傳遞中讀取的模式匹配時,此計數器都會遞減(在 A[14] 中)。
State4: push PSF push Acc move Acc, PI6 and #000Fh ; Grab low four bits only or A[13] cmp A[15] jump E, State4_End ; Ignore the last debounced pattern cmp A[14] jump E, State4_Match ; Match against pattern from last keypad read move LC[0], #DEBOUNCE move A[14], Acc ; Reset current bit array
為了防止鍵重復,一旦位模式靜態足夠長,就可以接受,必須先接受不同的位模式(包括未按下任何鍵的空閑狀態),然后才能再次接受第一個位模式。
處理同時按鍵
可以同時按下多個鍵。去抖動代碼將確保如果在第一個鍵之后立即按下第二個鍵,則去抖動間隔將重新開始,但間隔在實踐中會足夠短,這不會成為問題。
一旦接受了位模式,就可以將所有 16 位旋轉到進位中,一次使用累加器一個并依次檢查每個位,從而對每個按下鍵位執行操作。下面的代碼僅響應第一個按下的鍵,但這可以很容易地更改。
State4_Match: djnz LC[0], State4_End move A[15], Acc ; Reset last debounced pattern rrc jump NC, State4_KeyA rrc jump NC, State4_KeyB rrc jump NC, State4_KeyC rrc jump NC, State4_KeyD rrc jump NC, State4_Key3 rrc jump NC, State4_Key6 rrc jump NC, State4_Key9 rrc jump NC, State4_KeyPound rrc jump NC, State4_Key2 rrc jump NC, State4_Key5 rrc jump NC, State4_Key8 rrc jump NC, State4_Key0 rrc jump NC, State4_Key1 rrc jump NC, State4_Key4 rrc jump NC, State4_Key7 rrc jump NC, State4_KeyStar jump State4_End
與液晶顯示器接口
MAXQ2000評估板附帶的LCD顯示器具有如圖5所示的段定義。
圖5.液晶屏段內存映射。
要使用 LCD 顯示屏,必須首先將 LCD 控制器初始化為靜態驅動模式并啟用。
InitializeLCD: move LCRA, #03E0h ; xxx0001111100000 ; 00 - DUTY : Static ; 0111 - FRM : Frame freq ; 1 - LCCS : HFClk / 128 ; 1 - LRIG : Ground VADJ ; 00000 - LRA : RADJ = max move LCFG, #0F3h ; 1111xx11 ; 1111 - PCF : All segments enabled ; 1 - OPM : Normal operation ; 1 - DPE : Display enabled move LCD0, #00h ; Clear all segments move LCD1, #00h move LCD2, #00h move LCD3, #00h move LCD4, #00h ret
完成此操作后,可以通過適當設置段將字符寫入顯示器。顯示器連接到MAXQ2000的LCD段線,使得7個5段字符的段映射到存儲器中。如上面的映射圖(圖0)所示,通過設置LCD1、LCD2、LCD3和LCD<>顯示存儲器寄存器來寫入字符(從右到左)。
; dGFEDCBA LCD_CHAR_0 equ 00111111b LCD_CHAR_1 equ 00000110b LCD_CHAR_2 equ 01011011b LCD_CHAR_3 equ 01001111b LCD_CHAR_4 equ 01100110b LCD_CHAR_5 equ 01101101b LCD_CHAR_6 equ 01111101b LCD_CHAR_7 equ 00000111b LCD_CHAR_8 equ 01111111b LCD_CHAR_9 equ 01101111b LCD_CHAR_A equ 01110111b LCD_CHAR_B equ 01111100b LCD_CHAR_C equ 00111001b LCD_CHAR_D equ 01011110b State4_Key0: move Acc, #LCD_CHAR_0 jump State4_Shift State4_Key1: move Acc, #LCD_CHAR_1 jump State4_Shift State4_Key2: move Acc, #LCD_CHAR_2 jump State4_Shift State4_Key3: move Acc, #LCD_CHAR_3 jump State4_Shift State4_Key4: move Acc, #LCD_CHAR_4 jump State4_Shift State4_Key5: move Acc, #LCD_CHAR_5 jump State4_Shift State4_Key6: move Acc, #LCD_CHAR_6 jump State4_Shift State4_Key7: move Acc, #LCD_CHAR_7 jump State4_Shift State4_Key8: move Acc, #LCD_CHAR_8 jump State4_Shift State4_Key9: move Acc, #LCD_CHAR_9 jump State4_Shift State4_KeyA: move Acc, #LCD_CHAR_A jump State4_Shift State4_KeyB: move Acc, #LCD_CHAR_B jump State4_Shift State4_KeyC: move Acc, #LCD_CHAR_C jump State4_Shift State4_KeyD: move Acc, #LCD_CHAR_D jump State4_Shift
編輯密碼
當按下任何字母數字鍵時,相應的字符將加載到LCD顯示屏最右側的字符中。所有現有字符都向左移動一個位置。
State4_KeyStar: move LCD0, LCD1 move LCD1, LCD2 move LCD2, LCD3 move LCD3, #0 jump State4_End State4_Shift: move LCD3, LCD2 move LCD2, LCD1 move LCD1, LCD0 move LCD0, Acc State4_End: move PD6, #010h ; Set up values for next state move PD7, #000h move T2V0, #RELOAD ; Set reload value move T2CNB0.1, #0 ; Clear interrupt flags move T2CNB0.3, #0 move IV, #State1 pop Acc pop PSF reti
在此應用程序中,“star”鍵連接到刪除/退格功能。按星號鍵會將所有字符向右移動一個位置,并從顯示屏上擦除最左側的字符。
對比度調整
井號鍵執行一項附加功能以用于演示目的。按下它可以調整LCD顯示屏的對比度,這是一項通過增加LCRA寄存器中的RADJ位來執行的簡單功能。
State4_KeyPound: move Acc, LCRA or #0FFE0h ; clear low five bits move A[13], Acc ; save version with bits cleared move Acc, LCRA and #0001Fh ; get low five bits only add #1 ; increment and #0001Fh ; mask out any carry to sixth bit or A[13] ; OR in the rest of the bits move LCRA, Acc ; change contrast jump State4_End
結論
MAXQ2000通過專用的LCD控制器外設輕松直接地與LCD顯示器接口。使用MAXQ2000提供的靈活端口引腳配置,可以直接讀取多路復用鍵盤。中斷驅動的狀態機允許在主應用程序的后臺掃描和去抖動矩陣中的所有鍵,而對處理器開銷的影響最小。
審核編輯:郭婷
-
微控制器
+關注
關注
48文章
7649瀏覽量
152103 -
控制器
+關注
關注
112文章
16445瀏覽量
179438 -
嵌入式
+關注
關注
5092文章
19177瀏覽量
307647
發布評論請先 登錄
相關推薦
評論