westaust55
Moderator
From time to time there have been requests for code for a scrolling menu scheme using an LCD display.
Here is one possibility for a 4x20 character LCD module:
In this program, I do have some extra bits such as the interrupt routine to read my EDE-1188 based 48-key keypad based home brew keyboard (and using an eternal EEPROM for keyboard ASCII code lookup).
Plus moree SYMBOL statements than are specifically required for the scrolling menu.
Other than scroll up and down a menu with the U and D keys and give a message if the A key is pressed it is just a working demo for others to extrract code form.
Here is one possibility for a 4x20 character LCD module:
Code:
; =================================================
; File....... Scrolling Menu
; Purpose.... Scrolling Menu demo for 4x20 LCD dispaly
; Author..... Westaust55
; E-mail.....
; Started.... 25-02-2010
; Updated.... DD-MM-YYYY
; =================================================
;
; -----[ Program Description ]---------------------------------------------
;
; A program to demonstrate the ability for a scrolling menu on a 4x20 LCD
; functions of the Experimenters Box.
;
;
; -----[ Revision History ]------------------------------------------------
;
;
;
; -----[ I/O Definitions ]-------------------------------------------------
;
; - - - DIGITAL INPUT PINS - - -
SYMBOL key_data = 0 ; keypad serial data input
;intrpt val_data =1 ; keypad valid data signal
;
; - - - DIGITAL OUTPUT PINS - - -
SYMBOL lcd_data = 1 ; serial pin for data to LCD display
;
;
; -----[ i2c Device Addressing ]-------------------------------------------------------
;
; 24LC256 EEPROM's
SYMBOL eeprom_0 = %10100000 ; %1010 = EPROM, 000 = Addr 0 & 0 = control bit
;
; PCF8574 8-BIT IO EXPANDERS
SYMBOL expand_0 = %01000000 ; %0100 = Chip ID, 000 = Addr 0 - For the 8 Red LED's
SYMBOL expand_1 = %01000010 ; , 001 = Addr 1 - For Keypad Shift LED
;
;
; -----[ Constants ]-------------------------------------------------------
;
SYMBOL shiftkey = 64 ; value returned by keypad for shift key
SYMBOL NoLEDs = 8 ; No of LEDs in the bar graph
SYMBOL divisor = 255 ; typically divisor = 2^NoLEDs - 1
SYMBOL std_delay= 1000 ; default delay period in milliseconds
SYMBOL Scrollup = "U"
SYMBOL Scrolldown = "D"
SYMBOL Action = "A"
;
;
; 4 x 20 char LCD commands
SYMBOL lcd_bs = $08 ; back space
SYMBOL lcd_lf = $0A ; line feed
SYMBOL lcd_ff = $0C ; form feed
SYMBOL lcd_cr = $0D ; carriage return
;
SYMBOL lcdcmand = $FE ; = 254 - send this before following commands
SYMBOL lcdclear = $01 ; clear screen and cursor to home position
SYMBOL lcdhome = $02 ; move cursor to home position
SYMBOL lcdnocur = $0C ; display on with no cursor
SYMBOL lcdcuron = $0E ; display on with visible cursor
SYMBOL lcdcblnk = $0F ; display on with blinking cursor
SYMBOL lcdline1 = $80 ; move to start of 1st line
SYMBOL lcdline2 = $C0 ; move to start of 2nd line
SYMBOL lcdline3 = $94 ; move to start of 3rd line
SYMBOL lcdline4 = $D4 ; move to start of 4th line
SYMBOL lcdlitof = $FC ; turn backlight off
SYMBOL lcdLiton = $FD ; turn backlight on
;
; Scrolling Menu Constants
SYMBOL Displines = 4 ; Sets the number of lines in the display
SYMBOL Charsperline = 20 ; Sets the number of characters per line
SYMBOL MaxOptions = 9 ; Sets the total number of options in this menu set
;
;
; -----[ Variables ]-------------------------------------------------------
;
SYMBOL keypad = b27 ; Value returned from keypad (0-63)
SYMBOL keyval = b26 ; Add\justed value from keypad keypd+1 (1-64)
SYMBOL shflock = b25 ; Flag to indicate if shiftlock is ON/OFF
SYMBOL keychar = b24 ; ASCII character value for keypad key press
;
;
;Scrolling Menu Variables
SYMBOL ThisChar = b6
SYMBOL CharPtr = b5
SYMBOL Char2LCD = b4
SYMBOL LineNo = b3
SYMBOL Maxtop = b2 ; defines which is lowest menu set item that can scroll up to top display line
SYMBOL Cursor = b1 ; Defines which of the display lines the cursor is on
SYMBOL TopVisLine = b0 ; Defines which is the upper line of menu set visible on display
;
; -----[ EEPROM Data ]-----------------------------------------------------
;
EEPROM 0, ("Set The Time ")
EEPROM 20, ("Show the Time ")
EEPROM 40, ("Show Temperature ")
EEPROM 60, ("Show Mag Field Str")
EEPROM 80, ("Show Pot Voltage ")
EEPROM 100, ("Show the Distance ")
EEPROM 120, ("Show the Heading ")
EEPROM 140, ("Show Light Level ")
EEPROM 160, ("Hex to Dec & Bin ")
EEPROM 180, ("Say Text String ")
EEPROM 200, ("Play a Tune ")
;
;
; -----[ Initialization ]--------------------------------------------------
;
Init:
PAUSE 1000 ; wait for LCD to initialise
SEROUT lcd_data, N2400, (lcdcmand,lcdclear)
pause 10
; Scrolling LCD Menu variables
TopVisLine = 1
Cursor = 1
Maxtop = MaxOptions - Displines
;
GOSUB DispMenu
SETINT %00000000, %00000010 ; set polled interrupt to act on a change to 0 on input 1
;
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
;
Main:
Cont: DO
PAUSE 10
LOOP WHILE keyval =0
; Serin 1, N2400, keypad
IF keychar = scrollup THEN
Cursor = Cursor -1
IF Cursor = 0 THEN
Cursor = 1
TopVisLine = TopVisLine - 1 MIN 1
ENDIF
GOSUB DispMenu
ENDIF
IF keychar = scrolldown THEN
Cursor = Cursor + 1
IF Cursor = 5 THEN
Cursor = 4
TopVisLine = TopVisLine + 1 MAX MaxTop
ENDIF
GOSUB DispMenu
ENDIF
IF keychar = action THEN
GOSUB DoAction
GOSUB DispMenu
ENDIF
keyval =0
GOTO Main
;
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
;
DispMenu:
SEROUT lcd_data, N2400, (lcdcmand,lcdclear)
pause 10
For LineNo = 1 to Displines
LOOKUP LineNo, (0,lcdline1,lcdline2,lcdline3,lcdline4), Char2LCD
SEROUT lcd_data, N2400, (lcdcmand,Char2LCD)
PAUSE 10
For CharPtr = 1 to Charsperline
IF CharPtr = 1 THEN
IF Cursor = LineNo THEN
SEROUT lcd_data, N2400, (">")
ELSE
SEROUT lcd_data, N2400, (" ")
ENDIF
ELSEIF CharPtr = 2 THEN
SEROUT lcd_data, N2400, (" ")
ELSE
ThisChar = TopVisLine -1 + LineNo - 1 * Charsperline + CharPtr - 3;
READ ThisChar, Char2LCD
SEROUT lcd_data, N2400, (Char2LCD)
ENDIF
NEXT CharPtr
NEXT LineNo
RETURN
;
;
DoAction:
SEROUT lcd_data, N2400, (lcdcmand,lcdclear)
pause 10
SEROUT lcd_data, N2400, ("Here we would do the"); Do the action here
SEROUT lcd_data, N2400, ("selected action")
PAUSE 5000 ; give time to see message
RETURN
;
;
Shlok2led: ; Subroutine to togggle the keypad "SHIFT" LED
HI2CSETUP i2cmaster, expand_1, i2cslow, i2cbyte
IF shflock = 0 THEN
HI2COUT (0)
ELSE
HI2COUT (1)
ENDIF
RETURN
;
; -----[ Interrupt Routines (if used) ]-------------------------------------
;
Interrupt: SERIN key_data, T2400, keypad ; here when a key is pressed
keyval = keypad +1 ; change 0 to 63 to 1 to 64 (easier for maths)
IF keyval = shiftkey THEN ; If it was shift key Then . . .
shflock = shflock ^ keyval ; exclusive OR to toggle state of shift lock flag
GOSUB Shlok2led ; update the SHIFT LED
ENDIF
keyval = keyval + shflock ; 1 to 63 for lower, 65 to 127 for upper/shifted
HI2CSETUP i2cmaster, EEPROM_0, i2cslow, i2cword
HI2CIN keyval, (keychar) ; fetch the equivalent character from EEPROM table
SETINT %00000000, %00000010 ; restore the interrupt scheme and return to main program
RETURN
;
; =================================================
; THE END
; =================================================
In this program, I do have some extra bits such as the interrupt routine to read my EDE-1188 based 48-key keypad based home brew keyboard (and using an eternal EEPROM for keyboard ASCII code lookup).
Plus moree SYMBOL statements than are specifically required for the scrolling menu.
Other than scroll up and down a menu with the U and D keys and give a message if the A key is pressed it is just a working demo for others to extrract code form.