Keypad Display Forth Demo
This section presents the Forth version of the demonstration program source code. This source code activates the LCD display and keypad for a simple question response demo. This example can serve as a great starting point for your own instrumentation requirements.
\ Forth demo code for Keypad/Display Wildcard \ DATE: 10/1/2009 DECIMAL \ Numbers are interpreted as decimal unless preceeded with "0x"; \ if preceeded with "0x" they are interpreted as hexadecimal. \ the memory map must be set up prior to loading this file 15 WIDTH ! \ Prevent nonuniqueness in examples 0 CONSTANT KP_DISPLAY_MODULENUM \ KP/display wildcard MUST use module0 on Wildcard bus for V4.xx (QCard) kernel platforms \ V6.xx (PDQ Board) platforms can choose a module number between 0 and 7 \ Modulenum 0 corresponds to a WildCard plugged into Module Port 0 with no jumpers set. \ A WildCard plugged directly into a QCard is plugged into Module Port 0. \ Ordinarily, WildCards can be configured for module addresses 0 to 7; \ but the Keypad/Display WildCard MUST be set to module address 0 for the \ built-in software drivers on the QCard to work. \ On a PDQ Board, any module address can be specified using Set_Display_Modulenum \ The 16-bit value at Wildcard offset 0 is a security key; \ bits at Wildcard offset 02 control the beeper (the lsb) and backlight (the next bit); \ a bit at Wildcard offset 0x0E configures the I/O direction \ of the lower nibble I/O at Wildcard offset 0x0D; \ and Wildcard offset 0x0D provides 8 bits of general purpose user I/O. 0x20 CONSTANT ASCII.BLANK : Keypad_Demo ( -- ) KP_DISPLAY_MODULENUM Set_Display_Modulenum \ needed for PDQ line, does nothing on V4.xx Character_4x20 \ 4 row x20 column text mode character display INIT.DISPLAY \ Initialize the display and the DISPLAY.BUFFER Backlight_On \ Turn on the backlight BEGIN PAUSE.ON.KEY \ allows you to type a CR from the terminal to bail out of the loop " Press any key; " 0 0 $>DISPLAY \ write to buffer on line 0 " Press key 0 to exit" 1 0 $>DISPLAY \ write exit message to buffer on line 1 " You pressed key#:" 2 0 $>DISPLAY \ write to buffer on line 2 UPDATE.DISPLAY \ write to display KEYPAD \ get the key number ( -- key# ) 1000 Chirp \ makes a 1000 usec key click to provide audible feedback DUP WHILE \ terminate on key# 0 S>D <# # # #> DROP 1XN- ( -- x$addr ) \ convert key# to a string 3 0 $>DISPLAY ( -- ) \ write key# to buffer on line 3 UPDATE.DISPLAY \ write to display REPEAT DROP ( -- ) \ drop the zero key# " Done" 3 0 $>DISPLAY UPDATE.DISPLAY ; : Show_Keypad_Test_creen ( -- ) \ Shows X’s for each keypad button position. As each button is pressed \ an X in the corresponding location disappears. " ************ XXXXX *" 0 0 $>DISPLAY \ Stores the string at the row\col " Press keys XXXXX *" 1 0 $>DISPLAY \ position in the display buffer " to test. XXXXX *" 2 0 $>DISPLAY \ UPDATE.DISPLAY then transfers the " ************ XXXXX *" 3 0 $>DISPLAY \ buffer to the screen UPDATE.DISPLAY ; : Show_Exit_Screen ( -- ) \ Display screen to show after the test is done. " Congratulations ! " 0 0 $>DISPLAY \ Stores the string at the row\col " " 1 0 $>DISPLAY \ position in the display buffer " All the keys work " 2 0 $>DISPLAY \ UPDATE.DISPLAY then transfers the " as they should. " 3 0 $>DISPLAY \ buffer to the screen UPDATE.DISPLAY ; : Key_To_Row_Col ( key.num -- row\col ) \ Converts a keypad button number in the range 0-19 to \ row and column numbers, 0-3 for rows, and 0-4 for columns. \ The keypad is laid out as: \ Row Col: 0 1 2 3 4 \ 0 19 15 11 7 3 \ 1 18 14 10 6 2 \ 2 17 13 9 5 1 \ 3 16 12 8 4 0 4 /MOD \ row.offset/col.offset 3 ROT - \ col.offset/row 4 ROT - \ row/col ; : Key_To_Display_Addr ( key.num -- char.addr.in.display.buffer ) Key_To_Row_Col 13 + \ increment col# to start of array of X’s on the screen BUFFER.POSITION \ converts row\col to a display buffer offset DISPLAY.BUFFER \ leave display buffer address on stack ROT XN+ \ bring offset to top and add it to display buffer address ; : Keypad_Test ( -- ) \ This routine waits for the user to press each key. As each key is pressed it \ removes an "X" from the display at the key position. After all the keys are \ pressed this routine returns. We’ll use the bit positions in a local variable to \ keep track of which keys are pressed, setting a different bit for each different \ key pressed. 0x0000 \ for keys numbered 0-15, start with all bits cleared 0xFFF0 \ for keys numbered 16-19, start only with four bits cleared LOCALS{ &msb.keys &lsb.keys } \ hold the key positions in local variables KP_DISPLAY_MODULENUM Set_Display_Modulenum \ needed for PDQ line, does nothing on V4.xx Backlight_On \ Turn on the backlight Character_4x20 \ Define display to have 4 rows, 20 columns, text mode, \ a char.display, and to use hitachi controller chip INIT.DISPLAY \ Initializes the display, reserves the DISPLAY.BUFFER in RAM \ and calls CLEAR.DISPLAY. Show_Keypad_Test_creen \ Put our instructions to the user on the screen BEGIN PAUSE.ON.KEY \ Allows premature exit with a CR from the serial port &msb.keys &lsb.keys XOR \ Continue until all bits are set WHILE KEYPAD \ loops on the keypad & returns the number of pressed key 1000 Chirp \ makes a 1000 usec key click to provide audible feedback DUP Key_To_Display_Addr ASCII.BLANK -ROT C! \ ascii blank -> key’s location in UPDATE.DISPLAY \ the display buffer and update the display to show it DUP 16 < \ Is the key number less than 16? IF \ If so, set a bit in &lsb.keys 1 SWAP SCALE &lsb.keys OR TO &lsb.keys ELSE \ If not, subtract 16 and set a bit in &msb.keys 16 - 1 SWAP SCALE &msb.keys OR TO &msb.keys ENDIF REPEAT Show_Exit_Screen ;
See also → Keypad Display Wildcard Users Guide
This page is about: Keypad Display Forth Example Program, Question Answer HMI – Example program in Forth Language shows how to control an LCD character display and respond to keypad presses. Display, Character, 8 bits, key, number, message