/*---------------------------------------------------------------------------- ** ** Display.c ** ** Control of LCD display. ** This display is only fitted during development/debug, so diagnostic ** messages can be displayed on it. It is driven through the serial-parallel ** shift regsiter to minimise the number of I/O ports required by the micro, ** since execution speed is unimportant in this module. ** ** The display is a 8 character x 2 line display, using the Samsung KS0066 ** LCD driver chip (refer to datasheet), allowing a total of 16 characters ** to be displayed. ** **--------------------------------------------------------------------------*/ #include "ShiftReg.h" #define SIZE_OF_MESSAGE_STORE 24 typedef enum { DS_IDLE, DS_SENDING } TDisplayState; // Store of characters/commands to send. static short DisplayStore[SIZE_OF_MESSAGE_STORE]; // Index into DisplayStore. static char DisplayIdx=0; // State machine variable. static TDisplayState DisplayState = DS_IDLE; // Command codes embedded in DisplayStore string #define DATA 0x0100 #define COMMAND 0x0200 #define LONG_WAIT 0x0400 #define END_OF_MESSAGE 0x0800 // LCD Commands #define DISPLAY_CLEAR 0x01 #define RETURN_HOME 0x02 #define ENTRY_MODE 0x04 #define DISP_ON_OFF 0x08 #define SHIFT 0x10 #define SET_FUNCTION 0x20 #define SET_CG_ADDRESS 0x40 #define SET_DD_ADDRESS 0x80 // LCD Command parameters #define CURSOR_INCREASE 0x02 #define CURSOR_DECREASE 0x00 #define DISPLAY_ON 0x04 #define DISPLAY_OFF 0x00 #define INTERFACE_8BIT 0x10 #define INTERFACE_4BIT 0x00 #define TWO_LINES 0x08 #define ONE_LINE 0x00 /*---------------------------------------------------------------------------- // // WriteLcd // // Writes to the display. // // Modification Record: // 09-Oct-00 Paul Hills First version. -----------------------------------------------------------------------------*/ void WriteLcd(unsigned char Data, char Type) { if (Type == COMMAND) ChainSetBit(SR_LCD_RS, 0); else ChainSetBit(SR_LCD_RS, 1); ChainSetBitNow(SR_LCD_RW, 0); ChainSetBitNow(SR_LCD_E, 1); ChainSetByteNow(SR_LCD_DATA, Data); ChainSetBitNow(SR_LCD_E, 0); ChainSetBit(SR_LCD_RS, 1); ChainSetBitNow(SR_LCD_RW, 1); } /*---------------------------------------------------------------------------- // // InitialiseDisplay // // Sets up a command sequence to initialise the display, and starts the // state machine to send it. // // Modification Record: // 09-Oct-00 Paul Hills First version. -----------------------------------------------------------------------------*/ void InitialiseDisplay(void) { DisplayStore[0] = COMMAND | DISPLAY_CLEAR; DisplayStore[1] = LONG_WAIT; DisplayStore[2] = COMMAND | DISP_ON_OFF | DISPLAY_ON; DisplayStore[3] = COMMAND | ENTRY_MODE | CURSOR_INCREASE; DisplayStore[4] = COMMAND | SET_FUNCTION | INTERFACE_8BIT | TWO_LINES; DisplayStore[5] = COMMAND | SET_DD_ADDRESS | 0x00; DisplayStore[6] = END_OF_MESSAGE; DisplayState = DS_SENDING; } /*---------------------------------------------------------------------------- // // Display // // Writes message to be displayed sandwiched around appropriate commands, and // starts the state machine. // // Modification Record: // 09-Oct-00 Paul Hills First version. -----------------------------------------------------------------------------*/ void Display(char *Message) { int i = 2; // Copy message to display area DisplayStore[0] = COMMAND | RETURN_HOME; DisplayStore[1] = LONG_WAIT; do { DisplayStore[i++] = DATA | (short)(*Message++); } while (i