LCD will not start


Closed Thread
Page 1 of 2 12 LastLast
Results 1 to 40 of 50
  1. #1
    Join Date
    Mar 2003
    Posts
    41

    Default LCD will not start

    I have problems with an LCD which will not start after power up about 90% of the time. The code is running as all other functions work as expected but the LCD is just 16 black squares where I expect characters.

    The same code and hardware will start the LCD about 90% of the time if I power up, wait a few seconds, then apply a manual reset by grounding the MCLR line.

    a/ Can I perform a full PIC reset in code ?
    b/ Any one else experienced this and found a fix?
    c/ Bad news that the forum does not allow a serach on 3 characters. LCD is automatically thrown out and there are no hits found searching for "Liquid Crystal Display"

    The code follows - all help welcome.
    data @0, 0 'Action Flags
    data @1, 0 'Status flags
    Data @2, "PW50 Gas Mixer v1a BDT 11OCT06 "

    '************************************************* ***************
    '* Name : Gas Mixer v1a.pbp *
    '* Author : Brian Taylor *
    '* Notice : Copyright (c) 2005 Brian Taylor *
    '* : All Rights Reserved *
    '* Date : 11 OCT 2006 *
    '* Version : 1a *
    '* Notes : *
    '* : *
    '************************************************* ***************
    '
    '

    Start:
    define osc 20
    define loader_used 1
    ' Define LCD registers and bits
    Define LCD_DREG PORTD
    Define LCD_DBIT 0
    Define LCD_RSREG PORTD
    Define LCD_RSBIT 5
    Define LCD_EREG PORTD
    Define LCD_EBIT 4
    DEFINE LCD_LINES 2
    DEFINE LCD_BITS 4
    DEFINE LCD_COMMANDUS 5000 'Command delay time in us
    DEFINE LCD_DATAUS 250 'Data delay time in us
    define char_pacing 200

    @ Device pic16F877A, HS_OSC, BOD_OFF, PWRT_ON, WDT_ON, PROTECT_OFF
    '@__config_HS_OSC &_BOD_OFF &_PWRT_ON &_WDT_ON &_PROTECT_OFF &_LVP_OFF

    '********************** hardware definition ***************************
    'PortA
    Function var porta.0 'pin 2 analog from 12 position switch IN
    RunStop var porta.1 ' SWp6 to 877p3 Front panel toggle IN
    Enter var porta.2 ' SWp4 to 877p4 Selects current value IN
    Up var porta.3 ' SWp2 to 877p5 Advances selection IN
    AutoMan var porta.4 ' SWp7 to 877p6 Local/Remote control IN
    Down var porta.5 ' SWp3 to 877p7 Reduces selection IN
    TRISA = %00011111
    CMCON = %00000111 ' comparators disabled
    ADCON0 = %11000000 ' int RC clock, ADC disabled
    ADCON1 = %11001110 ' port 0 analog, all others digital

    'PortB
    GMData var portb.0 'bidirecional data to/from Master Controller
    GMStrobe1 var portb.1 'signals MC that GM needs attention
    GMStrobe2 var portb.2 'signals GM that MC has data
    GMSpare var portb.3 'a PCB trace between PeeWee50 pin 9 and 877p36
    LED2 var portb.4 'front panel LED2
    N2 var portb.5 'Nitrogen solenoid
    SClk var portb.6 'Intersema SClk OUT to MS5534 & 5535
    DIn var portb.7 'Intersems Data In OUT from 877a to MS5534 & 5535
    TRISB = %00001111
    PortB = %00000000

    'PortC
    CO2 var portc.0 'CO2 solenoid
    O2 var portc.1 'O2 solenoid
    MClk var portc.2 'MClk to Intersema PWM2 32678 Hz OUT to MS5534/5
    Vent var portc.3 'Vent/dump solenoid
    Delvry var portc.4 'delivery solenoid controls final delivery
    SpareSol var portc.5 'spare solenoid OUT
    TxD var portc.6 'Boot loader and RS232 OUT
    RxD var portc.7 'Boot & RS232 IN
    TRISC = %10000000
    PortC = %00000000

    'PortD
    DB4 var portd.0 'Data bit 4 to LCD
    DB5 var portd.1 'Data bit 5 to LCD
    DB6 var portd.2 'Data bit 6 to LCD
    DB7 var portd.3 'Data bit 7 to LCD
    LCDEnable var portd.4 'LCD ENABLE line OUT to LCD
    RegSel var portd.5 'LCD Register Select OUT to LCD
    ReadWrite var portd.6 'LCD Read/Write line OUT to LCD
    LED1 var portd.7 'Front Panel LED1
    TRISD = %00000000
    PortD = %00110000

    'PortE
    ClrEntry var porte.0 'SWp5 to 877p8 Clears entry on front panel??? IN
    Dout1 var porte.1 'Input from 14 bar Intersema
    Dout2 var porte.2 'Input from 1 bar Intersema
    TRISE = %11111111
    PortE = %00000000

    '************************ Variable assignments ***************************
    'OPTION_REG = %10001111 ' no pullups, prescaler to WDT /128

    'CMCON = %00000111 'comparators OFF

    A var byte ' General purpose Variable
    B var byte ' General purpose Variable
    C var byte ' General purpose Variable
    FuncSel var byte ' Switch position after decoding ADC value
    ADCval var word
    LoopCtr var byte
    U var word
    V var word
    W var word
    X var word
    Y var word
    Z var word
    RunFlag var bit



    '************************** Initialise *********************************
    loopctr = 0
    pause 500 'wait for LCD to start

    LEDTest:

    for a = 0 to 3
    ' high led1
    high led2
    high readwrite
    pause 1
    low readwrite
    pause 10
    ' low led1
    low led2
    next a

    StartLCD:
    pause 500
    lcdout $FE, $01 ' Get LCD registers into active states
    pause 100 ' wait for LCD to start
    lcdout $FE, $01 ' for justin

    ShowRevision:
    serout txd, 2, [$0D, $0A]
    lcdout $FE, $01 ' clear display
    for a = 2 to 16
    read a,b
    ' pause 50
    lcdout b
    serout txd, 2, [b]
    next a
    lcdout $FE, $C0 'select second line
    for a = 17 to 32
    read a,b
    lcdout b
    serout txd, 2, [b]
    next a
    serout txd,2, [$0D, $0A]
    pause 2000



    ' ************************* MAIN **************************************
    MAIN:
    loopctr = loopctr + 1
    SwitchTest:
    ' LCDout $FE, $01, " Function test"
    ADCON1 = %11100100 ' ports 0, 1 & 3 analog, all others digital
    ADCON0 = %11000001 ' internal RC clock, select Ch0, turn ADC ON
    pauseus 50 ' allow setling time
    ADCON0 = %11000101 ' start conversion
    waitdone1:
    IF ADCON0.2 = 1 then waitdone1 ' tight loop until conversion ends
    adcval.byte1 = ADRESH ' upper two bits of result
    adcval.byte0 = ADRESL ' lower eight bits of result
    if adcval < 47 then funcsel = 0
    if adcval > 47 then funcsel = 1
    if adcval > 140 then funcsel = 2
    if adcval > 232 then funcsel = 3
    if adcval > 327 then funcsel = 4
    if adcval > 420 then funcsel = 5
    if adcval > 511 then funcsel = 6
    if adcval > 605 then funcsel = 7
    if adcval > 700 then funcsel = 8
    if adcval > 790 then funcsel = 9
    if adcval > 890 then funcsel = 10
    if adcval > 970 then funcsel = 11
    lcdout $FE, $01, " Function = ", #funcsel, $FE, $C0, "ADCVal ", #adcval, " ", #loopctr
    serout txd, 2, [$0D, $0A, "Function = ", #funcsel, ", ADCVal = ", #adcval, ", LoopCtr = ", #loopctr]

    SolenoidTest:
    low n2
    low co2
    low 02
    low sparesol
    low vent
    low delvry
    if funcsel = 1 then high co2
    if funcsel = 2 then high o2
    if funcsel = 3 then high n2
    if funcsel = 4 then high vent
    if funcsel = 5 then high delvry
    if funcsel = 6 then high sparesol
    pause 50

    if loopctr = 255 then start
    goto main

  2. #2
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    Hey Brian,

    > a/ Can I perform a full PIC reset in code ?
    No. With a 16F, you can reset the program, but not the pic itself. (unless you tie an output pin to the MCLR pin, and set the output LOW). But even that doesn't reset everything to "Power-ON" settings. However, that won't solve your problem anyways.

    > b/ Any one else experienced this and found a fix?
    Yes, see below.

    > c/ Bad news that the forum does not allow a serach on 3 characters. LCD is automatically thrown out and there are no hits found searching for "Liquid Crystal Display"
    See this thread. It's a sticky at the top of the FAQ forum that you posted this message in. (but I've moved this thread)
    A better Search tool for the Forum
    http://www.picbasic.co.uk/forum/showthread.php?t=4751

    Now for the LCD.

    LCD's can't initialize while the pins are floating, which is the state they are in on power-up of the PIC. Once those pins are taken to the proper state, it then needs a short delay for it's internal initialization. It's usually safe to wait around 500ms, but most of the ones I have only need about 250ms.

    In your program, this section...
    Code:
    [************************** Initialise *********************************
    loopctr = 0
    pause 500 'wait for LCD to start
    doesn't do anything for the LCD since the pins are still floating. It just spends a half second doing nothing.

    Then here...
    Code:
    StartLCD:
    pause 500
    It uses another half second doing nothing again.

    Then here...
    Code:
    lcdout $FE, $01 ' Get LCD registers into active states
    pause 100 ' wait for LCD to start 
    lcdout $FE, $01 ' for justin
    This is the first place that the pins are no longer floating, but the pause is only 100ms so the next lcdout will interfere with the start-up.

    So here's how to fix it.

    Up at the ***** Initialise ****** lines, change it to this...
    Code:
    LCDOUT $FE,1
    pause 500 'wait for LCD to start
    .. Remove all the other pauses and clear screens.
    .. Remove the LCD_COMMANDUS 5000 and LCD_DATAUS 250 lines, they are way too high.

    It'll start up every time.
    DT

  3. #3
    Join Date
    Mar 2003
    Posts
    41


    Did you find this post helpful? Yes | No

    Default Thanks Darryl

    Thanks,

    I will be back on that project in 48 hours so I will let you know how it goes. Your explanations make excellent sense.

    Thanks again

    Brian

  4. #4
    Join Date
    Sep 2004
    Location
    montreal, canada
    Posts
    6,898


    Did you find this post helpful? Yes | No

    Default

    And a simple add at the bottom of the List...
    Code:
    @ Device pic16F877A, HS_OSC, BOD_OFF, PWRT_ON, WDT_ON, PROTECT_OFF
    1. You Should also disable the LVP mode, sometime it could do some strange behaviour..

    2. Could be interesting to enable the BOD... safety sake.

    good luck!
    Steve

    It's not a bug, it's a random feature.
    There's no problem, only learning opportunities.

  5. #5
    Join Date
    Mar 2003
    Posts
    41


    Did you find this post helpful? Yes | No

    Default LCD still unreliable

    I have implemented Darrel's suggestions and they improve the situation but do not fix it. The LCD now starts about 50% of the time - up from less than 10% - but still not a solid solution.

    I think the problem lies (in part) in the power supply dV/dT at startup. Depending where in the mains cycle the unit is turned on, the power rise time can be from 20 - 90 mSecs. The data sheet implies the rise time should be under 10 mSecs and if that cannot be guaranteed, then a software reset sequence should be followed.

    Does anyone know the software sequence for 4 bit mode? The only examples I can find are both ambiguous and written for 8 bit mode which I cannot implement on this existing PCB with all i/o pins used on the PIC16F877A.

    Cheers
    Brian

  6. #6
    Join Date
    Sep 2004
    Location
    montreal, canada
    Posts
    6,898


    Did you find this post helpful? Yes | No

    Default

    What happen if you tie the PORTB.3 to gnd via 10K (or less)?

    Did you tried to enable the BOD (brown out voltage) and disable the LVP (Low voltage programming) mode?

    If nothing work, maybe, you could add a little capacitor (0.1-1uF) between MCLR and GND... maybe.

    Schematic?
    Steve

    It's not a bug, it's a random feature.
    There's no problem, only learning opportunities.

  7. #7
    Join Date
    Mar 2003
    Posts
    41


    Did you find this post helpful? Yes | No

    Default LVP, BOD, etc

    Hi Mister-e.

    The PIC always starts. I know this because I have solenoids and switches and the switches always control the solenoids correctly. I think that rules out BOD or LVP issues. The 2 x 16 LCD always starts with the top row all black boxes and the lower row blank. When it starts properly, the LCD clears in about 500 mS and shortly afterwards the expected characters appear. When it does not start, the top line remains black and nothing appears on the lower line.

    I have tried 100 nf, 1uf and 10 uF as the MCLR capacitor with 10k to +5. Again the PIC always starts.

    The big 12 V 10 amp power supply is relatively slow to start and turning it on/off at the wall shows the LCD problem much more often than leaving the power supply on all the time and make/break the power line to the processor board. A scope shows the +5V rise time as 20-100 mS for on/off at the wall and under 1 mS for make/break to the 12 volt feed to the processor board. dV/dT is clearly part of the problem.

    A web search has turned up www.densitron.com and they have a discussion on timing aspects plus 4 bit and 8 bit modes. They make much of the tight timing restrictions between the Enable, RegisterSelect, data transitions and Read/Write lines and say this is a common problem with faster processors. sadly their app note is shot with typos and they do not define the pin functions (should RS be high or low during write? - they show it as both)

    I have the distinct feeling that PBP may be marginal with some brands of LCD at higher crystal speeds.

    Cheers
    Brian

  8. #8
    Join Date
    Sep 2004
    Location
    montreal, canada
    Posts
    6,898


    Did you find this post helpful? Yes | No

    Default

    try...

    Code:
    Start:
        Pause 1000
        LCDOUT $FE,1,"First"
        Pause 1000
        FLAGS=0
        LCDOUT $FE,1,"Second"
        pause 1000
        FLAGS=0
        LCDOUT $FE,1,"Third"
    Loop:
        Goto Loop
    What happen?

    I heard that some LCD may need up to 2 second to start correctly... but i never had one in my hand
    Last edited by mister_e; - 18th October 2006 at 01:34.
    Steve

    It's not a bug, it's a random feature.
    There's no problem, only learning opportunities.

  9. #9
    Join Date
    Mar 2003
    Posts
    41


    Did you find this post helpful? Yes | No

    Default Nope mister-e - that does not do it

    Hi mister-e.

    Your code, after fixing the start/loop and flag issues, does not work on power up. It does work after a MCLR reset but so do all my attempts.

    I am trying now to implement the full reset sequence in code.

  10. #10
    Join Date
    Feb 2003
    Location
    Salt Lake City, Utah USA
    Posts
    517


    Did you find this post helpful? Yes | No

    Smile

    this might help - untried by me

    EDIT: My uploads do not appear to work?? - I put the file here as well
    http://www.cruxanalysis.com/temp/softwarereset.pdf
    Attached Images Attached Images  
    Last edited by paul borgmeier; - 18th October 2006 at 05:27.
    Paul Borgmeier
    Salt Lake City, UT
    USA
    __________________

  11. #11
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    Brian,

    Which model LCD do you have from Densitron? They list 20 diffeent 2x16's.

    How long is the cable to the LCD?

    I looked at a couple of the desitron datasheets, they seem to be within the spec's for PBP's LCDOUT timing.

    And, RS can be either high or low during a write. It would be 0 for a command such as Clear Screen, or 1 to write data to memory.
    <br>
    DT

  12. #12
    Join Date
    Mar 2003
    Posts
    41


    Did you find this post helpful? Yes | No

    Default LCD frustrations

    Hi Darrel,
    I do not have any Densitron LCDs, The LCDs I am using (I have 3) have data sheets viewable at
    https://secure4.vivid-design.com.au/...ed/QP-5515.pdf
    They are Chinese as are most things these days. The supplied documentation is pretty sparse. I only mentioned Densitron as they were the first appnotes I found with any discussion of setup lines and handshake timings.

    I have tried all three LCDs and they all behave the same. I have tried cable lengths from 35 to 400 mm - no difference. The LCD will work most times after a direct MCLR reset. That is, power up, wait a few seconds then manually ground MCLR.

    I tried the following code which sets up the interface with Enable already high, waits a short while then takes Enable low for each of the data states described in the manual. I think I have these correct. This code clears the 'all black' LCD cells shortly after startup but then leaves the LCD bank - as though it is turned off in software despite my having the LCD ON bits enabled (or so I think). I have tried a range of PAUSE times to no avail.

    I also tried setting up the interface with Enable low, strobing Enable high for 100 uSecs then moving on to the next setup state. No joy there either.

    'attention
    for a = 0 to 1 ' call attention mode several times
    portd = %00010011 ' attention request
    pause 1
    portd = %00000011 'drop ENABLE
    pause 5
    next a

    'set 4 bit mode
    portd = %00010010 'set 4 bit mode
    pause 5
    portd = %00000010 ' drop enable
    pause 5

    'set function
    portd = %00010010 'first nibble
    pause 5 'allow setup time
    portd = %00000010
    pause 5
    portd = %00011000 'select 2 lines 5x7 character set
    pause 5 'allow setup time
    portd= %00001000 'low ENABLE
    pause 5

    'display OFF
    portd = %00010000 'first nibble
    pause 5 'allow setup time
    portd = %00000000 'low ENABLE
    pause 5
    portd = %00011000 '
    pause 5 'allow setup time
    portd = %00001000 'low ENABLE
    pause 5

    'display ON
    portd = %00010000 'first nibble
    pause 5 'allow setup time
    portd = %00000000 'low ENABLE
    pause 5
    portd = %00010001 '
    pause 5 'allow setup time
    portd = %00000001 '
    pause 5

    'set entry mode
    portd = %00010000 'first nibble
    pause 5 'allow setup time
    portd = %00000000
    pause 5
    portd = %00010110 '
    pause 5 'allow setup time
    portd = %00000110
    pause 5

    'display ON
    portd = %00010000 'first nibble
    pause 5 'allow setup time
    portd = %00000000
    pause 5
    portd = %00010001 '
    pause 5 'allow setup time
    portd = %00000001
    pause 5

    I will try with another brand of LCD I have at home tonight.

    Driving me crazy.
    Brian

  13. #13
    Join Date
    Jan 2006
    Location
    Istanbul
    Posts
    1,185


    Did you find this post helpful? Yes | No

    Default

    Ok. I know the issue.

    Are you using 4K7 on MCLR?
    If so, change it to 10K first.

    Then, as mister_e repeated, change BOD_OFF to BOD_ON. This should take care of your problem.


    (fingers crossed).
    "If the Earth were a single state, Istanbul would be its capital." Napoleon Bonaparte

  14. #14
    malc-c's Avatar
    malc-c Guest


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by sayzer
    Ok. I know the issue.

    Are you using 4K7 on MCLR?
    If so, change it to 10K first.
    If I read post #7 correctly he already is using a 10K resitor

    I have tried 100 nf, 1uf and 10 uF as the MCLR capacitor with 10k to +5.
    Crossing fingers didn't work on this occasion

  15. #15
    Join Date
    Jan 2006
    Location
    Istanbul
    Posts
    1,185


    Did you find this post helpful? Yes | No

    Default

    Still finger crossed for BOD_ON issue.

    Even if it is a must to use, at least he can try and see if it is the issue.
    "If the Earth were a single state, Istanbul would be its capital." Napoleon Bonaparte

  16. #16
    Join Date
    Sep 2004
    Location
    montreal, canada
    Posts
    6,898


    Did you find this post helpful? Yes | No

    Default

    I bet on LVP. But i'll have a look to the datasheet of the LCD.

    What happen if you use a 4MHZ osc?
    Steve

    It's not a bug, it's a random feature.
    There's no problem, only learning opportunities.

  17. #17
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    Brian,

    I see what you mean about the minimum power-up time of 10ms and the big power supply. Couple things you might try.

    If you have an extra pin available? You could use that to power the LCD. It would allow a nice fast rise time independant of the power supply. It only draws 4-5ma for the logic. Power the backlight separately (if there is one).

    Or, if you want to try the software initialization. Here's something I threw together.

    The datasheet shows a slightly different init sequence than a normal HD44780. It doesn't even say which driver chip the display uses.

    This routine follows the datasheet, and over emphasizes the delays, just in case. (16F only)
    Code:
    ;---- Change these to match your hardware ---------------------------
    @ Device pic16F877A, HS_OSC, BOD_OFF, PWRT_ON, WDT_ON, PROTECT_OFF
    DEFINE OSC 20
    DEFINE LOADER_USED 1 
    
    DEFINE LCD_DREG PORTD   ' Set LCD Data port
    DEFINE LCD_DBIT 0       ' Set starting Data bit (0 or 4) if 4-bit bus
    DEFINE LCD_RSREG PORTD  ' Set LCD Register Select port
    DEFINE LCD_RSBIT 5      ' Set LCD Register Select bit
    DEFINE LCD_EREG PORTD   ' Set LCD Enable port
    DEFINE LCD_EBIT 4       ' Set LCD Enable bit
    DEFINE LCD_BITS 4       ' Set LCD bus size (4 or 8 bits)
    DEFINE LCD_LINES 2      ' Set number of lines on LCD
    
    ;CMCON = 7               ' if needed
    ;ADCON1 = 7
    ;--------------------------------------------------------------------
    
    GOSUB LCD_INIT          ' Do manual LCD Initialization
    
    LCDOUT "Hello World!"
    
    stop
    
    ;---- Manual LCD Initialization -------------------------------------
    TempB     VAR BYTE
    BUSdata   VAR BYTE
    
    Send4Bit:
        @ MOVE?CT  1, LCD_EREG,LCD_EBIT       ; Enable LCD
    @   MOVE?BB  LCD_DREG, _TempB             ; Put Data on the Bus R-M-W
    @   if LCD_DBIT == 0                      ;   Bus starts at 0
            TEMPB = (TEMPB & $F0) | BUSdata
    @   else                                  ;   Bus starts at 4
            TEMPB = (TEMPB & $0F) | (BUSdata << 4)
    @   endif
    @   MOVE?BB  _TempB, LCD_DREG  
        
        PAUSEUS 25                            ; Keep enabled extra long
        @ MOVE?CT  0, LCD_EREG,LCD_EBIT       ; Disable LCD
        Pauseus 50
    return
    ;-----------------------------------------
    LCD_INIT:
        @ MOVE?CT  0, LCD_RSREG,LCD_RSBIT     ; Start with RS LOW
        @ MOVE?CT  0, LCD_RSREG+80h,LCD_RSBIT ; RS is OUTPUT
        
        @ MOVE?CT  0, LCD_EREG,LCD_EBIT       ; Start with Enable LOW
        @ MOVE?CT  0, LCD_EREG+80h,LCD_EBIT   ; Enable is OUTPUT
    
        @ MOVE?CT  0, LCD_DREG+80h,LCD_DBIT   ; Data Bus is OUTPUT
        @ MOVE?CT  0, LCD_DREG+80h,LCD_DBIT +1
        @ MOVE?CT  0, LCD_DREG+80h,LCD_DBIT +2
        @ MOVE?CT  0, LCD_DREG+80h,LCD_DBIT +3
        
        PAUSE 1000
        BUSdata = 3
        GOSUB Send4Bit : pause 8              ; FunctionSet 4 times
        GOSUB Send4Bit : pauseUS 200
        GOSUB Send4Bit : pauseUS 200
        GOSUB Send4Bit : pauseUS 200
        BUSdata = 2  :  GOSUB Send4Bit        ; 4-bit mode
    
        BUSdata = 2  :  GOSUB Send4Bit        ; 2-line, 5x7
        BUSdata = 8  :  GOSUB Send4Bit        
        
        BUSdata = 0  :  GOSUB Send4Bit        ; Display OFF
        BUSdata = 8  :  GOSUB Send4Bit
        
        BUSdata = 0  :  GOSUB Send4Bit        ; Display Clear
        BUSdata = 1  :  GOSUB Send4Bit
        PAUSE 3
    
        BUSdata = 0  :  GOSUB Send4Bit        ; Entry Mode Set
        BUSdata = 6  :  GOSUB Send4Bit
        PAUSE 3
        
        BUSdata = 0  :  GOSUB Send4Bit        ; Display ON
        BUSdata = $C :  GOSUB Send4Bit
        
        @  MOVE?CT 1, LCDINITFLAG   ; Tell PBP LCD is already Initialized
    return
    ;---------- END LCD_INIT --------------------------------------------
    HTH,
    Last edited by Darrel Taylor; - 19th October 2006 at 00:29. Reason: Changed Defines to match original Post
    DT

  18. #18
    Join Date
    Mar 2003
    Posts
    41


    Did you find this post helpful? Yes | No

    Default

    Hi Darrel,
    Thanks for all the effort you have put into this. Below is my entire program, using your LCD code. It still does not work - the LCD top line are dark squares and the lower line is all blanks. I tried a different brand of LCD this morning - same story.

    I want to use a backlit LCD which draws about 100 mA so I could cut a trace and add a PNP high side switch but I would rather not if a software fix can be found.

    The code fuses in the PIC16F877A (set via EPIC) include LVP OFF, WDT ON, BOD ON, POR ON for those asking about LVP.

    I need to fully understand what your code does as it looks similar to what I am trying in a sequence of PBP247 lines. Where can I find an explanation of the instructions used in your code? I can make sense of some lines but I don't know what is happening with...

    @ MOVE?CT 0, LCD_EREG+80h,LCD_EBIT ; Enable is OUTPUT
    Does this OR together the Enable bit with 80 hex?

    @ MOVE?CT 0, LCD_DREG+80h,LCD_DBIT +1
    @ MOVE?CT 0, LCD_DREG+80h,LCD_DBIT +2
    @ MOVE?CT 0, LCD_DREG+80h,LCD_DBIT +3
    What does the +1, +2, +3 do?

    I do want to end up with a bullet proof LCD startup sequence, preferably all written in PBP, that can reliably work with slow start power supplies. The PIC 16F877A data sheet (parameter D004) shows a PIC can work with power supply dV/dT as low as 50 volts per second (i.e. 100 mS power supply rise time). I want to be sure the LCD will also work in that environment or this problem will bite me again and again in other designs as well.

    The full code follows

    data @0, 0 'Action Flags
    data @1, 0 'Status flags
    Data @2, "PW50 Gas Mix LCD fix BDT 19 OCT 06 "


    define osc 20
    define loader_used 1
    Define LCD_DREG PORTD
    Define LCD_DBIT 0
    Define LCD_RSREG PORTD
    Define LCD_RSBIT 5
    Define LCD_EREG PORTD
    Define LCD_EBIT 4
    DEFINE LCD_LINES 2
    DEFINE LCD_BITS 4
    'DEFINE LCD_COMMANDUS 5000 'Command delay time in us
    'DEFINE LCD_DATAUS 250 'Data delay time in us
    define char_pacing 200
    DEFINE SHIFT_PAUSEUS 500


    @ Device pic16F877A, HS_OSC, BOD_ON, LVP_OFF, PWRT_ON, WDT_ON, PROTECT_OFF

    '***************** hardware definition ***********************
    'PortA
    Function var porta.0 'pin 2 analog from 12 position switch IN
    RunStop var porta.1 ' SWp6 to 877p3 Front panel toggle IN
    Enter var porta.2 ' SWp4 to 877p4 Selects current value IN
    Up var porta.3 ' SWp2 to 877p5 Advances selection IN
    AutoMan var porta.4 ' SWp7 to 877p6 Local/Remote control IN
    Down var porta.5 ' SWp3 to 877p7 Reduces selection IN
    TRISA = %00011111
    CMCON = %00000111 ' comparators disabled
    ADCON0 = %11000000 ' int RC clock, ADC disabled
    ADCON1 = %11001110 ' port 0 analog, all others digital

    'PortB
    GMData var portb.0 'bidirecional data to/from Master Controller
    GMStrobe1 var portb.1 'signals MC that GM needs attention
    GMStrobe2 var portb.2 'signals GM that MC has data
    GMSpare var portb.3 'a PCB trace between PeeWee50 pin 9 and 877p36
    LED2 var portb.4 'front panel LED2
    N2 var portb.5 'Nitrogen solenoid
    SClk var portb.6 'Intersema SClk OUT to MS5534 & 5535
    DIn var portb.7 'Intersems Data In OUT from 877a to MS5534 & 5535
    TRISB = %00001111
    PortB = %00000000

    'PortC
    CO2 var portc.0 'CO2 solenoid
    O2 var portc.1 'O2 solenoid
    MClk var portc.2 'MClk to Intersema PWM2 32678 Hz OUT to MS5534/5
    Vent var portc.3 'Vent/dump solenoid
    Delvry var portc.4 'delivery solenoid controls final delivery
    SpareSol var portc.5 'spare solenoid OUT
    TxD var portc.6 'Boot loader and RS232 OUT
    RxD var portc.7 'Boot & RS232 IN
    TRISC = %10000000
    PortC = %00000000

    'PortD
    DB4 var portd.0 'Data bit 4 to LCD
    DB5 var portd.1 'Data bit 5 to LCD
    DB6 var portd.2 'Data bit 6 to LCD
    DB7 var portd.3 'Data bit 7 to LCD
    LCDEnable var portd.4 'LCD ENABLE line OUT to LCD
    RegSel var portd.5 'LCD Register Select OUT to LCD
    ReadWrite var portd.6 'LCD Read/Write line OUT to LCD
    LED1 var portd.7 'Front Panel LED1
    TRISD = %00000000
    'PortD = %00110000
    PortD = %00000000

    'PortE
    ClrEntry var porte.0 'SWp5 to 877p8 Clears entry on front panel??? IN
    Dout1 var porte.1 'Input from 14 bar Intersema
    Dout2 var porte.2 'Input from 1 bar Intersema
    TRISE = %11111111
    PortE = %00000000

    '******************* Variable assignments *********************
    'OPTION_REG = %10001111 ' no pullups, prescaler to WDT /128

    A var byte ' General purpose Variable
    B var byte ' General purpose Variable
    C var byte ' General purpose Variable
    I var byte
    J var byte
    K var byte
    FuncSel var byte ' Switch position after decoding ADC value
    ADCval var word
    LoopCtr var byte
    U var word
    V var word
    W var word
    X var word
    Y var word
    Z var word
    RunFlag var bit
    C1 var word ' Pressure sensitivity
    C2 var word ' Pressure Offset
    C3 var word ' Temp Coef of pressure sensitivity
    C4 var word ' Temp Coef of Pressure Offset
    C5 var word ' Reference temperature
    C6 var word ' Temp coef of Temp reading
    D1 var word ' raw word from 5535
    D2 var word ' raw word from 5535
    W1 var word ' coefficient from 5535
    W2 var word ' coefficient from 5535
    W3 var word ' coefficient from 5535
    W4 var word ' coefficient from 5535
    dT var word ' intermediate calc value
    UT1 var word ' Calibration temperature
    Temp var word ' Sensor temperature
    Tempnegflag var bit ' set if temperature is below zero C
    Press var word ' Pressure
    Offset var word '
    Sens var word '


    'DDDDDD Darrel's code here DDDDDDDDDDDDDDDDDDDDDDDDDDDD
    ;---- Change these to match your hardware ---------------------------
    ' done above
    ;--------------------------------------------------------------------

    low readwrite 'put the LCD into write mode
    GOSUB LCD_INIT ' Do manual LCD Initialization

    LCDOUT "Hello World!"
    end
    stop

    ;---- Manual LCD Initialization -------------------------------------
    TempB VAR BYTE
    BUSdata VAR BYTE

    Send4Bit:
    @ MOVE?CT 1, LCD_EREG,LCD_EBIT ; Enable LCD
    @ MOVE?BB LCD_DREG, _TempB ; Put Data on the Bus R-M-W
    @ if LCD_DBIT == 0 ; Bus starts at 0
    TEMPB = (TEMPB & $F0) | BUSdata
    @ else ; Bus starts at 4
    TEMPB = (TEMPB & $0F) | (BUSdata << 4)
    @ endif
    @ MOVE?BB _TempB, LCD_DREG

    PAUSEUS 25 ; Keep enabled extra long
    @ MOVE?CT 0, LCD_EREG,LCD_EBIT ; Disable LCD
    Pauseus 50
    return
    ;-----------------------------------------
    LCD_INIT:
    @ MOVE?CT 0, LCD_RSREG,LCD_RSBIT ; Start with RS LOW
    @ MOVE?CT 0, LCD_RSREG+80h,LCD_RSBIT ; RS is OUTPUT

    @ MOVE?CT 0, LCD_EREG,LCD_EBIT ; Start with Enable LOW
    @ MOVE?CT 0, LCD_EREG+80h,LCD_EBIT ; Enable is OUTPUT

    @ MOVE?CT 0, LCD_DREG+80h,LCD_DBIT ; Data Bus is OUTPUT
    @ MOVE?CT 0, LCD_DREG+80h,LCD_DBIT +1
    @ MOVE?CT 0, LCD_DREG+80h,LCD_DBIT +2
    @ MOVE?CT 0, LCD_DREG+80h,LCD_DBIT +3

    PAUSE 1000
    BUSdata = 3
    GOSUB Send4Bit : pause 8 ; FunctionSet 4 times
    GOSUB Send4Bit : pauseUS 200
    GOSUB Send4Bit : pauseUS 200
    GOSUB Send4Bit : pauseUS 200
    BUSdata = 2 : GOSUB Send4Bit ; 4-bit mode

    BUSdata = 2 : GOSUB Send4Bit ; 2-line, 5x7
    BUSdata = 8 : GOSUB Send4Bit

    BUSdata = 0 : GOSUB Send4Bit ; Display OFF
    BUSdata = 8 : GOSUB Send4Bit

    BUSdata = 0 : GOSUB Send4Bit ; Display Clear
    BUSdata = 1 : GOSUB Send4Bit
    PAUSE 3

    BUSdata = 0 : GOSUB Send4Bit ; Entry Mode Set
    BUSdata = 6 : GOSUB Send4Bit
    PAUSE 3

    BUSdata = 0 : GOSUB Send4Bit ; Display ON
    BUSdata = $C : GOSUB Send4Bit

    @ MOVE?CT 1, LCDINITFLAG ; Tell PBP LCD is already Initialized
    return
    ;---------- END LCD_INIT --------------------------------------------

    end

  19. #19
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    > @ MOVE?CT 0, LCD_EREG+80h,LCD_EBIT ; Enable is OUTPUT
    > Does this OR together the Enable bit with 80 hex?


    It's similar to "TRISx.b = 0", or "OUTPUT pin", but in PBP you can't just "OUTPUT LCD_EREG" or "TRIS.LCD_EREG = 0", so it uses some built in PBP macros to set the TRIS register.

    In a 16F, TRIS is located in BANK1 which starts at 80h. Adding 80h to the address of the PORT register gives the TRIS register address.

    So MOVE?CT 0, LCD_EREG+80h,LCD_EBIT will copy the constant 0 to the TRIS bit that corresponts to the Enable Pin.

    > @ MOVE?CT 0, LCD_DREG+80h,LCD_DBIT +1
    > @ MOVE?CT 0, LCD_DREG+80h,LCD_DBIT +2
    > @ MOVE?CT 0, LCD_DREG+80h,LCD_DBIT +3
    > What does the +1, +2, +3 do?


    Those also set the TRIS bits to output. The +1, +2, +3 selects each of the four bits that will be set to OUTPUT. IF LCD_DBIT = 0, it sets the lower 4 bits to output, otherwise it sets the upper 4 bits.

    <hr>But Wait! There's more!

    In the latest code listing (well, actually it was in the first post too ), it appears that you have the R/W pin hooked up to PORTD.6. But the ...

    Code:
    DEFINE LCD_RWREG PORTD 'LCD read/write port 
    DEFINE LCD_RWBIT 6     'LCD read/write bit
    were not defined.

    There's a good possibility!
    Last edited by Darrel Taylor; - 19th October 2006 at 01:36. Reason: First Post had it too.
    DT

  20. #20
    Join Date
    Mar 2003
    Posts
    41


    Did you find this post helpful? Yes | No

    Default Portd.4 = 1

    Here is my version of your assembler. I have verified on the scope that I can strobe the enable line with lcdenable = 1, delay, then lcdenable = 0.
    this program still will not start with a slow dV/dT but works a treat with a MCLR reset or a 'snap on' power supply.

    I have tried
    DEFINE LCD_RWREG PORTD 'LCD read/write port
    DEFINE LCD_RWBIT 6 'LCD read/write bit
    as well as explicitly raising/lowering the read write line.
    No joy from that quarter.



    define osc 20
    define loader_used 1
    Define LCD_DREG PORTD
    Define LCD_DBIT 0
    Define LCD_RSREG PORTD
    Define LCD_RSBIT 5
    Define LCD_EREG PORTD
    Define LCD_EBIT 4
    DEFINE LCD_LINES 2
    DEFINE LCD_BITS 4
    DEFINE LCD_RWREG PORTD 'LCD read/write port
    DEFINE LCD_RWBIT 6 'LCD read/write bit
    'DEFINE LCD_COMMANDUS 5000 'Command delay time in us
    'DEFINE LCD_DATAUS 250 'Data delay time in us
    define char_pacing 200
    DEFINE SHIFT_PAUSEUS 500

    @ Device pic16F877A, HS_OSC, BOD_ON, LVP_OFF, PWRT_ON, WDT_ON, PROTECT_OFF
    '
    '****************** hardware definition **********************
    'PortA
    Function var porta.0 'pin 2 analog from 12 position switch IN
    RunStop var porta.1 ' SWp6 to 877p3 Front panel toggle IN
    Enter var porta.2 ' SWp4 to 877p4 Selects current value IN
    Up var porta.3 ' SWp2 to 877p5 Advances selection IN
    AutoMan var porta.4 ' SWp7 to 877p6 Local/Remote control IN
    Down var porta.5 ' SWp3 to 877p7 Reduces selection IN
    TRISA = %00011111
    CMCON = %00000111 ' comparators disabled
    ADCON0 = %11000000 ' int RC clock, ADC disabled
    ADCON1 = %11001110 ' port 0 analog, all others digital

    'PortB
    GMData var portb.0 'bidirecional data to/from Master Controller
    GMStrobe1 var portb.1 'signals MC that GM needs attention
    GMStrobe2 var portb.2 'signals GM that MC has data
    GMSpare var portb.3 'a PCB trace between PeeWee50 pin 9 and 877p36
    LED2 var portb.4 'front panel LED2
    N2 var portb.5 'Nitrogen solenoid
    SClk var portb.6 'Intersema SClk OUT to MS5534 & 5535
    DIn var portb.7 'Intersems Data In OUT from 877a to MS5534 & 5535
    TRISB = %00001111
    PortB = %00000000

    'PortC
    CO2 var portc.0 'CO2 solenoid
    O2 var portc.1 'O2 solenoid
    MClk var portc.2 'MClk to Intersema PWM2 32678 Hz OUT to MS5534/5
    Vent var portc.3 'Vent/dump solenoid
    Delvry var portc.4 'delivery solenoid controls final delivery
    SpareSol var portc.5 'spare solenoid OUT
    TxD var portc.6 'Boot loader and RS232 OUT
    RxD var portc.7 'Boot & RS232 IN
    TRISC = %10000000
    PortC = %00000000

    'PortD
    DB4 var portd.0 'Data bit 4 to LCD
    DB5 var portd.1 'Data bit 5 to LCD
    DB6 var portd.2 'Data bit 6 to LCD
    DB7 var portd.3 'Data bit 7 to LCD
    LCDEnable var portd.4 'LCD ENABLE line OUT to LCD
    RegSel var portd.5 'LCD Register Select OUT to LCD
    ReadWrite var portd.6 'LCD Read/Write line OUT to LCD
    LED1 var portd.7 'Front Panel LED1
    TRISD = %00000000
    'PortD = %00110000
    PortD = %00000000

    'PortE
    ClrEntry var porte.0 'SWp5 to 877p8 Clears entry on front panel??? IN
    Dout1 var porte.1 'Input from 14 bar Intersema
    Dout2 var porte.2 'Input from 1 bar Intersema
    TRISE = %11111111
    PortE = %00000000

    '****************** Variable assignments *******************
    'OPTION_REG = %10001111 ' no pullups, prescaler to WDT /128

    A var byte ' General purpose Variable
    B var byte ' General purpose Variable
    C var byte ' General purpose Variable
    I var byte
    J var byte
    K var byte
    FuncSel var byte ' Switch position after decoding ADC value
    ADCval var word
    LoopCtr var byte
    U var word
    V var word
    W var word
    X var word
    Y var word
    Z var word
    RunFlag var bit
    C1 var word ' Pressure sensitivity
    C2 var word ' Pressure Offset
    C3 var word ' Temp Coef of pressure sensitivity
    C4 var word ' Temp Coef of Pressure Offset
    C5 var word ' Reference temperature
    C6 var word ' Temp coef of Temp reading
    D1 var word ' raw word from 5535
    D2 var word ' raw word from 5535
    W1 var word ' coefficient from 5535
    W2 var word ' coefficient from 5535
    W3 var word ' coefficient from 5535
    W4 var word ' coefficient from 5535
    dT var word ' intermediate calc value
    UT1 var word ' Calibration temperature
    Temp var word ' Sensor temperature
    Tempnegflag var bit ' set if temperature is below zero C
    Press var word ' Pressure
    Offset var word '
    Sens var word '


    'portd = 0
    'pause 1
    'Loop2:
    ' portd.4 = 1
    ' pause 1
    ' portd.4 = 0
    ' pause 1
    'goto loop2


    Goto endofsubroutines
    'Subroutines
    Strobe: ' drives the enable line to latch data into LCD
    lcdenable = 1
    pauseus 20
    lcdenable = 0
    pauseus 50
    return

    EndOfSubRoutines:

    InitialiseLCD:
    TRISD = %00000000
    portd = 0 ' set all lines low
    pause 250 ' power up delay
    portd = 3 ' 0011 written to DB7 ~ DB4 Do it 4 times
    gosub strobe
    pause 5 ' > 4.1 mSec
    portd = 3
    gosub strobe
    pauseus 150 '> 100 uSec
    portd = 3
    gosub strobe
    pauseus 150
    portd = 3
    gosub strobe
    pauseus 150
    portd = 2 'function set
    gosub strobe
    portd = 8 'set 2 lines 5x7 font
    gosub strobe
    portd = 0 'display OFF
    gosub strobe
    portd = 8 'display off
    gosub strobe
    portd = 0 'display clear
    gosub strobe
    portd = 1 'display clear
    gosub strobe
    portd = 0 'Entry mode set
    gosub strobe
    portd = 6 'increment position
    gosub strobe
    portd = 0 'display ON
    gosub strobe
    portd = 15
    gosub strobe 'display on, cursor on, blink on

    Loop:
    lcdout $FE, $01
    LCDOUT "Hello "
    pause 500
    lcdout $FE, $01, $FE, $C0
    lcdout "World"
    pause 500
    goto loop

  21. #21
    Join Date
    Sep 2004
    Location
    montreal, canada
    Posts
    6,898


    Did you find this post helpful? Yes | No

    Default

    I second the following...
    Quote Originally Posted by Darrel Taylor
    If you have an extra pin available? You could use that to power the LCD. It would allow a nice fast rise time independant of the power supply. It only draws 4-5ma for the logic. Power the backlight separately (if there is one).
    That would be my first choice.

    Too bad, those LCd don't have internal BOD.
    Last edited by mister_e; - 19th October 2006 at 02:52.
    Steve

    It's not a bug, it's a random feature.
    There's no problem, only learning opportunities.

  22. #22
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    Can I Third that?

    or is that double dipping?
    <br>
    DT

  23. #23
    Join Date
    Mar 2003
    Posts
    41


    Did you find this post helpful? Yes | No

    Default Backlight not separable on SDEC (Electus) LCD

    The LCDs I already purchased from ELECTUS have the backlight permanently ON.

    I still want to solve this problem as we will all come across slow start power supplies sooner or later. If we can find a reliable software reset and incorporate it as standard code our designs will all be better.

    Cheers
    Brian

  24. #24
    Join Date
    Mar 2003
    Posts
    41


    Did you find this post helpful? Yes | No

    Default LCD now working

    Problem solved.

    I originally had my TRIS statements immediately following the port definitions. By making the first line of my code a PAUSE 2500 statement followed by the TRIS etc, the system now works.

    It seems the LCD wants to see floating drive for something more than one second before it is happy. With this approach I can eliminate all my initialise code and just rely on LCDOUT $FE, $01 to somehow do it for me.

    The following code now works on both slow start and fast start power supplies as well as a direct MCLR.

    define osc 20
    define loader_used 1
    Define LCD_DREG PORTD
    Define LCD_DBIT 0
    Define LCD_RSREG PORTD
    Define LCD_RSBIT 5
    Define LCD_EREG PORTD
    Define LCD_EBIT 4
    DEFINE LCD_LINES 2
    DEFINE LCD_BITS 4
    DEFINE LCD_RWREG PORTD 'LCD read/write port
    DEFINE LCD_RWBIT 6 'LCD read/write bit
    DEFINE LCD_COMMANDUS 2000 'Command delay time in us
    DEFINE LCD_DATAUS 100 'Data delay time in us
    define char_pacing 200
    DEFINE SHIFT_PAUSEUS 100

    @ Device pic16F877A, HS_OSC, BOD_ON, LVP_OFF, PWRT_ON, WDT_ON, PROTECT_OFF
    '@__config_HS_OSC &_BOD_OFF &_PWRT_ON &_WDT_ON &_PROTECT_OFF &_LVP_OFF

    '**************** hardware definition **************
    'PortA
    Function var porta.0 'pin 2 analog from 12 position switch IN
    RunStop var porta.1 ' SWp6 to 877p3 Front panel toggle IN
    Enter var porta.2 ' SWp4 to 877p4 Selects current value IN
    Up var porta.3 ' SWp2 to 877p5 Advances selection IN
    AutoMan var porta.4 ' SWp7 to 877p6 Local/Remote control IN
    Down var porta.5 ' SWp3 to 877p7 Reduces selection IN
    'TRISA = %00011111
    'CMCON = %00000111 ' comparators disabled
    'ADCON0 = %11000000 ' int RC clock, ADC disabled
    'ADCON1 = %11001110 ' port 0 analog, all others digital

    'PortB
    GMData var portb.0 'bidirecional data to/from Master Controller
    GMStrobe1 var portb.1 'signals MC that GM needs attention
    GMStrobe2 var portb.2 'signals GM that MC has data
    GMSpare var portb.3 'a PCB trace between PeeWee50 pin 9 and 877p36
    LED2 var portb.4 'front panel LED2
    N2 var portb.5 'Nitrogen solenoid
    SClk var portb.6 'Intersema SClk OUT to MS5534 & 5535
    DIn var portb.7 'Intersems Data In OUT from 877a to MS5534 & 5535

    'TRISB = %00001111
    'PortB = %00000000

    'PortC
    CO2 var portc.0 'CO2 solenoid
    O2 var portc.1 'O2 solenoid
    MClk var portc.2 'MClk to Intersema PWM2 32678 Hz OUT to MS5534/5
    Vent var portc.3 'Vent/dump solenoid
    Delvry var portc.4 'delivery solenoid controls final delivery
    SpareSol var portc.5 'spare solenoid OUT
    TxD var portc.6 'Boot loader and RS232 OUT
    RxD var portc.7 'Boot & RS232 IN
    'TRISC = %10000000
    'PortC = %00000000

    'PortD
    DB4 var portd.0 'Data bit 4 to LCD
    DB5 var portd.1 'Data bit 5 to LCD
    DB6 var portd.2 'Data bit 6 to LCD
    DB7 var portd.3 'Data bit 7 to LCD
    LCDEnable var portd.4 'LCD ENABLE line OUT to LCD
    RegSel var portd.5 'LCD Register Select OUT to LCD
    ReadWrite var portd.6 'LCD Read/Write line OUT to LCD
    LED1 var portd.7 'Front Panel LED1
    'TRISD = %00000000
    ''PortD = %00110000
    'PortD = %00000000

    'PortE
    ClrEntry var porte.0 'SWp5 to 877p8 Clears entry on front panel??? IN
    Dout1 var porte.1 'Input from 14 bar Intersema
    Dout2 var porte.2 'Input from 1 bar Intersema
    'TRISE = %11111111
    'PortE = %00000000

    '******************** Variable assignments ************************
    'OPTION_REG = %10001111 ' no pullups, prescaler to WDT /128

    A var byte ' General purpose Variable
    B var byte ' General purpose Variable
    C var byte ' General purpose Variable
    I var byte
    J var byte
    K var byte
    FuncSel var byte ' Switch position after decoding ADC value
    ADCval var word
    LoopCtr var byte
    U var word
    V var word
    W var word
    X var word
    Y var word
    Z var word
    RunFlag var bit
    C1 var word ' Pressure sensitivity
    C2 var word ' Pressure Offset
    C3 var word ' Temp Coef of pressure sensitivity
    C4 var word ' Temp Coef of Pressure Offset
    C5 var word ' Reference temperature
    C6 var word ' Temp coef of Temp reading
    D1 var word ' raw word from 5535
    D2 var word ' raw word from 5535
    W1 var word ' coefficient from 5535
    W2 var word ' coefficient from 5535
    W3 var word ' coefficient from 5535
    W4 var word ' coefficient from 5535
    dT var word ' intermediate calc value
    UT1 var word ' Calibration temperature
    Temp var word ' Sensor temperature
    Tempnegflag var bit ' set if temperature is below zero C
    Press var word ' Pressure
    Offset var word '
    Sens var word '


    pause 2500 '
    TRISA = %00011111
    CMCON = %00000111 ' comparators disabled
    ADCON0 = %11000000 ' int RC clock, ADC disabled
    ADCON1 = %11001110 ' port 0 analog, all others digital
    TRISB = %00001111
    PortB = %00000000
    TRISC = %10000000
    PortC = %00000000
    TRISD = %00000000
    PortD = %00000000
    TRISE = %11111111
    PortE = %00000000


    Loop:
    lcdout $FE, $01
    LCDOUT "Hello "
    pause 500
    lcdout $FE, $01, $FE, $C0
    lcdout "World"
    pause 500
    goto loop

    end


    thanks to all who helped.

    Cheers
    Brian

  25. #25
    Join Date
    Sep 2004
    Location
    montreal, canada
    Posts
    6,898


    Did you find this post helpful? Yes | No

    Default

    <img src="http://img8.picsplace.to/img8/22/Thumbs-up.gif">
    Steve

    It's not a bug, it's a random feature.
    There's no problem, only learning opportunities.

  26. #26
    Join Date
    May 2007
    Posts
    14


    Did you find this post helpful? Yes | No

    Question New to HD44780, MCU & PBP. - Need LCD Help

    Hello, everyone.

    I am new to this forum. I am so happy to see so many people helping out others. I wish I could be of help myself in the future.

    I have been tracking problems in HD44780. I think this could be the closest problem solved that is relevant to my problem.

    I have two HD44780 that I am currently getting to work. One is a 16x2 and another 20x4. I am using Pic Basic Pro & PIC16F627A. I pick this chip because I would like to simplify without the External Osc components. I am currently using a solderless breadboard.

    Currently,
    for the 16x2, I got 16 blocks on first line and blank on 2nd line.
    for the 20x4, I am getting 20 blocks of 1st & 3rd lines, rest are blank.



    So far, my code is

    ' HD44780 LCD MODULE
    ' Pin 1: VSS 0V(Ground)
    ' Pin 2: VDD Power Supply for logic
    ' Pin 3: V0 Power Supply for LCD Driver (5k Potentiometer for Contrast)
    ' Pin 4: RS Data / Instruction register select (10k Resistor)
    ' Pin 5: R/W Read/Write select
    ' Pin 6: E Read/Write enable strobe
    ' Pin 11-14: DB0-7 Data bus (LSB)
    ' Pin 15: LED Backlight (5.0v)
    ' Pin 16: LED Backlight (0v)
    '
    ' PIC16F627A
    ' Pin 1: RA2 LCD DB6
    ' Pin 2: RA3 LCD DB7
    ' Pin 3: RA4 LCD RS (10k Voltage Pullup to +5v)
    ' Pin 5: VSS Ground
    ' Pin 9: RB3 LCD E
    ' Pin 14: VDD
    ' Pin 17: RA0 LCD DB4
    ' Pin 18: RA1 LCD DB5
    '
    ' LCD Definition
    DEFINE LCD_DREG PORTA ' Set LCD Data port
    DEFINE LCD_DBIT 0 ' Set starting Data bit (0 or 4) if 4-bit bus
    DEFINE LCD_RSREG PORTB ' Set LCD Register Select port
    DEFINE LCD_RSBIT 4 ' Set LCD Register Select bit
    DEFINE LCD_EREG PORTB ' Set LCD Enable port
    DEFINE LCD_EBIT 3 ' Set LCD Enable bit
    DEFINE LCD_BITS 4 ' Set LCD bus size (4 or 8 bits)
    DEFINE LCD_LINES 2 ' Set number of lines on LCD
    ' DEFINE LCD_LINES 4 ' Set number of lines on LCD
    DEFINE LCD_COMMANDUS 2000 ' Set command delay time in us
    DEFINE LCD_DATAUS 50 ' Set data delay time in us

    CMCON = 7 ' RA0-RA3 are digital I/O
    TRISA = 0 ' PORT A is output
    TRISB = 0 ' PORT B is output


    RPT:
    LCDOUT $FE,1 ' Clear LCD
    LCDOUT $FE, $0C 'Cursor off
    LCDOUT $FE, $0F ' Blinking cursor on
    PAUSE 500 ' Wait 0.5 second for LCD to startup

    ' For 16x2 LCD
    LCDOUT $FE,2, "Hello." ' Display 1st Line
    LCDOUT $FE,$C0, "World." ' Display 2nd Line
    ' For 20x4 LCD
    ' LCDOUT $FE,2, "Hello." ' Display 1st Line
    ' LCDOUT $FE,$C0, "World." ' Display 2nd Line
    ' LCDOUT $FE,$94, "Line 3" ' Display 3rd Line
    ' LCDOUT $FE,$D4, "Line 4" ' Display 4th Line

    PAUSE 10000 ' Wait 10 second

    GOTO RPT ' Repeat

    END ' End of program


    I think based on code below. It appear that I am missing

    define osc 20
    define loader_used 1
    @ Device pic16F877A, HS_OSC, BOD_ON, LVP_OFF, PWRT_ON, WDT_ON, PROTECT_OFF

    for 16F627, what should my parameters be?
    define osc 4 ? for pic16f627a
    What is the usage for all these statements? Are they all required?
    Can someone kindly explain? And show me where these material (an perhaps more) are documented?

    Also, do I still need the following three PBP statements. Are they redundant with the DEFINE statements?
    CMCON = 7 ' RA0-RA3 are digital I/O
    TRISA = 0 ' PORT A is output
    TRISB = 0 ' PORT B is output

    What is the best way to test if my internal OSC function is working?

    Since I am so new to all the elements, can someone tell me where how to pin down my LCD problem(s). Any help would be greatly appreciated.



    Hello, everyone.

    After I posted, I just added following statements to my code. Still no help.

    define osc 4 ' Internal OSC 4 MHZ
    define loader_used 1 ' ?
    @ Device pic16F627A, HS_OSC, BOD_ON, LVP_OFF, PWRT_ON, WDT_ON, PROTECT_OFF


    I am also new to both pic chip and LCD module. I have used voltmeter to check the voltages at each point. How do I conduct proper hardware check. I have been through many times on regarding the pin / wiring connection. How do I know if my chip is defective? How do I know if my LCD is defective? Thank you for reading.

    John Paul
    Michigan

    Quote Originally Posted by btaylor View Post
    Problem solved.

    I originally had my TRIS statements immediately following the port definitions. By making the first line of my code a PAUSE 2500 statement followed by the TRIS etc, the system now works.

    It seems the LCD wants to see floating drive for something more than one second before it is happy. With this approach I can eliminate all my initialise code and just rely on LCDOUT $FE, $01 to somehow do it for me.

    The following code now works on both slow start and fast start power supplies as well as a direct MCLR.

    define osc 20
    define loader_used 1
    Define LCD_DREG PORTD
    Define LCD_DBIT 0
    Define LCD_RSREG PORTD
    Define LCD_RSBIT 5
    Define LCD_EREG PORTD
    Define LCD_EBIT 4
    DEFINE LCD_LINES 2
    DEFINE LCD_BITS 4
    DEFINE LCD_RWREG PORTD 'LCD read/write port
    DEFINE LCD_RWBIT 6 'LCD read/write bit
    DEFINE LCD_COMMANDUS 2000 'Command delay time in us
    DEFINE LCD_DATAUS 100 'Data delay time in us
    define char_pacing 200
    DEFINE SHIFT_PAUSEUS 100

    @ Device pic16F877A, HS_OSC, BOD_ON, LVP_OFF, PWRT_ON, WDT_ON, PROTECT_OFF
    '@__config_HS_OSC &_BOD_OFF &_PWRT_ON &_WDT_ON &_PROTECT_OFF &_LVP_OFF
    Last edited by JohnPaul; - 21st May 2007 at 02:48. Reason: Update & Typos

  27. #27
    skimask's Avatar
    skimask Guest


    Did you find this post helpful? Yes | No

    Default

    Add the
    PAUSE 500
    BEFORE you send ANYTHING out to the LCD...
    And try PAUSE 2000 and work your way down to a managable value.

  28. #28
    Join Date
    May 2007
    Posts
    14


    Did you find this post helpful? Yes | No

    Default

    Hi, skimask.

    Thank you for the reply.

    I added PAUSE 2000 before CMCON=7 statement.

    On my 20x4, I still get 20 blocks on lines 1 & 3.. and rest are blanks.


    Regards,
    John Paul

  29. #29
    skimask's Avatar
    skimask Guest


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by JohnPaul View Post
    Hi, skimask.
    Thank you for the reply.
    I added PAUSE 2000 before CMCON=7 statement.
    On my 20x4, I still get 20 blocks on lines 1 & 3.. and rest are blanks.
    Regards,
    John Paul
    Hook up an LED to a spare pin, and rewrite the program to blink it once per second along with running your LCD. That should tell you that the program is running in the first place.
    Note: I ALWAYS use a 'heartbeat' LED in my projects, doesn't matter what it is, or how I tie it into the main program, so long as I know how it's supposed to be blinking, whether I tie it into an interrupt, or just part of the main loop or whatever...doesn't really matter. And I usually don't remove the 'heartbeat' LED until I'm almost done, or I need that particular pin.

  30. #30
    Join Date
    Aug 2006
    Location
    Look, behind you.
    Posts
    2,818


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by JohnPaul View Post
    Code:
    ' HD44780 LCD MODULE
    ' Pin 1: VSS 0V(Ground)
    ' Pin 2: VDD Power Supply for logic
    ' Pin 3: V0 Power Supply for LCD Driver (5k Potentiometer for Contrast)
    ' Pin 4: RS Data / Instruction register select (10k Resistor)
    ' Pin 5: R/W Read/Write select
    ' Pin 6: E Read/Write enable strobe
    ' Pin 11-14: DB0-7 Data bus (LSB)
    ' Pin 15: LED Backlight (5.0v)
    ' Pin 16: LED Backlight (0v)
    '
    ' PIC16F627A
    ' Pin 1: RA2 LCD DB6
    ' Pin 2: RA3 LCD DB7
    ' Pin 3: RA4 LCD RS (10k Voltage Pullup to +5v)
    ' Pin 5: VSS Ground
    ' Pin 9: RB3 LCD E
    ' Pin 14: VDD
    ' Pin 17: RA0 LCD DB4
    ' Pin 18: RA1 LCD DB5
    '
    ' LCD Definition
    DEFINE LCD_DREG PORTA ' Set LCD Data port
    DEFINE LCD_DBIT 0 ' Set starting Data bit (0 or 4) if 4-bit bus
    DEFINE LCD_RSREG PORTB ' Set LCD Register Select port
    DEFINE LCD_RSBIT 4 ' Set LCD Register Select bit
    DEFINE LCD_EREG PORTB ' Set LCD Enable port
    DEFINE LCD_EBIT 3 ' Set LCD Enable bit
    DEFINE LCD_BITS 4 ' Set LCD bus size (4 or 8 bits)
    DEFINE LCD_LINES 2 ' Set number of lines on LCD
    ' DEFINE LCD_LINES 4 ' Set number of lines on LCD
    DEFINE LCD_COMMANDUS 2000 ' Set command delay time in us
    DEFINE LCD_DATAUS 50 ' Set data delay time in us
    
    CMCON = 7 ' <font color=red>disable analog comparators</font color>RA0-RA3 are digital I/O
    TRISA = 0 ' PORT A is output
    TRISB = 0 ' PORT B is output
    <font color = red> Pause 1000</font color>
    
    RPT:
    LCDOUT $FE,1 ' Clear LCD
    LCDOUT $FE, $0C 'Cursor off
    LCDOUT $FE, $0F ' Blinking cursor on
    PAUSE 500 ' Wait 0.5 second for LCD to startup
    
    ' For 16x2 LCD
    LCDOUT $FE,2, "Hello." ' Display 1st Line
    LCDOUT $FE,$C0, "World." ' Display 2nd Line
    ' For 20x4 LCD
    ' LCDOUT $FE,2, "Hello." ' Display 1st Line
    ' LCDOUT $FE,$C0, "World." ' Display 2nd Line
    ' LCDOUT $FE,$94, "Line 3" ' Display 3rd Line
    ' LCDOUT $FE,$D4, "Line 4" ' Display 4th Line
    
    PAUSE 10000 ' Wait 10 second
    
    GOTO RPT ' Repeat
    
    END ' End of program

    After I posted, I just added following statements to my code. Still no help.

    define osc 4 ' Internal OSC 4 MHZ<font color=red> add intrc</font color>
    define loader_used 1 ' <font color=red> makes bootloader work</font color>?
    @ Device pic16F627A, BOD_ON, LVP_OFF, PWRT_ON, WDT_ON, PROTECT_OFF,<font color=red> INTRC_OSC_NOCLKOUT </font color>

    Hello John Paul,
    I made some minor tweaks in red above, also be advised RA4 is an open drain output..edit: Oh I see the resistor in your comments, so you got that covered.
    JS
    Last edited by Archangel; - 21st May 2007 at 10:55.
    If you do not believe in MAGIC, Consider how currency has value simply by printing it, and is then traded for real assets.
    .
    Gold is the money of kings, silver is the money of gentlemen, barter is the money of peasants - but debt is the money of slaves
    .
    There simply is no "Happy Spam" If you do it you will disappear from this forum.

  31. #31
    Join Date
    May 2007
    Posts
    14


    Did you find this post helpful? Yes | No

    Default

    Ski,
    I am still using the same chip PIC16F627A.
    I failed the LED test. I hook up an LED to the Ground then in series to 330 ohm Resistor and a cable at the end. I tap the cable to +5V and tested the LED polarity. Then I tap each of the pin. I tried one LED then also tried all of the output pins. Program below.
    How could I have damaged my chip? It is new. How could I be certain my chip is damaged before I toss it to the trash can?

    LED6 VAR PORTB.0 ' Pin LED Test
    TRISB = 0 ' PORT B is output
    RPT:
    PAUSE 2000 ' WAIT 1 SECOND
    LED6 = 1 ' Turn Pin LED ON

    PAUSE 2000 ' WAIT 1 SECOND
    LED6 = 0 ' Turn Pin LED OFF

    GOTO RPT ' Repeat

    END ' End of program

    Also tried them all and none of the LED turned on.

    LED1 VAR PORTA.2 ' Pin LED Test
    LED2 VAR PORTA.3 ' Pin LED Test
    LED3 VAR PORTA.4 ' Pin LED Test
    LED4 VAR PORTA.5 ' Pin LED Test
    LED6 VAR PORTB.0 ' Pin LED Test
    LED7 VAR PORTB.1 ' Pin LED Test
    LED8 VAR PORTB.2 ' Pin LED Test
    LED9 VAR PORTB.3 ' Pin LED Test
    LED10 VAR PORTB.4 ' Pin LED Test
    LED11 VAR PORTB.5 ' Pin LED Test
    LED12 VAR PORTB.6 ' Pin LED Test
    LED13 VAR PORTB.7 ' Pin LED Test
    LED15 VAR PORTA.6 ' Pin LED Test
    LED16 VAR PORTA.7 ' Pin LED Test
    LED17 VAR PORTA.0 ' Pin LED Test
    LED18 VAR PORTA.1 ' Pin LED Test

    TRISA = 0 ' PORT A is output
    TRISB = 0 ' PORT B is output


    RPT:
    PAUSE 1000 ' WAIT 1 SECOND
    LED1 = 1 ' Turn Pin LED ON
    LED2 = 1 ' Turn Pin LED ON
    LED3 = 1 ' Turn Pin LED ON
    LED4 = 1 ' Turn Pin LED ON
    LED6 = 1 ' Turn Pin LED ON
    LED7 = 1 ' Turn Pin LED ON
    LED8 = 1 ' Turn Pin LED ON
    LED9 = 1 ' Turn Pin LED ON
    LED10 = 1 ' Turn Pin LED ON
    LED11 = 1 ' Turn Pin LED ON
    LED13 = 1 ' Turn Pin LED ON
    LED15 = 1 ' Turn Pin LED ON
    LED16 = 1 ' Turn Pin LED ON
    LED17 = 1 ' Turn Pin LED ON
    LED18 = 1 ' Turn Pin LED ON
    PAUSE 1000 ' WAIT 1 SECOND

    LED1 = 0 ' Turn Pin LED OFF
    LED2 = 0 ' Turn Pin LED OFF
    LED3 = 0 ' Turn Pin LED OFF
    LED4 = 0 ' Turn Pin LED OFF
    LED6 = 0 ' Turn Pin LED OFF
    LED7 = 0 ' Turn Pin LED OFF
    LED8 = 0 ' Turn Pin LED OFF
    LED9 = 0 ' Turn Pin LED OFF
    LED10 = 0 ' Turn Pin LED OFF
    LED11 = 0 ' Turn Pin LED OFF
    LED13 = 0 ' Turn Pin LED OFF
    LED15 = 0 ' Turn Pin LED OFF
    LED16 = 0 ' Turn Pin LED OFF
    LED17 = 0 ' Turn Pin LED OFF
    LED18 = 0 ' Turn Pin LED OFF

    GOTO RPT ' Repeat

    END ' End of program

  32. #32
    Join Date
    May 2007
    Posts
    14


    Did you find this post helpful? Yes | No

    Default

    JoeS,

    Your posts noted and changes made. I am pondering why my chip is not working. If the chip is damaged, won't the programmer verify step resulted in an error? What's next after LED test failed? I have another pci16gf627A chip. I am afraid that I might damage it too.

    Regards,
    JohnPaul

  33. #33
    Join Date
    May 2007
    Posts
    14


    Did you find this post helpful? Yes | No

    Default

    ski,

    I like your 'heartbeat' practice. I would adapt it as my practice too.

    Regards,
    JohnPaul

  34. #34
    skimask's Avatar
    skimask Guest


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by JohnPaul View Post
    ski,

    I like your 'heartbeat' practice. I would adapt it as my practice too.

    Regards,
    JohnPaul
    Put a voltmeter on the OSCx pins. You should get around 2.5v with an external oscillator, or if you've got OSC2 setup as an Fosc/4 output.
    I wouldn't think you smoked a chip...as has been noted before, PICs are fairly tough chips, not unbreakable, but tough.
    And if for some reason, your PIC is running on the 48khz internal clock, your program will run about 83 times slower than it should...in other words it'll take 166 seconds for your LEDs to blink.

  35. #35
    Join Date
    May 2007
    Posts
    14


    Did you find this post helpful? Yes | No

    Smile

    Ski,

    Hmm. I am not yet familiar with the OSC parameter settings.
    I did the LED test without any of the additional DEFINE and @ statements beside the ones that I posted.
    I waited 5-10 minutes for the LED to light up on pin 6. But the chip and bottom of the bread board were getting hot so I pulled the power off.


    I just checked again. I think that I might have really burned my chip this time.
    I placed the voltmeter on 0 and +5V, and I would read +5v. But the moment I connect my +5v cable to VDD (pin 14). The voltmeter reading would drop to 1.67v?


    Regards,
    JohnPaul

  36. #36
    skimask's Avatar
    skimask Guest


    Did you find this post helpful? Yes | No

    Default

    Ok, get rid of everything but the power supply (connect a light bulb across it, verify 5v under a small load, use 3 alkalines or 4 NiCads instead of a power supply), the PIC16F627A, an LED with a 300-ish ohm resistor in series, 10K pullup to +5v on MCLR, and some sort of crystal/oscillator setup on OSC1... and put a small cap across Vdd and Vss on the PIC (very important step here!)

    Double check your pin 1 on the PIC and plug it in.
    Break it down...break it WAY down to bare bones.

    Rewrite the program, simplify it as far as you can, one LED or a group of LEDs, doesn't matter, same thing, blink the LED...

    Let us know what you've got after you get it broke down...

    I don't think you've fried anything (although it's entirely possible), I think you're just forgetting something basic, and when that gets figured out, everything else will fall into place faster than you can spend money on it

  37. #37
    Join Date
    May 2007
    Posts
    14


    Did you find this post helpful? Yes | No

    Smile

    Dear Ski,

    Hahaha... Blinking the LED is the first project in the book and I thought it's so simple so I read all the projects but did not tried any of the LEDs .... skipped all the project all the way to the LCDs. Now, I am back... to LED1.BAS

    I will get a new chip and tried the LED Blinking tomorrow and start anew.
    It's late now.

    Thank you very much! I greatly appreciate your help.

    Regards,
    JohnPaul

  38. #38
    skimask's Avatar
    skimask Guest


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by JohnPaul View Post
    Dear Ski,
    Hahaha... Blinking the LED is the first project in the book and I thought it's so simple so I read all the projects but did not tried any of the LEDs .... skipped all the project all the way to the LCDs. Now, I am back... to LED1.BAS
    I will get a new chip and tried the LED Blinking tomorrow and start anew.
    It's late now.
    Thank you very much! I greatly appreciate your help.
    Regards,
    JohnPaul
    Excellent plan! There's a reason why all these books and websites have Blink.Bas as their first project.
    Once you get that working, you change the blink rate by changing the program, you add a couple of buttons which when pressed will change the blink rate depending on the button press......and it just goes up from there....then you get to spend money buying up neat stuff to play with....which is when the wife starts to disown you and you start to go broke and ...........
    Never mind...
    Enjoy

  39. #39
    Join Date
    Aug 2006
    Location
    Look, behind you.
    Posts
    2,818


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by JohnPaul View Post
    JoeS,

    Your posts noted and changes made. I am pondering why my chip is not working. If the chip is damaged, won't the programmer verify step resulted in an error? What's next after LED test failed? I have another pci16gf627A chip. I am afraid that I might damage it too.

    Regards,
    JohnPaul
    Hi JohnPaul,
    You would think so wouldn't you, but the short answer is no, I have killed a few PICs and had programs verify fine, I think I killed the output transistors while the core of the pic remained undamaged. You would do well if using an old breadboard to either replace it or use an ohmmeter to verify all connections, I have been led to the land of little hair as a result of these.
    JS
    If you do not believe in MAGIC, Consider how currency has value simply by printing it, and is then traded for real assets.
    .
    Gold is the money of kings, silver is the money of gentlemen, barter is the money of peasants - but debt is the money of slaves
    .
    There simply is no "Happy Spam" If you do it you will disappear from this forum.

  40. #40
    Join Date
    May 2007
    Posts
    14


    Did you find this post helpful? Yes | No

    Default

    Joes & Ski,
    Thank you for the help.

    JoeS,
    Using an Ohmeter, which pins do I tap, what to expect and why? I would also do the Ohmeter test on a new chip alongside with this chip in question.

    Regards,
    JohnPaul

Similar Threads

  1. 16f688 LCD what have I done wrong
    By spitfiredriver in forum mel PIC BASIC Pro
    Replies: 6
    Last Post: - 8th August 2009, 20:54
  2. Play with LCD on PICDEM
    By The IceMan in forum mel PIC BASIC
    Replies: 5
    Last Post: - 22nd August 2008, 17:56
  3. Need help with LCD number display.
    By Steve Matson in forum mel PIC BASIC
    Replies: 8
    Last Post: - 27th June 2007, 00:07
  4. Gps with 16f628
    By dragons_fire in forum mel PIC BASIC Pro
    Replies: 7
    Last Post: - 8th June 2006, 04:38
  5. Dedicated LCD Controller question
    By chuckles in forum mel PIC BASIC Pro
    Replies: 6
    Last Post: - 27th February 2006, 15:44

Members who have read this thread : 1

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts