Here you go. -Jordan cut here (___________________________________________________________________) /* LCDA.C Feb 19/94 */ /* By Jordan Nicol */ /* */ /* This program controls a Sharp LM16155 16*1 LCD Module */ /* (with a Hitachi HD44780 LCD Controller on it). To minimize */ /* number of I/O lines required, 4-bit operation is employed, */ /* meaning that a LCD command or data word is sent as two */ /* successive nybbles. */ /* The program does not check the busy flag to determine if */ /* the LCD controller has processed the last instruction, instead */ /* it waits the maximum processing time associated with the */ /* previous instruction-this saves some code. */ /* */ /* The I/O pin designation is as follows: */ /* LCD 68HC11 */ /* DB7-DB3 (data) PA7-PA3 */ /* E PC7 */ /* RS PC6 */ /* R/W GROUND */ /******************************************************************/ /******************************************************************/ /* NOTE for users of MICRO-C */ /* */ /* This program was written for use with Dunfield's Micro-C */ /* compiler and the library and set-up files for the Mini-board. */ /* Some of these files must be modified so that the variable */ /* i_code can be accessed using both C and assembly isntructions.*/ /* This is done as follows: */ /* 1) Edit 6811zp.src and add the following line to where the */ /* zero-page assembly variables are declared: */ /* i_code RMB 1 */ /* 2) Run the Make command. At this point you will be able to */ /* to access i_code with assembly code, but not with C code. */ /* 3) Edit extindex.lib and add i_code under the line ^6811zp.asm. */ /* 4) Define i_code as an external variable. This will give */ /* your C code access to it. Note that this part has already */ /* done for you below. */ /******************************************************************/ #define true 1 #define false 0 #define enable 1 #define disable 0 #define RSmask 0x40 /*01000000 */ #define ctlmask_w 1 #define nibmask 240 /* 11110000 */ #define WriteH 72 /* 01001000 */ #define DispClr 1 #define RetnHome 2 #define FncSet 0x20 #define EntryMode 0x06 #define DispOnNC 0x0C /* Display On - No Cursor */ #define DispOnC 0x0E /* Display On - cursor */ #define DispOff 0x08 /* These "defines" allow C code to access 6811 registers */ #define PORTA (*((char*)0x1000)) #define PORTC (*((char*)0x1003)) /* External variable declarations. These variables are located on */ /* zero page of memory and can be accessed using C code or in-line */ /* assembly. */ extern int time; extern char i_code; main() { /* Assembly Literals */ asm{ * Register offsets from $1000 PortA EQU $00 PortC EQU $03 ddrc EQU $07 Pactl EQU $26 Oc1m EQU $0C Tctl1 EQU $20 Emask EQU $80 } /* Set up PortC and PortA pin directions. Note: PA6-PA3 fixed */ /* outputs and PA2-PA0 are fixed inputs. */ asm{ LDX #$1000 CLR ddrc,X BSET ddrc,X,$C0 Set PC7 and PC6 as outputs BSET Pactl,X,$80 Set PA7 as output CLR Tctl1,X Disable Timer functions on PortA CLR Oc1m,X Ditto } Init_LCD(); /* Perform LCD initialization sequence */ while(1) /* endless loop */ { /* Your code goes here..... */ } /** end of infinite while loop **/ } /** end of main **/ /*************** FUNCTIONS ********************************************/ Init_LCD() /* This procedure performs the initialization sequnce for the LCD Module. */ /* It is written in assembly for efficiency. */ { asm{ LDX #$1000 LCD CLR PortC,X Clear PortC CLR PortA,X Clear PortA * Write a single command bit in your port to set to 8 bit mode BSET PortC,X,%10000000 Enable high BSET PortA,X,%00110000 Set LCD to 8-bit operation BCLR PortC,X,%10000000 Clear Enable * Wait for more than 4.1 ms BSR DELAY Wait approx. .5ms BSR DELAY Wait approx. .5ms BSR DELAY Wait approx. .5ms BSR DELAY Wait approx. .5ms BSR DELAY Wait approx. .5ms BSR DELAY Wait approx. .5ms BSR DELAY Wait approx. .5ms BSR DELAY Wait approx. .5ms CLR PortA,X Clear PortA * Write a single command bit in your port to set to 8 bit mode BSET PortC,X,%10000000 Enable high BSET PortA,X,%00110000 Set LCD to 8-bit operation BCLR PortC,X,%10000000 Clear Enable BSR DELAY Wait approx. .5ms CLR PortA,X Clear PortA * Write a single command bit in your port to set to 8 bit mode BSET PortC,X,%10000000 Enable high BSET PortA,X,%00110000 Set LCD to 8-bit operation BCLR PortC,X,%10000000 Clear Enable BSR DELAY Wait approx. .5ms CLR PortA,X Clear PortA BRA C1 DELAY CLR cntr Implements about .5ms delay L INC cntr BNE L RTS * Write a single command nibble to set 4 bit mode C1 BSET PortC,X,%10000000 Enable high BSET PortA,X,%00100000 Set LCD to 4-bit operation BCLR PortC,X,%10000000 Clear Enable * Wait more than 2.5ms BSR DELAY Wait approx. .5ms BSR DELAY BSR DELAY BSR DELAY BSR DELAY BSR DELAY * Here we begin 4-bit operation. Sets 4-bit operation and selects * 1-line display and 5 by 7 dot character font. BSET PortC,X,%10000000 Enable high BSET PortA,X,%00100000 Send MS nibble BCLR PortC,X,%10000000 Clear Enable CLR PortA,X Clear PortA BSET PortC,X,%10000000 Enable high BSET PortA,X,%10000000 Send LS nibble BCLR PortC,X,%10000000 Clear Enable BSR DELAY Wait .5 ms CLR PortA,X Clear PortA * Clears display and cursor. Puts into Space Mode * Sent in two nibbles. BSET PortC,X,%10000000 Enable high BSET PortA,X,%00000000 Send MS nibble BCLR PortC,X,%10000000 Clear Enable CLR PortA,X Clear PortA BSET PortC,X,%10000000 Enable high BSET PortA,X,%00010000 Send LS nibble BCLR PortC,X,%10000000 Clear Enable BSR DELAY Wait > 1.64ms BSR DELAY BSR DELAY BSR DELAY CLR PortA,X Clear PortA * Write Entry Mode instruction to inc address by 1 and to shift * cursor to right and to write to DD RAM BSET PortC,X,%10000000 Enable high BSET PortA,X,%00000000 Send MS nibble for H BCLR PortC,X,%10000000 Clear Enable BCLR PortA,X,%11111111 Clear PortA BSET PortC,X,%10000000 Enable high BSET PortA,X,%01100000 Send LS nibble BCLR PortC,X,%10000000 Clear Enable BCLR PortA,X,%11111111 Clear PortA BSR DELAY * End of initialization } /* end of Assembly stuff */ Send_Instruc(DispOnC,0); /* Turn on Display and cursor */ } /************************** End of Init_LCD()*************************/ int Send_Instruc(instcode,x) unsigned char instcode,x; /* This function handles all the low level details of sending commands to */ /* the LCD module. You simply specify the data byte to be sent and whether */ /* it is a command or data and this function does the rest. */ /* e.g. Send_Instruc('H',1) -- prints 'H' to LCD */ /* e.g. Send_Instruc(DispClr,0) -- clears the display */ { /* Send display instruction as 2 nibbles plus necessary control bits */ i_code = instcode; PORTC = 0; PORTA = 0; if (x == true) /* Data to be sent, need to set RS line */ { PORTC = RSmask; } asm{ LDX #$1000 LDAA i_code ANDA #$F0 BSET PortC,X,Emask Set E bit in PortC STAA PortA,X Write MS nibble to PORTA BCLR PortC,X,Emask Clear E bit only CLR PortA,X Clear PortA LDAA i_code Re-load i_code and shift lower nibble into LSLA upper nibble position LSLA LSLA LSLA BSET PortC,X,Emask Set E bit in PortC STAA PortA,X Write MS nibble, leaving E and RS unchanged BCLR PortC,X,Emask Clear E bit only CLR PortA,X Clear Port A } /* Display Clear and Return Home require 1.6ms to process */ if( (i_code==DispClr)||(i_code==RetnHome) ) { msleep(2); /* 2 ms delay prior to next instruction */ } else { asm{ DELAY2 BSET cntr $E0 Implements about 60us delay L2 INC cntr BNE L2 } } return(1); } /****************** End of Send_Instruc ***********************************/