| Stuckeymax 
 
 
 Joined: 15 Dec 2006
 Posts: 2
 Location: Atlanta, GA
 
 
			      
 
 | 
			
				| LCD Driver fix for Optrex 4x20 C-51847NFJ-SLW-ADN |  
				|  Posted: Tue Apr 28, 2009 8:31 pm |   |  
				| 
 |  
				|  	  | Code: |  	  | /////////////////////////////////////////////////////////////////////////// ////                             LCD.C                                ////
 ////                 Driver for common LCD modules                     ////
 ////                                                                   ////
 ////  lcd_init()   Must be called before any other function.           ////
 ////                                                                   ////
 ////  lcd_putc(c)  Will display c on the next position of the LCD.     ////
 ////                     The following have special meaning:           ////
 ////                      \f  Clear display                            ////
 ////                      \n  Go to start of second line               ////
 ////                      \b  Move back one position                   ////
 ////                                                                   ////
 ////  lcd_gotoxy(x,y) Set write position on LCD (upper left is 1,1)    ////
 ////                                                                   ////
 ////  lcd_getc(x,y)   Returns character at position x,y on LCD         ////
 ////  Note repair 100 uS delay added Line 190                          ////
 ///////////////////////////////////////////////////////////////////////////
 ////        (C) Copyright 1996,2003 Custom Computer Services           ////
 //// This source code may only be used by licensed users of the CCS C  ////
 //// compiler.  This source code may only be distributed to other      ////
 //// licensed users of the CCS C compiler.  No other use, reproduction ////
 //// or distribution is permitted without written permission.          ////
 //// Derivative programs created using this software in object code    ////
 //// form are not restricted in any way.                               ////
 ////                                                                   ////
 //// CCS lcd_init modified by SMc to correct LCD startup problems      ////
 //// with an Optrex C-51847NFJ-SLW-ADN 4x20 Transreflective Display    ////
 //// DK P/N 73-1249-ND     100 uS delay inserted Line 193              ////
 ///////////////////////////////////////////////////////////////////////////
 
 #ifndef __LCD_C__
 #define __LCD_C__
 
 #ifndef LCD_TYPE
 #define LCD_TYPE 2           // 0=5x7, 1=5x10, 2=2 or 4 lines
 #endif
 
 #define LCD_DELAY_CYCLES   3
 
 #define NUM_COLS 20
 
 //#if NUM_COLS==20
 //these maps are for 4x20
 const int8 lcd_line_off[] = {0x80, 0xc0, 0x94, 0xd4};
 //#elif NUM_COLS==16
 //these maps are for 4x16
 // const int8 lcd_line_off[] = {0x80, 0xc0, 0x90, 0xd0};
 //#endif
 
 #define NUM_LINES (sizeof(lcd_line_off)/sizeof(int8))
 
 int8 g_LCDCurrX, g_LCDCurrY;
 
 int8 const LCD_INIT_STRING[4] = {0x20 | (LCD_TYPE << 2), 0xc, 1, 6};
 // These bytes need to be sent to the LCD
 // to start it up.
 
 // use the following block if pins are on one port
 typedef struct
 {
 int1 enable;
 int1 rs;
 int1 rw;
 int1 blank;
 int8 dataPort:4;
 } LCDPinout;
 LCDPinout g_LCDLAT, g_LCDPORT, g_LCDTRIS;
 #locate g_LCDLAT=getenv("SFR:LATD")
 #locate g_LCDPORT=getenv("SFR:PORTD")
 #locate g_LCDTRIS=getenv("SFR:TRISD")
 #define lcd_data_set(d)       g_LCDLAT.dataPort = d
 #define lcd_data_get()        (g_LCDPORT.dataPort)
 #define lcd_tris_read()       g_LCDTRIS.dataPort = 0xF
 #define lcd_tris_write()      g_LCDTRIS.dataPort = 0
 #define lcd_tris_init()       g_LCDTRIS = 0x08
 #define lcd_output_enable(x)  g_LCDLAT.enable = x
 #define lcd_output_rs(x)      g_LCDLAT.rs = x
 #define lcd_output_rw(x)      g_LCDLAT.rw = x
 
 // use the following block if pins are all over the place
 /*
 #define lcd_output_enable(x) output_bit(LCD_ENABLE_PIN, x)
 #define lcd_output_rs(x) output_bit(LCD_RS_PIN, x)
 #define lcd_output_rw(x) output_bit(LCD_RW_PIN, x)
 
 void lcd_data_set(int8 data)
 {
 output_bit(LCD_D4_PIN, bit_test(data,0));
 output_bit(LCD_D5_PIN, bit_test(data,1));
 output_bit(LCD_D6_PIN, bit_test(data,2));
 output_bit(LCD_D7_PIN, bit_test(data,3));
 }
 
 int8 lcd_data_get(void)
 {
 int8 ret=0;
 
 if (input(LCD_D4_PIN))  bit_set(ret,0);
 if (input(LCD_D5_PIN))  bit_set(ret,1);
 if (input(LCD_D6_PIN))  bit_set(ret,2);
 if (input(LCD_D7_PIN))  bit_set(ret,3);
 
 return(ret);
 }
 
 void lcd_tris_read(void)
 {
 output_float(LCD_D4_PIN);
 output_float(LCD_D5_PIN);
 output_float(LCD_D6_PIN);
 output_float(LCD_D7_PIN);
 }
 
 void lcd_tris_write(void)
 {
 output_drive(LCD_D4_PIN);
 output_drive(LCD_D5_PIN);
 output_drive(LCD_D6_PIN);
 output_drive(LCD_D7_PIN);
 }
 
 void lcd_tris_init(void)
 {
 output_drive(LCD_ENABLE_PIN);
 output_drive(LCD_RS_PIN);
 output_drive(LCD_RW_PIN);
 }
 */
 
 int8 lcd_read_byte(void)
 {
 int8 low,high;
 
 lcd_tris_read();
 lcd_output_rw(1);
 delay_cycles(LCD_DELAY_CYCLES);
 lcd_output_enable(1);
 delay_cycles(LCD_DELAY_CYCLES);
 high = lcd_data_get();
 lcd_output_enable(0);
 delay_cycles(LCD_DELAY_CYCLES);
 lcd_output_enable(1);
 delay_us(1);
 low = lcd_data_get();
 lcd_output_enable(0);
 lcd_tris_write();
 return( (high<<4) | low);
 }
 
 
 void lcd_send_nibble( int8 n )
 {
 lcd_data_set(n);
 delay_cycles(LCD_DELAY_CYCLES);
 lcd_output_enable(1);
 delay_us(2);
 lcd_output_enable(0);
 }
 
 
 void lcd_send_byte( int8 address, int8 n ) {
 lcd_output_rs(0);
 while ( bit_test(lcd_read_byte(),7) ) ;
 lcd_output_rs(address);
 delay_cycles(LCD_DELAY_CYCLES);
 lcd_output_rw(0);
 delay_cycles(LCD_DELAY_CYCLES);
 lcd_output_enable(0);
 lcd_send_nibble(n >> 4);
 lcd_send_nibble(n & 0xf);
 
 delay_us(75);
 }
 
 
 void lcd_init(void)
 {
 int8 i;
 
 lcd_output_rs(0);
 lcd_output_rw(0);
 lcd_output_enable(0);
 
 lcd_tris_init();
 lcd_tris_write();
 
 delay_ms(5);
 for(i=1;i<=3;++i) {
 lcd_send_nibble(3);
 delay_ms(5);
 }
 lcd_send_nibble(2);
 delay_us(100);  //Provides a short delay between nibble(2) and init string
 //to correct LCD startup/cursor positioning problems
 for(i=0;i<=3;++i) {
 lcd_send_byte(0,LCD_INIT_STRING[i]);
 }
 }
 
 
 void lcd_gotoxy(int8 x, int8 y)
 {
 int8 address;
 // set new cursor position
 g_LCDCurrX = x % NUM_COLS;
 g_LCDCurrY = y % NUM_LINES;
 
 // wrap the y position by number of lines
 address = lcd_line_off[g_LCDCurrY];
 address += g_LCDCurrX;
 lcd_send_byte(0, address);
 }
 
 void lcd_gotoxy(int8 xy)
 {
 int8 address;
 
 g_LCDCurrX = xy % NUM_COLS;
 g_LCDCurrY = xy / NUM_COLS;
 
 // wrap the y position by number of lines
 address = lcd_line_off[g_LCDCurrY];
 address += g_LCDCurrX;
 lcd_send_byte(0, address);
 }
 
 
 void lcd_putc( char c)
 {
 switch (c) {
 case '\f'   : lcd_send_byte(0,1);
 delay_ms(2);
 lcd_gotoxy(0,0);
 break;
 case '\n'   : lcd_gotoxy(g_LCDCurrX, g_LCDCurrY+1);        break;
 case '\r'   : lcd_gotoxy(0, g_LCDCurrY);        break;
 case '\b'   : lcd_send_byte(0,0x10);  break;
 default     : lcd_send_byte(1,c);     break;
 }
 }
 
 void lcd_cursor_off(void) {
 lcd_send_byte(0,0x0C);           //turn LCD cursor OFF
 }
 
 void lcd_cursor_on(void) {
 lcd_send_byte(0,0x0F);           //turn LCD cursor ON
 }
 
 #endif
 | 
 |  |