使用键盘和LCD显示屏与MAXQ2000

描述

需要用户交互的嵌入式系统必须与接受用户输入的设备(如键盘、条形码阅读器或智能卡接受器)以及向用户显示信息的设备(如 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提供的灵活端口引脚配置,可以直接读取多路复用键盘。中断驱动的状态机允许在主应用程序的后台扫描和去抖动矩阵中的所有键,而对处理器开销的影响最小。

审核编辑:郭婷

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分