on Mon, 27 Jan 1997 20:43:11, Barry Carter wrote: >I am looking for some information on controlling an LCD screen in C. >Does anyone out there have any code they have written, If so please >reply. This is a sample program given with the MPLABC demo kit, you can download this demo compiler version at microchip WEB site. I make some little change in order to use PORTB instead of PORTE, the "Delay_Ms_4MHz" routine is also adapted just to match the needed time for LCD wait. This sample just wrote "LCD Test for 16C84" on the first line of the LCD panel and move it left and right 5 times. Hope this will help you, regards, Philippe. (P.TECHER@insat.com) /* ********************************************************************* */ /* UMPS capabilities to use an external compiler */ /*-----------------------------------------------------------------------*/ /* This file is extract from the MPLABC-dŽmo kit and was compiled */ /* with the MPLABC dŽmo. */ /* ********************************************************************* */ #include <16c84.h> /* ********************************************************************* */ /* These routines implement an 8-bit interface to a Hitachi */ /* LCD module, busy flag used when valid. The data lines */ /* are on PORTB, E is on PORTA bit 3, R/W is on PORTA bit 2, */ /* RS is on PORTA bit1. Based off a 4MHz external clock source. */ /* These routines were ported to MPLAB-C from the assembly firmware */ /* accompanying the PICDEM2 demo board. */ /* ********************************************************************* */ // Defines for control signals to LCD module #define RS 1 #define RW 2 #define E 3 bits TEMP; /* ********************************************************************* */ /* Wait byte x 100us doing nothing */ /* ********************************************************************* */ void Delay_Ms_4MHz (char byte) // wait more than 100us { char I,J; for (J=1;J<=byte;J++) { for (I=1;I<10;I++) {} } } /* ********************************************************************* */ /* Busy:This routine checks the busy flag. */ /* Returns a 1 when LCD is busy, or a 0 when the LCD is not busy. */ /* ********************************************************************* */ void Busy(void) { do { PORTB = 0; TRISB = 0xff; // make PORTB all inputs PORTA.RS = 0; // setup LCD to output flags PORTA.RW = 1; NOP(); PORTA.E = 1; NOP(); NOP(); TEMP = PORTB; PORTA.E = 0; } while (TEMP.7); // check busy flag PORTA.RW = 0; TRISB = 0x00; // restore PORTB to outputs return; } /* ********************************************************************* */ /* SendCha This routine sends the character in byte to the LCD. */ /* ********************************************************************* */ void SendChar(char byte) { Busy(); // wait for LCD to not be busy PORTB = byte; // load PORTB with byte PORTA.RW = 0; // send character to LCD PORTA.RS = 1; NOP(); PORTA.E = 1; NOP(); PORTA.E = 0; return; } /* ********************************************************************* */ /* SendCmd This routine sends the command in byte to the LCD. */ /* ********************************************************************* */ void SendCmd(char byte) { Busy(); // wait for LCD to not be busy PORTB = byte; // load PORTB with byte PORTA.RW = 0; // send command byte to LCD PORTA.RS = 0; NOP(); PORTA.E = 1; NOP(); PORTA.E = 0; return; } /* ********************************************************************* */ /* LCDInit This routine initializes the LCD module and ports. */ /* ********************************************************************* */ void LCDInit(void) { PORTA = 0x00; // clear PORTA and PORTB PORTB = 0x00; TRISB = 0; // make PORTA and PORTB all outputs TRISA = 0; PORTA = 0x00; // clear PORTA PORTB = 0b00111000; // set 8-bit interface NOP(); PORTA.E = 1; NOP(); PORTA.E = 0; Delay_Ms_4MHz(5); // wait more than 4.1ms PORTB = 0b00111000; // set 8-bit interface NOP(); PORTA.E = 1; NOP(); PORTA.E = 0; Delay_Ms_4MHz(1); // wait more than 100us SendCmd(0b00001110); // display on, cursor on SendCmd(0b00000001); // clear display SendCmd(0b00000110); // set entry mode inc, no shift SendCmd(0b10000000); // Address DDRam upper left return; } /* ********************************************************************* */ /* Send a message to the LCD panel */ /* ********************************************************************* */ void SendMessage (char *PSt) { char I; I = *PSt; while (I!=0x00) { SendChar (I); PSt++; I = *PSt; } return; } /* ********************************************************************* */ /* ********************************************************************* */ void main() { char I; Delay_Ms_4MHz(1); // wait more than 100us LCDInit (); SendMessage ("LCD Test for 16C84"); for (I=5; I!=0; I--) { Delay_Ms_4MHz(250); SendCmd(0b00011000); // shift display left SendCmd(0b00011000); SendCmd(0b00011000); Delay_Ms_4MHz(250); SendCmd(0b00011100); // shift display right SendCmd(0b00011100); SendCmd(0b00011100); } while(1) { } }