Connect with us

Help getting an LCD to work

Discussion in 'Electronic Design' started by Will, Feb 3, 2004.

Scroll to continue with content
  1. Will

    Will Guest

    I have an Optrex LCD (DMC-20481NY-LY-AGE) that is 4x20 characters and
    driven by a Microchip PIC16F877 running at 20MHz. I know I got this
    exact same physical LCD to work before but for the life of me I can't
    recall what trick I used to do so. Attached at the end is my
    software. I get power to the LCD, but all I see is lines 1 and 3 as
    all dark and lines 2 and 4 as all clear. Hunting around newsgroups
    leads me to think my initialization routines aren't working (gee, ya
    think?!?!) but as near as I can tell I have met or exceeded all of the
    timing requirements for data transfer. PLEASE HELP!!!!! If it
    matters, I am using a dedicated 5V DC supply to drive both the PIC and
    the LCD. The PIC is connected to the LCD through 330 Ohm resistors,
    with 10KOhm pulldown resistors to ground on ALL of the lines on the
    PIC side. This was because I was seeing a lot of glitches on powerup
    due to ports being inputs. Each line also has a .01uF cap to ground
    and there is a bypass capacitor on the 5V line to ground next to the
    PIC. The BusyFlag is also connected directly from the LCD to the PIC
    on PORTB, 6. Thanks for any insight!
    -Will

    ; LCD Control Software
    ;
    ; Software uses a 20MHz crystal
    ; for timing.
    ;

    ;******************************************************************
    Stall MACRO
    LOCAL Stall_Jump
    goto Stall_Jump
    Stall_Jump
    ENDM
    ;******************************************************************
    Wait_For_Busy_Flag MACRO
    btfsc BUSY_FLAG
    goto $-1
    ENDM
    ;******************************************************************
    Wait_15ms MACRO
    LOCAL OuterLoop
    LOCAL InnerLoop

    movlw .59
    movwf OUTER_COUNTER
    OuterLoop
    movlw .255
    movwf INNER_COUNTER
    InnerLoop
    Stall
    decfsz INNER_COUNTER, F
    goto InnerLoop
    decfsz OUTER_COUNTER, F
    goto OuterLoop
    ENDM
    ;******************************************************************
    Wait_4.1ms MACRO
    LOCAL OuterLoop
    LOCAL InnerLoop

    movlw .17
    movwf OUTER_COUNTER
    OuterLoop
    movlw .255
    movwf INNER_COUNTER
    InnerLoop
    Stall
    decfsz INNER_COUNTER, F
    goto InnerLoop
    decfsz OUTER_COUNTER, F
    goto OuterLoop
    ENDM
    ;******************************************************************
    Wait_100us MACRO
    LOCAL InnerLoop

    movlw .100
    movwf INNER_COUNTER
    InnerLoop
    Stall
    decfsz INNER_COUNTER, F
    goto InnerLoop
    ENDM
    ;******************************************************************

    list p=16F877

    ; Include file, change directory if needed
    include "p16f877.inc"

    #define ENABLE PORTE, 2
    #define RS PORTE, 1
    #define RW PORTE, 0

    #define DATA_PORT PORTD
    #define BUSY_FLAG PORTB, 6

    OUTER_COUNTER equ 0x20
    INNER_COUNTER equ 0x21


    W_TEMP equ 0x70
    STATUS_TEMP equ 0x71
    PCLATH_TEMP equ 0x72


    ;//Reset Vector
    Org 0x00
    clrf PCLATH ; ensure page bits are cleared
    goto Initialize

    ;//Interrupt Vector
    ORG 0x04
    MOVWF W_TEMP ;Copy W to TEMP register
    SWAPF STATUS,W ;Swap status to be saved into W
    CLRF STATUS ;bank 0, regardless of current bank, Clears
    IRP,RP1,RP0
    MOVWF STATUS_TEMP ;Save status to bank zero STATUS_TEMP
    register
    MOVF PCLATH, W ;Only required if using pages 1, 2 and/or 3
    MOVWF PCLATH_TEMP ;Save PCLATH into W
    CLRF PCLATH ;Page zero, regardless of current page

    ;Fill this in if you want interrupt vectoring

    banksel PCLATH_TEMP
    MOVF PCLATH_TEMP, W ;Restore PCLATH
    MOVWF PCLATH ;Move W into PCLATH
    SWAPF STATUS_TEMP,W ;Swap STATUS_TEMP register into W
    ;(sets bank to original state)
    MOVWF STATUS ;Move W into STATUS register
    SWAPF W_TEMP,F ;Swap W_TEMP
    SWAPF W_TEMP,W ;Swap W_TEMP into W
    retfie ; return from interrupt

    ;//Initialization
    Initialize
    clrf INTCON
    clrf INTCON
    CGIE
    bcf INTCON, GIE
    btfsc INTCON, GIE
    goto CGIE

    ; //Declare port/pin definitions
    banksel TRISA
    movlw B'00000111'
    movwf ADCON1 ; Port A is all digital
    movlw B'00000000'
    movwf TRISA ; Port A is OOOOOOOO
    movlw B'01000000'
    movwf TRISB ; Port B is OIOOOOOO
    movlw B'10000001'
    movwf TRISC ; Port C is IOOOOOOI
    movlw B'00000000'
    movwf TRISD ; Port D is OOOOOOOO
    bcf TRISE, PSPMODE ; Turn off the parallel port
    bcf TRISE, 0 ; Port E is -----OOO
    bcf TRISE, 1
    bcf TRISE, 2

    bsf OPTION_REG, 7 ;Turn off port B pullups

    banksel OUTER_COUNTER
    bsf PORTB, 7

    Wait_15ms
    Wait_15ms

    bcf PORTB, 7

    bcf RS
    bcf RW
    movlw b'00111000'
    call StrobeData

    Wait_4.1ms
    Wait_4.1ms

    bcf RS
    bcf RW
    movlw b'00111000'
    call StrobeData

    Wait_4.1ms
    Wait_4.1ms

    bcf RS
    bcf RW
    movlw b'00111000'
    call StrobeData

    Wait_4.1ms
    Wait_4.1ms

    call DisplayOFF_CursorOFF_BlinkOFF
    Wait_15ms
    Wait_4.1ms

    call DisplayON_CursorON_BlinkON
    Wait_15ms
    Wait_4.1ms

    call EntryModeSet
    Wait_100us

    call ClearDisplay
    Wait_15ms
    Wait_4.1ms

    movlw b'01001000' ;H
    call SendChar
    movlw b'01100101' ;e
    call SendChar
    movlw b'01101100' ;l
    call SendChar
    movlw b'01101100' ;l
    call SendChar
    movlw b'01101111' ;o
    call SendChar
    movlw b'01010111' ;W
    call SendChar
    movlw b'01101111' ;o
    call SendChar
    movlw b'01110010' ;r
    call SendChar
    movlw b'01101100' ;l
    call SendChar
    movlw b'01100100' ;d
    call SendChar

    Eternal
    bcf PORTB, 0
    nop
    bsf PORTB, 0
    goto Eternal

    ;-----------
    StrobeData
    nop
    bsf ENABLE
    nop
    movwf DATA_PORT
    nop
    bcf ENABLE
    return
    ;-----------
    EntryModeSet
    btfsc BUSY_FLAG
    goto EntryModeSet
    bcf RS
    bcf RW
    movlw b'00000110'
    call StrobeData
    return
    ;-----------
    SendChar
    btfsc BUSY_FLAG
    goto SendChar
    bsf RS
    bcf RW
    call StrobeData
    return
    ;-----------
    ClearDisplay
    btfsc BUSY_FLAG
    goto ClearDisplay
    bcf RS
    bcf RW
    movlw 0x01
    call StrobeData
    return
    ;-----------
    HomeCursor
    btfsc BUSY_FLAG
    goto HomeCursor
    bcf RS
    bcf RW
    movlw 0x02
    call StrobeData
    return
    ;-----------
    DisplayOFF_CursorOFF_BlinkOFF
    btfsc BUSY_FLAG
    goto DisplayOFF_CursorOFF_BlinkOFF
    bcf RS
    bcf RW
    movlw b'00001000'
    call StrobeData
    return
    ;-----------
    DisplayOFF_CursorOFF_BlinkON
    btfsc BUSY_FLAG
    goto DisplayOFF_CursorOFF_BlinkON
    bcf RS
    bcf RW
    movlw b'00001001'
    call StrobeData
    return
    ;-----------
    DisplayOFF_CursorON_BlinkOFF
    btfsc BUSY_FLAG
    goto DisplayOFF_CursorON_BlinkOFF
    bcf RS
    bcf RW
    movlw b'00001010'
    call StrobeData
    return
    ;-----------
    DisplayOFF_CursorON_BlinkON
    btfsc BUSY_FLAG
    goto DisplayOFF_CursorON_BlinkON
    bcf RS
    bcf RW
    movlw b'00001011'
    call StrobeData
    return
    ;-----------
    DisplayON_CursorOFF_BlinkOFF
    btfsc BUSY_FLAG
    goto DisplayON_CursorOFF_BlinkOFF
    bcf RS
    bcf RW
    movlw b'00001100'
    call StrobeData
    return
    ;-----------
    DisplayON_CursorOFF_BlinkON
    btfsc BUSY_FLAG
    goto DisplayON_CursorOFF_BlinkON
    bcf RS
    bcf RW
    movlw b'00001101'
    call StrobeData
    return
    ;-----------
    DisplayON_CursorON_BlinkOFF
    btfsc BUSY_FLAG
    goto DisplayON_CursorON_BlinkOFF
    bcf RS
    bcf RW
    movlw b'00001110'
    call StrobeData
    return
    ;-----------
    DisplayON_CursorON_BlinkON
    btfsc BUSY_FLAG
    goto DisplayON_CursorON_BlinkON
    bcf RS
    bcf RW
    movlw b'00001111'
    call StrobeData
    return
    ;-----------
    END
     
  2. [...]

    10nF on each signal line is quite a lot! Why do you need such a big
    capacitive load on the data wires?

    Have you checked the timing on a scope, or are you just counting clock
    cycles in your program?
     
  3. Make sure you have the proper delays in the Init routines.
    I've used the same display and had problems with short delays in the Init routines.

    Cheers
     
  4. Mickey

    Mickey Guest

    I can only tell you from my experience which things made my life difficult
    with LCD.

    1. Contrast voltage had to be negative.

    I belive it isn't the case in your case, you only have to connect 10k
    potentiometer
    for contrast.

    2. Inpropper initialization routine.

    Wrong sequence of initialization commands. If order off commands is not
    right it
    can cause a lot of headaches.

    3. Using BUSY flag?

    When using BUSY flag you have to watch carefuly during the initialization
    routine
    when the busy flag can be checked.

    In your case my guess you would be you have incorrect initialization routine
    maybe
    timings are ok but the order of commands isn't.
    I had done initialization as written in one datasheet of my 2x16 LCD, and it
    worked
    badly sometimes it would initialize the LCD, and sometimes wouldn't I found
    another
    sequence for initializing on the Internet and it worked great since then.

    Mickey
     
  5. Your strobedata routine is too fast. Many LCD displays have a cycle time of
    500ns to 1000ns, where the E has to be kept high for 300 to 500ns or longer.
    Apart from that, your filtering of the datalines kills your signals. 0.01uF
    and 330 Ohm has a time constant of 3.3us. Your signals in the order of 1us
    cycle times will NEVER pass this filter. Remove the caps and resistors and
    you'll be fine.

    Meindert
     
  6. Crooksie

    Crooksie Guest

  7. CWatters

    CWatters Guest

    I think one pin on the most PICs is open collector.
     
  8. Will

    Will Guest

    I'm not sure how you're arriving at that conclusion. The formula I
    used to determine how long the enable pin strobed was as follows:
    For a PIC
    20 MHz external resonator/crystal -> 5MHz instruction rate (clock/4)
    -> 200 ns per instruction.

    Even assuming worst case that the PIC sets the pin high at the very
    end of the BSF instruction and low at the very beginning of the BCF
    instruction, there are 3 instructions between them. At 200ns each,
    that's at least 600ns and possibly 800ns if everything lines up
    nicely. I've also checked it with a scope probe and it looks more
    than long enough. In fact, I have verified that the PIC is in fact
    sending the signals I thinnk it should be at the right timing, based
    upon the datasheet that Optrex had on their website. In case anyone
    cares, that file was
    Dmcman_full.pdf and had 58 pages. It had no revisions listed on the
    second page so I guess it was revision 0.
     
  9. Michael

    Michael Guest


    (Maybe it's obvious from your code .... but I didn't read it.)
    The first thing I'd do is get rid of all the pulldowns and caps; you can
    add 'em all later if you really-really have to. I've driven half a
    dozen different LCDs with three kinds of PICs for several years and
    never needed all that extra hardware.

    The most persistant bug in my LCD boilerplate setup routines is that
    it's 5x8 dots, 2x20 display and the LCD I've got hooked up is different
    from those. I recall being in the same boat as you are now ... for
    days! ... gnashing my teeth because I _knew_ the code worked (I was
    looking at at earlier project that used the same code), and I _knew_ the
    LCD was OK (because it worked when hooked up to a different project).
    Yes, it was a case of operator error; the display that wouldn't
    initialize was not a 2x20 but a 1x16.
     
  10. Michael

    Michael Guest


    Ah yes ... the famous open collector gotcha. That's another trap for
    amateurs. It still bites me from time to time, even after upteen
    Microchip projects.
     
  11. By reading the datasheets and experience. Driving earlier LCD's from a '51
    bus was already a problem. You had to use nifty adressing tricks to get it
    running as a memory mapped device. the other solution was to drive the port
    pins directly.

    But I strongly suggest to remove the caps. Your signals do not have the
    proper rise and fall time requirements. And they simply block a strobe as as
    short as a microsecond.

    Meindert
     
  12. Will

    Will Guest

    Ok, I've had limited success so far. Circuit-wise I have removed the
    capacitors from the data lines but left the series and pulldown
    resisitors alone. Program-wise I have added enourmous delays to the
    initialization routines and reordered some of the commands. The
    combination seems to have done the trick for initializing the display
    since I now get a blinking cursor and some letters. I say some
    letters, because there is still a timing glitch I can't seem to track
    down. I know it has to do with trying to use the Busy Flag instead of
    hard coded delays, but despite searching the web and pouring over
    cryptic datasheets I cannot find a solution that works. If someone
    familiar with PIC assembly could post a WORKING snippet of code for a
    20MHz crystal, or if someone could just post a graphical plot of
    signals versus time for checking the busy flag I would greatly
    appreciate it! My new code is appended below. Thanks for all the
    help!
    -Will

    ; LCD Control Software
    ;
    ; Software uses a 20MHz crystal
    ; for timing.
    ;

    ;******************************************************************
    Stall MACRO
    LOCAL Stall_Jump
    goto Stall_Jump
    Stall_Jump
    ENDM
    ;******************************************************************
    Wait_15ms MACRO
    LOCAL OuterLoop
    LOCAL InnerLoop

    movlw .59
    movwf OUTER_COUNTER
    OuterLoop
    movlw .255
    movwf INNER_COUNTER
    InnerLoop
    Stall
    decfsz INNER_COUNTER, F
    goto InnerLoop
    decfsz OUTER_COUNTER, F
    goto OuterLoop
    ENDM
    ;******************************************************************
    Wait_4.1ms MACRO
    LOCAL OuterLoop
    LOCAL InnerLoop

    movlw .17
    movwf OUTER_COUNTER
    OuterLoop
    movlw .255
    movwf INNER_COUNTER
    InnerLoop
    Stall
    decfsz INNER_COUNTER, F
    goto InnerLoop
    decfsz OUTER_COUNTER, F
    goto OuterLoop
    ENDM
    ;******************************************************************
    Wait_100us MACRO
    LOCAL InnerLoop

    movlw .100
    movwf INNER_COUNTER
    InnerLoop
    Stall
    decfsz INNER_COUNTER, F
    goto InnerLoop
    ENDM
    ;******************************************************************
    CheckBusyFlag MACRO
    LOCAL JumpPoint
    JumpPoint
    bcf RS
    bsf RW
    nop
    nop
    bsf ENABLE
    nop
    nop
    nop
    nop
    nop
    bcf ENABLE
    btfsc BUSY_FLAG
    goto JumpPoint
    ENDM
    ;******************************************************************
    list p=16F877

    ; Include file, change directory if needed
    include "p16f877.inc"

    #define ENABLE PORTE, 2
    #define RS PORTE, 1
    #define RW PORTE, 0

    #define DATA_PORT PORTD
    #define BUSY_FLAG PORTB, 6

    OUTER_COUNTER equ 0x20
    INNER_COUNTER equ 0x21

    W_TEMP equ 0x70
    STATUS_TEMP equ 0x71
    PCLATH_TEMP equ 0x72


    ;//Reset Vector
    Org 0x00
    clrf PCLATH ; ensure page bits are cleared
    goto Initialize

    ;//Interrupt Vector
    ORG 0x04
    MOVWF W_TEMP ;Copy W to TEMP register
    SWAPF STATUS,W ;Swap status to be saved into W
    CLRF STATUS ;bank 0, regardless of current bank, Clears
    IRP,RP1,RP0
    MOVWF STATUS_TEMP ;Save status to bank zero STATUS_TEMP
    register
    MOVF PCLATH, W ;Only required if using pages 1, 2 and/or 3
    MOVWF PCLATH_TEMP ;Save PCLATH into W
    CLRF PCLATH ;Page zero, regardless of current page

    ;TO DO: Fill in for interrupt vectoring

    banksel PCLATH_TEMP
    MOVF PCLATH_TEMP, W ;Restore PCLATH
    MOVWF PCLATH ;Move W into PCLATH
    SWAPF STATUS_TEMP,W ;Swap STATUS_TEMP register into W
    ;(sets bank to original state)
    MOVWF STATUS ;Move W into STATUS register
    SWAPF W_TEMP,F ;Swap W_TEMP
    SWAPF W_TEMP,W ;Swap W_TEMP into W
    retfie ; return from interrupt

    ;//Initialization from powerup
    Initialize
    clrf INTCON
    clrf INTCON
    CGIE
    bcf INTCON, GIE
    btfsc INTCON, GIE
    goto CGIE
    clrf INTCON

    ; //Declare port/pin definitions
    banksel TRISA
    movlw B'00000111'
    movwf ADCON1 ; Port A is all digital
    movlw B'00000000'
    movwf TRISA ; Port A is OOOOOOOO
    movlw B'01000000'
    movwf TRISB ; Port B is OIOOOOOO
    movlw B'10000001'
    movwf TRISC ; Port C is IOOOOOOI
    movlw B'00000000'
    movwf TRISD ; Port D is OOOOOOOO
    bcf TRISE, PSPMODE ; Turn off the parallel port
    bcf TRISE, 0 ; Port E is -----OOO
    bcf TRISE, 1
    bcf TRISE, 2
    bsf OPTION_REG, 7 ;Turn off port B pullups

    banksel PORTB
    call Big_Delay
    call Big_Delay
    call Big_Delay
    call Big_Delay

    banksel OUTER_COUNTER
    bsf PORTB, 7

    Wait_15ms
    Wait_15ms

    bcf PORTB, 7

    bcf RS
    bcf RW
    movlw b'00111000'
    call StrobeData

    Wait_15ms
    Wait_15ms

    bcf RS
    bcf RW
    movlw b'00111000'
    call StrobeData

    Wait_15ms
    Wait_15ms

    bcf RS
    bcf RW
    movlw b'00111000'
    call StrobeData

    Wait_15ms
    Wait_15ms

    bcf RS
    bcf RW
    movlw b'00111000'
    call StrobeData

    Wait_15ms
    Wait_15ms

    call DisplayOFF_CursorOFF_BlinkOFF
    Wait_15ms
    Wait_15ms

    call ClearDisplay
    Wait_15ms
    Wait_15ms

    call EntryModeSet
    Wait_15ms
    Wait_15ms

    call DisplayON_CursorON_BlinkON
    Wait_15ms
    Wait_15ms

    movlw b'01001000' ;H
    call SendChar
    movlw b'01100101' ;e
    call SendChar
    movlw b'01101100' ;l
    call SendChar
    movlw b'01101100' ;l
    call SendChar
    movlw b'01101111' ;o
    call SendChar
    movlw b'01010111' ;W
    call SendChar
    movlw b'01101111' ;o
    call SendChar
    movlw b'01110010' ;r
    call SendChar
    movlw b'01101100' ;l
    call SendChar
    movlw b'01100100' ;d
    call SendChar

    Eternal
    bsf PORTB, 0
    nop
    bcf PORTB, 0
    goto Eternal

    ;-----------
    StrobeData
    nop
    bsf ENABLE
    nop
    nop
    movwf DATA_PORT
    nop
    nop
    bcf ENABLE
    return
    ;-----------
    EntryModeSet
    CheckBusyFlag
    bcf RW
    movlw b'00000110'
    call StrobeData
    return
    ;-----------
    SendChar
    CheckBusyFlag
    bsf RS
    bcf RW
    call StrobeData
    return
    ;-----------
    ClearDisplay
    CheckBusyFlag
    bcf RW
    movlw 0x01
    call StrobeData
    return
    ;-----------
    HomeCursor
    CheckBusyFlag
    bcf RW
    movlw 0x02
    call StrobeData
    return
    ;-----------
    DisplayOFF_CursorOFF_BlinkOFF
    CheckBusyFlag
    bcf RW
    movlw b'00001000'
    call StrobeData
    return
    ;-----------
    DisplayOFF_CursorOFF_BlinkON
    CheckBusyFlag
    bcf RW
    movlw b'00001001'
    call StrobeData
    return
    ;-----------
    DisplayOFF_CursorON_BlinkOFF
    CheckBusyFlag
    bcf RW
    movlw b'00001010'
    call StrobeData
    return
    ;-----------
    DisplayOFF_CursorON_BlinkON
    CheckBusyFlag
    bcf RW
    movlw b'00001011'
    call StrobeData
    return
    ;-----------
    DisplayON_CursorOFF_BlinkOFF
    CheckBusyFlag
    bcf RW
    movlw b'00001100'
    call StrobeData
    return
    ;-----------
    DisplayON_CursorOFF_BlinkON
    CheckBusyFlag
    bcf RW
    movlw b'00001101'
    call StrobeData
    return
    ;-----------
    DisplayON_CursorON_BlinkOFF
    CheckBusyFlag
    bcf RW
    movlw b'00001110'
    call StrobeData
    return
    ;-----------
    DisplayON_CursorON_BlinkON
    CheckBusyFlag
    bcf RW
    movlw b'00001111'
    call StrobeData
    return
    ;-----------
    ShiftCursorRight
    CheckBusyFlag
    bcf RW
    movlw b'00010100'
    call StrobeData
    return
    ;-----------
    ShiftCursorLeft
    CheckBusyFlag
    bcf RW
    movlw b'00010000'
    call StrobeData
    return
    ;-----------
    ShiftDisplayRight
    CheckBusyFlag
    bcf RW
    movlw b'00011100'
    call StrobeData
    return
    ;-----------
    ShiftDisplayLeft
    CheckBusyFlag
    bcf RW
    movlw b'00011000'
    call StrobeData
    return
    ;-----------
    ;******************************************************************
    Little_Delay
    Stall
    Stall
    Stall
    Stall
    Stall
    Stall
    Stall
    Stall
    Stall
    Stall
    Stall
    Stall
    Stall
    Stall
    Stall
    Stall
    Stall
    Stall
    Stall
    Stall
    Stall
    Stall
    Stall
    Stall
    Stall
    Stall
    Stall
    Stall
    Stall
    Stall
    Stall
    Stall
    Stall
    Stall
    Stall
    Stall
    Stall
    Stall
    Stall
    Stall
    Stall
    Stall
    Stall
    Stall
    Stall
    Stall
    Stall
    Stall
    Stall
    Stall
    Stall
    Stall
    Stall
    Stall
    Stall
    Stall
    Stall
    Stall
    Stall
    Stall
    Stall
    Stall
    Stall
    Stall
    Stall
    Stall
    Stall
    Stall
    Stall
    Stall
    return
    Big_Delay
    call Little_Delay
    call Little_Delay
    call Little_Delay
    call Little_Delay
    call Little_Delay
    call Little_Delay
    call Little_Delay
    call Little_Delay
    call Little_Delay
    call Little_Delay
    call Little_Delay
    call Little_Delay
    Medium_Delay
    call Little_Delay
    call Little_Delay
    call Little_Delay
    call Little_Delay
    call Little_Delay
    call Little_Delay
    call Little_Delay
    call Little_Delay
    call Little_Delay
    call Little_Delay
    call Little_Delay
    call Little_Delay
    call Little_Delay
    return
    ;-----------
    END
     
  13. No comment on the hardware aspect of your design, but
    putting caps on data lines is unusual to say the least.

    The main problem with getting Optrex LCDs to work is the
    initialization. The info provided by Optrex is only
    approximately accurate with respect to the time delays.
    I've had to insert looooong delays at each initialization
    step and then shorten them until failure, thus finding
    that some had to be substantially longer than Optrex
    says.

    There's also a gotcha with the BUSY flag -- it doesn't
    start working at the point in the initialization
    process that Optrex states. A wait loop has to be
    used at each step until the end of initialization.
    The BUSY flag can and should be used from there onward.
     
  14. Bob Stephens

    Bob Stephens Guest

    I had exactly the same experience - took many frustrating hours to figure
    out and Optrex was zero help.
    Yup
     
  15. I seem to remember that you were saying the Busy flag was connected to
    bit 6 Port B. Odd, because the busy flag is the highest data bit (bit 7)
    if I remember this right. Can you check your busy flag definition
    against the data sheet of the LCD chip? Have you got the data sheet of
    the HD44780, which is the prototypical chip everyone emulates?
    I consider it advisable to change the order of the bcf and btfsc
    instructions, because the former disables the output of the data that
    you are reading with the second.
     
  16. Egads

    Egads Guest

    Make sure you give the LCD time to power up. I just hooked
    up a Optrex 2x16 display to a TI MSP430 and I had to put in huge
    delays before I ever started initializing the LCD. After I did
    that all of my problems went away....

    --
    Greg Deuerling
    Fermi National Accelerator Laboratory
    P.O.Box 500 MS368 Batavia, IL 60510
    (630)840-4629 FAX (630)840-5406
    Electronic Systems Engineering Group
    Work: egads_AT_fnal.gov, remove '_AT_'
     
  17. Active8

    Active8 Guest


    Ah yes ... the famous open collector gotcha. That's another trap for
    amateurs. It still bites me from time to time, even after upteen
    Microchip projects.
    [/QUOTE]

    /MCLR is OC when used as a data line - isn't that one of 'em? Works
    as an out only, IIRC.
     
  18. Active8

    Active8 Guest

    On 3 Feb 2004 14:34:31 -0800, said...
    <snip>

    I haven't used Optrex yet but My biggest prob getting those black
    lines to go away and everything else to init was that I left the
    R/W line open. The controller inputs have internal weak pullups so
    you have to either tie R/W low or drive it with the PIC.

    The other thing I found was that the home command was pretty
    useless or something like that. It didn't do what the HDwhatever
    Spec sheet said. I have to use Clear Display.

    Also, resetting the PIC which runs my LCD init code sometimes
    doesn't give the LCD enough time to do whatever it needs to do, I
    have to power down the LCD.

    I'm not sure, but for the 4 bit interface, I may have had to run
    the init code twice. Once to get it in 4 bit mode and again once
    it's there.
     
Ask a Question
Want to reply to this thread or ask your own question?
You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.
Electronics Point Logo
Continue to site
Quote of the day

-