需要用戶交互的嵌入式系統(tǒng)必須與接受用戶輸入的設(shè)備(如鍵盤、條形碼閱讀器或智能卡接受器)以及向用戶顯示信息的設(shè)備(如 LED 或 LCD 顯示屏)接口。本應(yīng)用筆記使用MAXQ2000微控制器,介紹兩種典型器件的使用:4x4開關(guān)鍵盤和LCD顯示器。
概述
需要用戶交互的嵌入式系統(tǒng)必須與接受用戶輸入的設(shè)備(如鍵盤、條形碼閱讀器或智能卡接受器)以及向用戶顯示信息的設(shè)備(如 LED 或 LCD 顯示器)進(jìn)行交互。本應(yīng)用筆記介紹了兩種典型器件(4 x 4開關(guān)鍵盤和LCD顯示器)與MAXQ2000微控制器的使用。
本應(yīng)用筆記的所有示例代碼均使用MAX-IDE開發(fā)環(huán)境,用MAXQ匯編語言編寫。該代碼針對(duì)MAXQ2000評(píng)估板(EV kit)板,使用以下附加硬件。
LCD—精電靜態(tài)3V液晶顯示器,部件號(hào)VI-502(包含在MAXQ2000評(píng)估板中)
鍵盤 - Grayhill 16 按鈕(4 行 x 4 列)鍵盤,部件號(hào) 96BB2-006-F
設(shè)計(jì)目標(biāo)
我們的示例應(yīng)用程序?qū)⑼ㄟ^接受來自鍵盤的輸入并顯示在LCD上輸入的字符來演示鍵盤和LCD顯示屏的基本用法。該應(yīng)用程序?qū)⒄_處理開關(guān)去抖動(dòng),以避免從單個(gè)按鍵注冊(cè)多個(gè)字符,并且它還允許在輸入后刪除字符。作為最后一項(xiàng)任務(wù),鍵盤將支持LCD顯示屏的對(duì)比度調(diào)整。
與任何嵌入式設(shè)計(jì)一樣,應(yīng)用應(yīng)嘗試有效地利用MAXQ2000的資源。
中斷例程應(yīng)使用盡可能少的堆棧空間。
工作寄存器的使用應(yīng)保持在最低限度。
與 4x4 鍵盤接口
用于此示例應(yīng)用程序的鍵盤由 16 個(gè)開關(guān)組成,這些開關(guān)組織在一個(gè) 4 x 4 網(wǎng)格中。(圖 1。
圖1.鍵盤開關(guān)布局。
這些開關(guān)以行和列矩陣連接在一起,如圖 2 所示。按下鍵盤開關(guān)將一行連接到一列線。例如,按下“3”鍵將第 1 行和第 3 列連接在一起。
圖2.鍵盤行/列矩陣。
鍵盤提供八個(gè)接口引腳,鍵盤矩陣的每一行和每列一個(gè)引腳。為了允許使用一根八連接器電纜從鍵盤連接到MAXQ2000評(píng)估板,通過評(píng)估板上的JU6接頭引腳連接器將鍵盤連接到端口引腳P5[0:7]和P1[0:2],如下表1所示。對(duì)于定制設(shè)計(jì),鍵盤可以以最有效的方法連接到微控制器。
針 | 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 |
在本例中,將鍵盤連接到評(píng)估板時(shí),應(yīng)按如下方式配置電路板:
這些 DIP 開關(guān)必須關(guān)閉 — 所有 SW1 交換機(jī)、SW3.1、SW3.7、SW3.8、SW6.1、SW6.4、SW6.5、SW6.6、SW6.7 和 SW6.8。
打開跳線 JU5、JU6、JU8 和 JU9。
或者,在不進(jìn)行修改的情況下運(yùn)行示例應(yīng)用程序時(shí),可以關(guān)閉所有 DIP 開關(guān)以簡(jiǎn)化設(shè)置;只有跳線 JU1、JU2、JU3 和 JU11 需要連接。
按列掃描
通過鍵盤的行和列排列,可以隨時(shí)讀取四個(gè)開關(guān)的狀態(tài)。這可以按每行或每列完成。
要在一列中讀取四個(gè)開關(guān),必須將該列的行拉低,并將所有其他列三元組。接下來,必須在每行線上建立弱上拉。最后,將四行線連接到端口引腳輸入。默認(rèn)為 HIGH 狀態(tài)時(shí),當(dāng)按下該行的開關(guān)時(shí),行輸入將變?yōu)榈碗娖?。(圖 3。
圖3.鍵盤設(shè)置以讀取第 1 列開關(guān)。
類似地,可以通過將該行線拉低并在所有四列上設(shè)置輸入和弱上拉來讀取連續(xù)四個(gè)開關(guān)的狀態(tài)。行和列是可以互換的。
在我們的設(shè)置(表 2)中,四行線(鍵盤引腳 1 到 4)都連接到同一個(gè)輸入端口 (P6[3:0]),這使得一次讀取它們更容易。因此,示例應(yīng)用程序?qū)戳卸皇前葱袙呙桄I盤。
連接到鍵盤的八個(gè)端口引腳線有四種設(shè)置狀態(tài),每種狀態(tài)都允許讀取四個(gè)開關(guān)。當(dāng)正在讀取的開關(guān)閉合時(shí),所有輸入線都讀為低電平,當(dāng)開關(guān)斷開時(shí),所有輸入線都讀為高電平。
州 | 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 | 三州 | 三州 | 三州 | 低 |
中斷驅(qū)動(dòng)的狀態(tài)機(jī)
為了確保不會(huì)錯(cuò)過按鍵,必須快速發(fā)送四列。此外,為了防止開關(guān)的彈跳觸點(diǎn)注冊(cè)多次按下,應(yīng)用程序要求在注冊(cè)之前按住某個(gè)鍵一定時(shí)間。這兩個(gè)問題都可以同時(shí)解決,方法是將定時(shí)器驅(qū)動(dòng)的中斷例程作為應(yīng)用程序的核心。
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
計(jì)時(shí)器的重新加載值(控制中斷觸發(fā)的頻率)應(yīng)足夠短,以便捕獲所有按鍵,并且按鍵響應(yīng)不會(huì)明顯緩慢。重新加載值也應(yīng)該足夠長(zhǎng),以免占用過多的處理時(shí)間。上面顯示的值 0FF00h(大約每 2.4 毫秒一次)是通過實(shí)驗(yàn)得出的。
一旦一組四個(gè)開關(guān)的柱線被驅(qū)動(dòng)為低電平,則可能需要一定的時(shí)間才能通過按下的開關(guān)進(jìn)行連接,以將其輸入線拉低。這個(gè)時(shí)間將受到開關(guān)的導(dǎo)通電阻以及一次按下柱上多少個(gè)開關(guān)的影響。為了避免在將柱線拉低和讀取四個(gè)開關(guān)之間延遲中斷服務(wù)例程,給定狀態(tài)的柱線將在前一種狀態(tài)下被驅(qū)動(dòng)為低電平,如圖4所示。
圖4.鍵盤讀取狀態(tài)機(jī)。
由于MAXQ2000的中斷向量(IV)可以即時(shí)設(shè)置,因此可以將每個(gè)狀態(tài)的處理程序例程設(shè)置為下一個(gè)狀態(tài)的處理程序例程,從而將下一個(gè)狀態(tài)值保存在中斷向量寄存器中。
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
其他四種狀態(tài)的處理程序例程類似,只是在 A[13] 保持寄存器中先前收集的開關(guān)位中略微調(diào)整為 OR。狀態(tài)例程使用三個(gè)工作累加器。
A[13] 保存通過鍵盤的電流傳遞上讀取的所有開關(guān)狀態(tài)的位數(shù)組。狀態(tài) 4 讀取完成后,此寄存器將包含以下位,其中 1 位表示打開(釋放)鍵開關(guān),0 位表示關(guān)閉(按下)鍵開關(guān)。
位 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 | 一個(gè) |
<
A[14] 保存上一次通過狀態(tài)機(jī)的位數(shù)組。這由去抖代碼使用。
A[15] 保存最后一個(gè)位模式,該模式保持的時(shí)間足夠長(zhǎng),可以注冊(cè)為按鍵。這用于防止重復(fù)按鍵。
去抖動(dòng)開關(guān)
達(dá)到狀態(tài) 4 并掃描所有鍵后,必須決定是否接受按下的任何鍵。
處理去抖動(dòng)的一種簡(jiǎn)單方法是為 4 個(gè)開關(guān)中的每一個(gè)保持一個(gè)計(jì)數(shù)器值。每次達(dá)到狀態(tài) <> 并按下該鍵時(shí),計(jì)數(shù)器都會(huì)遞增。如果未按下該鍵,計(jì)數(shù)器將遞減。當(dāng)計(jì)數(shù)器達(dá)到某個(gè)值時(shí),將注冊(cè)按鍵。為了防止按住鍵重復(fù)(通常在計(jì)算機(jī)鍵盤上允許,但在小鍵盤上不允許),必須允許計(jì)數(shù)器遞減到零(通過釋放鍵),然后才能再次注冊(cè)該鍵。
因?yàn)槲覀冊(cè)趩蝹€(gè)寄存器中擁有所有 16 個(gè)鍵的狀態(tài),所以有一個(gè)更簡(jiǎn)單、內(nèi)存占用更少的解決方案。應(yīng)用程序?qū)⒕S護(hù)單個(gè)計(jì)數(shù)器值(保存在 LC[0] 中),該值最初將設(shè)置為去抖動(dòng)常數(shù)。每次位模式與前一次傳遞中讀取的模式匹配時(shí),此計(jì)數(shù)器都會(huì)遞減(在 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
為了防止鍵重復(fù),一旦位模式靜態(tài)足夠長(zhǎng),就可以接受,必須先接受不同的位模式(包括未按下任何鍵的空閑狀態(tài)),然后才能再次接受第一個(gè)位模式。
處理同時(shí)按鍵
可以同時(shí)按下多個(gè)鍵。去抖動(dòng)代碼將確保如果在第一個(gè)鍵之后立即按下第二個(gè)鍵,則去抖動(dòng)間隔將重新開始,但間隔在實(shí)踐中會(huì)足夠短,這不會(huì)成為問題。
一旦接受了位模式,就可以將所有 16 位旋轉(zhuǎn)到進(jìn)位中,一次使用累加器一個(gè)并依次檢查每個(gè)位,從而對(duì)每個(gè)按下鍵位執(zhí)行操作。下面的代碼僅響應(yīng)第一個(gè)按下的鍵,但這可以很容易地更改。
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評(píng)估板附帶的LCD顯示器具有如圖5所示的段定義。
圖5.液晶屏段內(nèi)存映射。
要使用 LCD 顯示屏,必須首先將 LCD 控制器初始化為靜態(tài)驅(qū)動(dòng)模式并啟用。
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
完成此操作后,可以通過適當(dāng)設(shè)置段將字符寫入顯示器。顯示器連接到MAXQ2000的LCD段線,使得7個(gè)5段字符的段映射到存儲(chǔ)器中。如上面的映射圖(圖0)所示,通過設(shè)置LCD1、LCD2、LCD3和LCD<>顯示存儲(chǔ)器寄存器來寫入字符(從右到左)。
; 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
編輯密碼
當(dāng)按下任何字母數(shù)字鍵時(shí),相應(yīng)的字符將加載到LCD顯示屏最右側(cè)的字符中。所有現(xiàn)有字符都向左移動(dòng)一個(gè)位置。
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
在此應(yīng)用程序中,“star”鍵連接到刪除/退格功能。按星號(hào)鍵會(huì)將所有字符向右移動(dòng)一個(gè)位置,并從顯示屏上擦除最左側(cè)的字符。
對(duì)比度調(diào)整
井號(hào)鍵執(zhí)行一項(xiàng)附加功能以用于演示目的。按下它可以調(diào)整LCD顯示屏的對(duì)比度,這是一項(xiàng)通過增加LCRA寄存器中的RADJ位來執(zhí)行的簡(jiǎn)單功能。
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
結(jié)論
MAXQ2000通過專用的LCD控制器外設(shè)輕松直接地與LCD顯示器接口。使用MAXQ2000提供的靈活端口引腳配置,可以直接讀取多路復(fù)用鍵盤。中斷驅(qū)動(dòng)的狀態(tài)機(jī)允許在主應(yīng)用程序的后臺(tái)掃描和去抖動(dòng)矩陣中的所有鍵,而對(duì)處理器開銷的影響最小。
審核編輯:郭婷
-
微控制器
+關(guān)注
關(guān)注
48文章
7454瀏覽量
150853 -
控制器
+關(guān)注
關(guān)注
112文章
16103瀏覽量
177074 -
嵌入式
+關(guān)注
關(guān)注
5059文章
18973瀏覽量
302033
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論