Jump to content

Sarge

EstablishedMember
  • Content Count

    12
  • Joined

  • Last visited

Community Reputation

0 Neutral

About Sarge

  • Rank
    Newbrie

Contact Methods

  • Website URL
    http://tekcube.ath.cx
  • ICQ
    0

Profile Information

  • Location
    Canada
  • Interests
    Computers, Gaming, Programming, Electronics
  1. Yes, I moved it to RA0 and left RW and E where they were.
  2. I was under the impression that that was referring to the upper or lower nibble of the port on the PIC. Just to see I tried hooking up DB0-DB3 to RC0-RC3 and there is no noticeable difference.
  3. There should have been a post above that said I think I fragged the LCD. I then asked what LCD's do when they die. Well I'm not to sure it is dead anymore. I just think it isn't sending the necessary signals or something. Err now I am thinking I might have fragged it again. Ahh so confused. EDIT: Found broken solder joint. I am going to fix it then try again and see if luck is on my side. Broken connection is DB7. EDIT: ...No luck. How can I see a flashing cursor when I first try cac001's code, not I see the top line all blocks... EDIT: Pulled out all of the LCD connections out of my breadboard and rewired it very carefully. Still the same thing... EDIT: Oh and RC4 & RC5; What do you mean by using them as serial interface. I don't have them hooked up to anything, should they be wired to something?
  4. It kind of worked but I think I just fragged it... What do LCD's typically do when they die?
  5. Well the problem now is I don't exactly know why it isn't working. Here is the code: main_lcd.c #include <system.h> #include "lcd_drv.h" #pragma CLOCK_FREQ 4000000 #pragma DATA 0x2007, _HS_OSC & _WDT_OFF void main() { lcd_setup(); porta = 0; lprintf( "4Bit test :-)" ); while(1){ ; } } lcd_drv.h (Slightly modifed version of lcd_driver.h) I removed comments at start to shorten this post: #define LCD_ARGS 1, /* Interface type: mode 0 = 8bit, 1 = 4bit(low nibble), 2 = 4bit(upper nibble) */ \ 1, /* Use busy signal: 1 = use busy, 0 = use time delays */\ PORTC, TRISC, /* Data port and data port tris register */ \ PORTA, TRISA, /* Control port and control port tris register */ \ 3, /* Bit number of control port is connected to RS */ \ 2, /* Bit number of control port is connected to RW */ \ 1 /* Bit number of control port is connected to Enable */ //////////////////////////////////////////////////////////////////////////// char writeDelayType; //////////////////////////////////////////////////////////////////////////// // LCD Commands ( Refer to LCD Data Sheet ) //////////////////////////////////////////////////////////////////////////// #define clear_lcd 0x01 // Clear Display #define return_home 0x02 // Cursor to Home position #define entry_mode 0x06 // Normal entry mode #define entry_mode_rev 0x04 // Normal entry mode -reverse direction #define entry_mode_scroll 0x07 // - with shift #define entry_mode_scroll_rev 0x05 // reverse direction #define system_set_8_bit 0x38 // 8 bit data mode 2 line ( 5x7 font ) #define system_set_4_bit 0x28 // 4 bit data mode 2 line ( 5x7 font ) #define system_set_reset 0x30 // Reset code #define display_on 0x0C // Display ON - 2 line mode #define display_off 0x08 // Display off #define set_dd_line1 0x80 // Line 1 position 1 #define set_dd_line2 0xC0 // Line 2 position 1 #define set_dd_ram 0x80 // Line 1 position 1 #define write_data 0x00 // With RS = 1 #define cursor_on 0x0E // Switch Cursor ON #define cursor_off 0x0C // Switch Cursor OFF #define cursor_blink_on 0x0F // Cursor plus blink #define cursor_shift_right 0x14 // Move cursor right #define cursor_shift_left 0x10 // Move cursor left #define display_shift_right 0x1C // Scroll display right #define display_shift_left 0x18 // Scroll display left #define WriteNoDelay 1 #define WriteControlled 0 // Interface type #define LCD_8_BIT_MODE 0 #define LCD_4_BIT_LO_NIB_MODE 1 #define LCD_4_BIT_HI_NIB_MODE 2 // These macros make susequent code more readable, but can seem a little confusing #define _LCD_RawWriteNibble LCD_RawWriteNibble <InterfaceType, UseBusy, DataPort, Data_PortTris, CtrlPort, Ctrl_PortTris, RS, RW, E> #define _LCD_RawWriteNibbleInline LCD_RawWriteNibbleInline <InterfaceType, UseBusy, DataPort, Data_PortTris, CtrlPort, Ctrl_PortTris, RS, RW, E> #define _LCD_Read LCD_Read <InterfaceType, UseBusy, DataPort, Data_PortTris, CtrlPort, Ctrl_PortTris, RS, RW, E> #define _LCD_WaitForNotBusy LCD_WaitForNotBusy <InterfaceType, UseBusy, DataPort, Data_PortTris, CtrlPort, Ctrl_PortTris, RS, RW, E> #define _LCD_Write LCD_Write <InterfaceType, UseBusy, DataPort, Data_PortTris, CtrlPort, Ctrl_PortTris, RS, RW, E> #define _LCD_FunctionMode LCD_FunctionMode <InterfaceType, UseBusy, DataPort, Data_PortTris, CtrlPort, Ctrl_PortTris, RS, RW, E> #define _LCD_DataMode LCD_DataMode <InterfaceType, UseBusy, DataPort, Data_PortTris, CtrlPort, Ctrl_PortTris, RS, RW, E> #define _LCD_RawWrite LCD_RawWrite <InterfaceType, UseBusy, DataPort, Data_PortTris, CtrlPort, Ctrl_PortTris, RS, RW, E> #define _LCD_ClockOut LCD_ClockOut <InterfaceType, UseBusy, DataPort, Data_PortTris, CtrlPort, Ctrl_PortTris, RS, RW, E> #define _LCD_TEMPL template < unsigned char InterfaceType,\ unsigned char UseBusy,\ unsigned int DataPort, unsigned int Data_PortTris,\ unsigned int CtrlPort, unsigned int Ctrl_PortTris,\ unsigned char RS, unsigned char RW, unsigned char E> _LCD_TEMPL inline void LCD_FunctionMode( void ) { volatile bit rs@CtrlPort.RS = 0; } _LCD_TEMPL inline void LCD_DataMode( void ) { volatile bit rs@CtrlPort.RS = 1; } inline void LCD_CycleMakeupDelay() { // Enable cycle time must be > 1000ns total for both reading and writing // LCD_SetupDelay + LCD_EnablePulseDelay + LCD_HoldupDelay + LCD_CycleMakeupDelay >= 1000ns // 200 + 500 + 100 + 200 >= 1000ns // This delay is required to meet the Sharp data sheet total cycle time of > 1000ns // @40MHz this is 2 instructions asm nop asm nop } inline void LCD_EnablePulseDelay() { // PWEH > 460ns on Sharp data sheet // @40MHz this is 5 instructions asm nop asm nop asm nop asm nop asm nop } inline void LCD_SetupDelay() { // tAS > 140ns min on Sharp data sheet // @40MHz this is 2 instructions asm nop asm nop } inline void LCD_HoldupDelay() { // tAS > 10ns min on Sharp data sheet // @40MHz this is 1 instructions asm nop } _LCD_TEMPL char LCD_Read() { char d; volatile unsigned char data@DataPort, tris@Data_PortTris; volatile bit rw@CtrlPort.RW, e@CtrlPort.E; if( InterfaceType == LCD_4_BIT_HI_NIB_MODE ) { // upper nibble input tris |= 0xF0; rw = 1; // set reading mode // first high nibble LCD_SetupDelay(); e = 1; LCD_EnablePulseDelay(); d = data & 0xF0; // read data e = 0; LCD_HoldupDelay(); LCD_CycleMakeupDelay(); // then low nibble LCD_SetupDelay(); e = 1; LCD_EnablePulseDelay(); d |= data >> 4; e = 0; LCD_HoldupDelay(); LCD_CycleMakeupDelay(); } if( InterfaceType == LCD_4_BIT_LO_NIB_MODE ) { // lower nibble input tris |= 0x0F; rw = 1; // set reading mode // first high nibble LCD_SetupDelay(); e = 1; LCD_EnablePulseDelay(); d = data << 4; e = 0; LCD_HoldupDelay(); LCD_CycleMakeupDelay(); // then low nibble LCD_SetupDelay(); e = 1; LCD_EnablePulseDelay(); d |= data & 0x0F; e = 0; LCD_HoldupDelay(); LCD_CycleMakeupDelay(); } if( InterfaceType == LCD_8_BIT_MODE ) { // port input tris = 0xFF; rw = 1; // set reading mode LCD_SetupDelay(); e = 1; LCD_EnablePulseDelay(); d = data; e = 0; LCD_HoldupDelay(); LCD_CycleMakeupDelay(); } return d; } _LCD_TEMPL void LCD_RawWriteNibble( char d ) { // Note: this function is duplicate below, but declared inline. // this is to reduce stack depth usage // Note: this function is above, but declared inline. // this is to reduce stack depth usage volatile unsigned char data@DataPort, tris@Data_PortTris; volatile bit rw@CtrlPort.RW, e@CtrlPort.E; if( InterfaceType == LCD_4_BIT_HI_NIB_MODE ) { // port upper nibble output rw = 0; // set writing mode LCD_SetupDelay(); tris &= 0x0F; data &= 0x0F; data |= d & 0xF0; e = 1; LCD_EnablePulseDelay(); e = 0; LCD_HoldupDelay(); LCD_CycleMakeupDelay(); } if( InterfaceType == LCD_4_BIT_LO_NIB_MODE ) { // port upper nibble output rw = 0; // set writing mode LCD_SetupDelay(); tris &= 0xF0; data &= 0xF0; data |= d >> 4; e = 1; LCD_EnablePulseDelay(); e = 0; LCD_HoldupDelay(); LCD_CycleMakeupDelay(); } } _LCD_TEMPL inline void LCD_RawWriteNibbleInline( char d ) { // Note: this function is above, but declared inline. // this is to reduce stack depth usage volatile unsigned char data@DataPort, tris@Data_PortTris; volatile bit rw@CtrlPort.RW, e@CtrlPort.E; if( InterfaceType == LCD_4_BIT_HI_NIB_MODE ) { // port upper nibble output rw = 0; // set writing mode LCD_SetupDelay(); tris &= 0x0F; data &= 0x0F; data |= d & 0xF0; e = 1; LCD_EnablePulseDelay(); e = 0; LCD_HoldupDelay(); LCD_CycleMakeupDelay(); } if( InterfaceType == LCD_4_BIT_LO_NIB_MODE ) { // port upper nibble output rw = 0; // set writing mode LCD_SetupDelay(); tris &= 0xF0; data &= 0xF0; data |= d >> 4; e = 1; LCD_EnablePulseDelay(); e = 0; LCD_HoldupDelay(); LCD_CycleMakeupDelay(); } } _LCD_TEMPL void LCD_RawWrite( char d ) { volatile unsigned char tris@Data_PortTris, data@DataPort; volatile bit rw@CtrlPort.RW, e@CtrlPort.E; if( InterfaceType == LCD_4_BIT_HI_NIB_MODE ) { // output upper nibble, then lower nibble bit flag = 0; do { _LCD_RawWriteNibbleInline( d ); flag = !flag; d <<= 4; } while( flag ); } if( InterfaceType == LCD_4_BIT_LO_NIB_MODE ) { // output upper nibble, then lower nibble bit flag = 0; do { _LCD_RawWriteNibbleInline( d ); flag = !flag; d <<= 4; } while( flag ); } if( InterfaceType == LCD_8_BIT_MODE ) { // port b output rw = 0; // set writing mode tris = 0x00; data = d; LCD_SetupDelay(); e = 1; LCD_EnablePulseDelay(); e = 0; LCD_HoldupDelay(); LCD_CycleMakeupDelay(); } } _LCD_TEMPL inline void LCD_WaitForNotBusy() { volatile bit rs@CtrlPort.RS; bit old_RS = rs; rs = 0; while( _LCD_Read() & 0x80 ); // wait while busy set rs = old_RS; } _LCD_TEMPL void LCD_Write(char d ) { volatile bit rs@CtrlPort.RS; if( UseBusy == 1 ) { // wait until display Not busy before sending next data if ( writeDelayType == WriteControlled ) _LCD_WaitForNotBusy(); _LCD_RawWrite( d ); } else { _LCD_RawWrite( d ); // give time to complete if ( writeDelayType == WriteControlled ) { if( !rs && (d == return_home || d == clear_lcd) ) delay_ms( 2 ); // return_home takes more time than other instructions to execute else delay_10us( 5 ); // 50us - enough time for normal command execution - clear and home need longer!! } } } _LCD_TEMPL void LCD_Clear() { _LCD_FunctionMode(); _LCD_Write( clear_lcd ); // clear display _LCD_Write( return_home ); } _LCD_TEMPL void LCD_Setup( void ) { // set control port bits used to output volatile bit trisRS@Ctrl_PortTris.RS, trisRW@Ctrl_PortTris.RW, trisE@Ctrl_PortTris.E; trisRS = 0; trisRW = 0; trisE = 0; writeDelayType = WriteNoDelay; // no delays in data writes delay_ms(16); // Power up delay _LCD_FunctionMode(); if( InterfaceType == LCD_4_BIT_HI_NIB_MODE ) { // Reset sequence as described in data sheets _LCD_RawWriteNibble( system_set_reset ); delay_ms(5); // min delay here of 4.1 ms _LCD_RawWriteNibble( system_set_reset ); delay_10us(100); // min delay here of 100us _LCD_RawWriteNibble( system_set_reset ); // LCD busy flag is valid from this point onwards if( UseBusy == 1 ) _LCD_WaitForNotBusy(); else delay_10us( 5 ); // standard command delay time _LCD_RawWriteNibble( system_set_4_bit ); if( UseBusy == 1 ) _LCD_WaitForNotBusy(); else delay_10us( 5 ); // standard command delay time writeDelayType = WriteControlled; _LCD_Write( system_set_4_bit ); } if( InterfaceType == LCD_4_BIT_LO_NIB_MODE ) { // Reset sequence as described in data sheets _LCD_RawWriteNibble( system_set_reset ); delay_ms(5); // min delay here of 4.1 ms _LCD_RawWriteNibble( system_set_reset ); delay_10us(100); // min delay here of 100us _LCD_RawWriteNibble( system_set_reset ); // LCD busy flag is valid from this point onwards if( UseBusy == 1 ) _LCD_WaitForNotBusy(); else delay_10us( 5 ); // standard command delay time _LCD_RawWriteNibble( system_set_4_bit ); if( UseBusy == 1 ) _LCD_WaitForNotBusy(); else delay_10us( 5 ); // standard command delay time writeDelayType = WriteControlled; _LCD_Write( system_set_4_bit ); } if( InterfaceType == LCD_8_BIT_MODE ) { // Reset sequence as described in data sheets _LCD_RawWrite( system_set_reset ); delay_ms(5); // min delay here of 4.1 ms _LCD_RawWrite( system_set_reset ); delay_10us(10); // min delay here of 100us _LCD_RawWrite( system_set_reset ); // busy flag is valid from this point onwards if( UseBusy == 1 ) _LCD_WaitForNotBusy(); else delay_10us( 5 ); // standard command delay time _LCD_RawWrite( system_set_8_bit ); if( UseBusy == 1 ) _LCD_WaitForNotBusy(); else delay_10us( 5 ); // standard command delay time writeDelayType = WriteControlled; // use busy } _LCD_Write( entry_mode ); _LCD_Write( display_on ); _LCD_Write( set_dd_ram ); } _LCD_TEMPL void LCD_Printf( const char *lcdptr ) { char pi = 0, c; _LCD_DataMode(); while( 1 ) { c = lcdptr[pi++]; if ( !c ) return; if ( c == '\n' ) { _LCD_FunctionMode(); // move to start second line _LCD_Write( set_dd_ram + 0x40 ); _LCD_DataMode(); } else _LCD_Write( c );// Display on LCD } } _LCD_TEMPL void LCD_Printf( rom char *lcdptr ) { char pi = 0, c; _LCD_DataMode(); while( 1 ) { c = lcdptr[pi++]; if ( !c ) return; if ( c == '\n' ) { _LCD_FunctionMode(); // move to start second line _LCD_Write( set_dd_ram + 0x40 ); _LCD_DataMode(); } else _LCD_Write( c );// Display on LCD } } _LCD_TEMPL void LCD_Printf( const char *lcdptr, unsigned int val ) // JS - Accept unsigned by default { unsigned char pi = 0, bi, c, fill, baseOrBits, sign, mask; unsigned char buff[ 10 ]; // max length allow is 9 bit pad; _LCD_DataMode(); while( 1 ) { c = lcdptr[pi++]; if ( !c ) return; switch( c ) { case '\n': _LCD_FunctionMode(); // move to start second line _LCD_Write( set_dd_ram + 0x40 ); _LCD_DataMode(); break; case '%': c = lcdptr[pi++]; if ( !c ) return; //Handle escape sequence that prints '%' if ( c == '%' ) { _LCD_Write( c );// Display on LCD break; } // Next character if zero indicates that we should zero fill output if ( c == '0' ) { fill = '0'; c = lcdptr[pi++]; if ( !c ) return; } else fill = ' '; // Next character if valid digit indicates field width if( c > '0' && c <= '9' ) { pad = 1; bi = c - 48;; c = lcdptr[pi++]; if ( !c ) return; } else { pad = 0; bi = sizeof( buff ) - 1; } // Next character indicates the radix (number base) sign = 0; switch( c ) { case 'd': if( val & 0x8000 ) // Negative values must be adjusted to be positive // JS { sign = '-'; val ^= 0xFFFF; // 2s complement negate // JS val++; } case 'u': baseOrBits = 10; // base ten, divide by ten per digit break; case 'X': baseOrBits = 4; // base 16, requires a 4 bit shift per digit mask = 0x0F; break; case 'b': baseOrBits = 1; // base 16, requires a 1 bit shift per digit mask = 0x01; break; default: return; // no radix } // null terminate, then reverse fill string buff[ bi ] = '\0'; bit first = true; while( bi ) { bi--; if( val || first ) { first = false; if( baseOrBits == 10 ) { c = (unsigned char)(val % 10); // JS - Optimization, use absolute of 10 val /= 10; // JS - Optimization, use absolute of 10 } else { c = val & mask; val = ((unsigned int)val) >> baseOrBits; } if( c > 9 ) c += 55; // convert to hex digits character A-F else c += 48; // convert to digit character 0-9 } else { if( sign && (bi == 0 || fill != '0') ) { c = sign; sign = 0; } else c = fill; } buff[ bi ] = c; if( pad == 0 && val == 0 && sign == 0 ) break; } // output string to display while( 1 ) { c = buff[ bi ]; if( !c ) break; _LCD_Write( c );// Display on LCD bi++; } break; default: _LCD_Write( c );// Display on LCD break; } } } _LCD_TEMPL void LCD_GotoXy( char x, char y ) { // displays memory mapping with two lines: // line 1: 0x00 // line 2: 0x40 // display memory mapping with four lines: // line 1: 0x00 // line 2: 0x40 // line 3: 0x14 // line 4: 0x54 _LCD_FunctionMode(); unsigned char offset = x; if( y & 0x01 ) offset += 0x40; if( y & 0x02 ) offset += 0x14; _LCD_Write( set_dd_ram + offset ); } _LCD_TEMPL void LCD_Function( char func ) { _LCD_FunctionMode(); _LCD_Write( func ); } //////////////////////////////////////////////////////////////////////////// // Helpers that hide template arguments //////////////////////////////////////////////////////////////////////////// // low level functions #define lcd_write LCD_Write<LCD_ARGS> #define lcd_waitfornotbusy LCD_WaitForNotBusy<LCD_ARGS> #define lcd_read LCD_Read<LCD_ARGS> #define lcd_funcmode LCD_FunctionMode<LCD_ARGS> #define lcd_datamode LCD_DataMode<LCD_ARGS> // high level functions - these all set function or data mode as required #define lcd_setup LCD_Setup<LCD_ARGS> #define lprintf LCD_Printf<LCD_ARGS> #define lcd_clear LCD_Clear<LCD_ARGS> #define lcd_gotoxy LCD_GotoXy<LCD_ARGS> #define lcd_function LCD_Function<LCD_ARGS>
  6. I played around with one and it compiled, but doesn't work. I'm 99% sure it isn't the wiring. It's probably the signals sent to the LCD, but I am not sure what ones are right for my LCD. I basically just slightly modified the lcd_driver.h file that comes with SB IDE. Here is my project on my webserver, zipped: http://tekcube.ath.cx/lcd.zip Thanks!
  7. I have been looking for code to control it and modify it to control it. It doesn't even compile, thats how I know if it works or not.
  8. I pretty much have nothing code wise or wiring wise, so I don't have anything to provide other then the fact that I want to use a 16F688 to control an LCD. I contacted the LCD manufacturer for two things here is the response: "The EW24210BFW uses the NT3881 chipset. All EDT character modules are 8 bit interface." The NT3881 datasheet: http://www.datasheets.org.uk/datasheet.php?article=2582472 Thanks again.
  9. Sounds easy enough but how is that going to look in code compatible with the 16F688?
  10. Is there a trace I need to solder for 4 bit or something? I know it isn't a wiring problem, because I haven't even been able to get a working program compatible with a 16F688. As for the display driver, its gooped up and I am not seeing anything that is clearly the display driver model. Oh and the contrast is on a pot (I have tested and confirmed that works).
  11. Well I am new to PIC's and obviously LCD's so, this is all uncharted territory for me. The LCD is http://www.allelectronics.com/cgi-bin/item..._LINE_LCD_.html The datasheet: http://www.allelectronics.com/spec/LCD-113.pdf I didn't write my own functions because I have no idea where to start.
  12. Please someone help me out. I've been trying for almost a week to get a 16F688 driving an LCD (4 Bit). I've tried EVERY language in the Source Boost system and I've scoured the darkest corners of the net for code. I have tried the samples that come with Source Boost and nothing works. I have tried to modify each and every bit and byte of code I have found. I am to the point where I am damn near ready to give up. Can anyone lend me a much needed hand? Thanks 999 Trillion!
×
×
  • Create New...