Can't get LCD to work with 16F88


Closed Thread
Results 1 to 12 of 12
  1. #1
    jswayze's Avatar
    jswayze Guest

    Default Can't get LCD to work with 16F88

    I can't seem to get my LCD display to work with my 16F88. I get the solid blocks across the first line, and that's it (basically the same as applying power to the LCD). I've double-checked all the connections, so I think it's something in my program. Here's what I have (based on the lcd.bas file included with pbp):

    Code:
    define  osc 8
    
    ADCON0 = %11000001
    
    
    Define  LCD_DREG        PORTB
    Define  LCD_DBIT        4
    
    Define  LCD_RSREG       PORTB
    Define  LCD_RSBIT       5
    
    Define  LCD_EREG        PORTB
    Define  LCD_EBIT        6
    
            Pause 500       ' Wait for LCD to startup
    
    loop:   Lcdout $fe, 1   ' Clear LCD screen
            Lcdout "Hello"  ' Display Hello
            Pause 500       ' Wait .5 second
    
            Lcdout $fe, 1   ' Clear LCD screen
            Lcdout "World"
            Pause 500       ' Wait .5 second
    
            Goto loop       ' Do it forever
    The EPICWin programmer is set for INTRC (IN), so I think I'm correctly using the internal 8 MHz clock.

    I'm really not sure if I'm using ADCON0 properly. There always seems to be mention of ADCON1 and setting ports to analog/digital, but I can't seem to sort it out.

    Any help would be greatly appreciated.

    Thanks,

    Jeff

  2. #2
    carl_schell's Avatar
    carl_schell Guest


    Did you find this post helpful? Yes | No

    Cool

    Jeff -

    I have not used this particular chip, but you can check a few things...

    1.) I would suggest adding 2 additional defines

    Define LCD_BITS 4 'Set LCD Bus Size (4 or 8)
    Define LCD_LINES 2 'Set number of lines on LCD

    2.) also...try this

    CMCON = 7 ' Turn Off Comparators

    3.) If this still does not work, try this

    ADCON1 = 6 'Turn Off Analogue (ALL DIGITAL) Check your data sheet to make sure this is the right number

    Your ADCON0 Register is used to control the operation of the ADC and could be set to 0...in pbp, the adcin command deals with this register without us having to mess with it...it is used when needing to know when a/d conversion is done, etc. This is probably not your issue right now

    4.) Also, clean the code as follows...

    Loop:
    LCDOUT $FE,1,"Hello"
    Pause 500
    LCDOUT $FE,1,"World"
    Pause 500
    Goto Loop


    Good Luck & Best Regards,

    Carl

  3. #3
    Join Date
    Jul 2003
    Posts
    2,358


    Did you find this post helpful? Yes | No

    Default

    ADCON, CMCON etc have no effect on PORTB which is what you're connected to.

    1. Assuming your connections are as per your Defines, increase the Pause at the start of your program. Different LCD's from different manufacturers require different lengths of time to wake up and initialise. I generally use Pause 1000, but I do know of one LCD that requires Pause 2000.

    2. If changing Defines, I also usually put the full set in...it's a memory jogger just in case something else has changed... try this set...

    Define LCD_DREG PORTB ' Port for LCD Data
    Define LCD_DBIT 0 ' Use LOWER 4 bits of Port
    Define LCD_RSREG PORTB ' Port for RegisterSelect (RS) bit
    Define LCD_RSBIT 5 ' Port Pin for RS bit
    Define LCD_EREG PORTB ' Port for Enable (E) bit
    Define LCD_EBIT 6 ' Port Pin for E bit
    Define LCB_BITS 4 ' Using 4-bit bus
    Define LCD_LINES 2 ' Using 2 line Display
    Define LCD_COMMANDUS 2000 ' Command Delay (uS)
    Define LCD_DATAUS 50 ' Data Delay (uS)

    And in doing so I've just discovered your problem... you CANT use the UPPER 4 bits of the PORT for DATA...

    Define LCD_DREG PORTB
    Define LCD_DBIT 4

    and then connect your RS and E Bits to the upper bits as well!!!!

    Define LCD_RSREG PORTB
    Define LCD_RSBIT 5

    Define LCD_EREG PORTB
    Define LCD_EBIT 6


    Melanie

  4. #4
    jswayze's Avatar
    jswayze Guest


    Did you find this post helpful? Yes | No

    Default

    Thank you both for your answers.

    At one point I had a similar program (the D/A example) running - sort of - on another LCD. The format was messed up but it was at least writing to the LCD. The wierd thing was that it took a LONG time to start displaying the data, and once it did, it took a long time to update when it should have been updating every second. For this reason I think one of my problems is timing/clock speed. I have the presets for the 16F88 set to the internal 8 MHz R/C clock, but I'm not really sure if that's what I'm getting. I suppose I need to do a simple LED flasher to see what it thinks one second is.

    Regarding Melanie's discovery, I was under the impression that DBIT described which 4 bits on LCD were used, not on the PIC. I see that I was wrong. I also didnt' specify the width of the bus - perhaps it defaults to 8 bits.

    At any rate, before I left for work this morning I tried Melanie's code and saw the same problem with the LCD. I'll have more time to experiment tonight - this is frustrating because this should be the easy part! I still have to work out the real code for my project.

    Anyhow, thanks again. I'll post an update when appropriate.

    -Jeff

  5. #5
    jswayze's Avatar
    jswayze Guest


    Did you find this post helpful? Yes | No

    Default

    Well, good news/bad news. I finally solved my timing issue - I had to set OSCON in order for the clock to work properly. Turns out the PIC was running at about 4 Hz. (???)

    Bad news is that after the LCD initializes I get no output. I tried the same program on a F628 and it worked fine. Back to the F88 and I get nothing. There must be something that's impeding the data flow to RB0-4, but I can't find anything.

    Here's where I stand. Any suggestions?

    Code:
    Define LCD_DREG PORTB ' Port for LCD Data
    Define LCD_DBIT 0 ' Use LOWER 4 bits of Port
    Define LCD_RSREG PORTB ' Port for RegisterSelect (RS) bit
    Define LCD_RSBIT 5 ' Port Pin for RS bit
    Define LCD_EREG PORTB ' Port for Enable (E) bit
    Define LCD_EBIT 6 ' Port Pin for E bit
    Define LCB_BITS 4 ' Using 4-bit bus
    Define LCD_LINES 2 ' Using 2 line Display
    Define LCD_COMMANDUS 2000 ' Command Delay (uS)
    Define LCD_DATAUS 50 ' Data Delay (uS)
    define  osc 8
    osccon = %11111100
    option_reg = %11111000
    intcon = %00000000
    TRISB = 0
    CMCON = 7 ' Turn Off Comparators
    ADCON1 = 6 'Turn Off Analogue (ALL DIGITAL) Check your data sheet to make sure this is the right number
    
            Pause 2000       ' Wait for LCD to startup
    
    Loop
        LCDOUT $FE,1,"Hello"  
        Pause 500
        LCDOUT $FE,1,"World"
        Pause 500
        Goto Loop

  6. #6
    Join Date
    Jul 2003
    Posts
    2,405


    Did you find this post helpful? Yes | No

    Default

    1. If you're going to use the internal 8MHz oscillator, then you need to first conffigure it by writing to the OSCCON register.

    OSCCON = %01110000 ' INTRC = 8MHz

    DEFINE OSC 8 only tells PBP you're using an 8MHz oscillator and to adjust timing to work at this speed. It doesn't configure the internal osc on the 16F88 for 8MHz.

    2. If you use the upper 4-bits of PORTB for LCD data, then you can't use any of "the same pins" for your remaining LCD control lines.

    Define LCD_DREG PORTB
    Define LCD_DBIT 4 <-- use RB4 to RB7 for LCD data
    Define LCD_RSREG PORTB
    Define LCD_RSBIT 5 <-- already being used for data
    Define LCD_EREG PORTB
    Define LCD_EBIT 6 <-- already being used for data

    3. Always start out with DEFINE LCD_COMMANDUS 2000 in the top section of your code. You can tinker with the value, and for some LCDs, maybe even eliminate it altogether, but I recommend at least starting out with it in there. Some LCDs are slow. Some are fast.

    The example below has been tested with a 16F88 and 2-line LCD.

    @ DEVICE INTRC_OSC, LVP_OFF, WDT_OFF, MCLR_OFF

    DEFINE OSC 8
    DEFINE LCD_DREG PORTB
    DEFINE LCD_DBIT 4
    DEFINE LCD_RSREG PORTB
    DEFINE LCD_RSBIT 3
    DEFINE LCD_EREG PORTB
    DEFINE LCD_EBIT 2
    DEFINE LCD_COMMANDUS 2000

    OSCCON = %01110000 ' INTRC = 8MHz

    Pause 500 ' Wait for LCD to startup

    loop:
    Lcdout $fe, 1, "Hello" ' Display Hello
    Pause 500 ' Wait .5 second

    Lcdout $fe, $C0, "World"
    Pause 500 ' Wait .5 second

    Goto loop ' Do it forever
    Regards,

    -Bruce
    tech at rentron.com
    http://www.rentron.com

  7. #7
    jswayze's Avatar
    jswayze Guest


    Did you find this post helpful? Yes | No

    Default

    Bruce,

    This code did the trick. Thing is, it was no different than my previous attempts except for using B4-B7 instead of B0-B3. There must be a trick I'm missing somewhere.

    Anyhow it works (woo hoo!) and now I'm trying to figure out what the ADC is giving me.

    I'm assuming my 10-bit ADC result is a proportion as 1024 is to 5 volts. So, is there an easy way to display the decimal voltage value (to 2 places), or do I need to write a "subtract and conquer" routine to convert to decimal?

    Thanks,

    Jeff

  8. #8
    Join Date
    Jul 2003
    Posts
    2,405


    Did you find this post helpful? Yes | No

    Default

    Hi Jeff,

    > This code did the trick. Thing is, it was no different than my
    > previous attempts except for using B4-B7 instead of B0-B3.
    > There must be a trick I'm missing somewhere.

    I'm not sure why it wouldn't work for you assuming you had everything connected per your LCD DEFINE's.

    I'm sure if you look "very" carefully at how you had everything physically connected, then look at your previous LCD DEFINE's - you'll find your answer.

    For your A/D try this. It's using the previous 16F88 LCD example that's already working for you - so it should work as-is.

    Note: 1st measure your +Vref (ground & Vdd). If it's < or > 5V, then simply change the quanta value.

    Example: If you measure 4.95V from gnd & Vdd, then +Vref = 4.95V : Quanta=4.95V/1023*256=1.238=1238.

    The result is fairly accurate @ +/- ~0.01V.

    @ DEVICE INTRC_OSC, LVP_OFF, WDT_OFF, MCLR_OFF

    define OSC 8
    Define LCD_DREG PORTB
    Define LCD_DBIT 4
    Define LCD_RSREG PORTB
    Define LCD_RSBIT 3
    Define LCD_EREG PORTB
    Define LCD_EBIT 2
    DEFINE LCD_COMMANDUS 2000
    Define ADC_BITS 10 ' Set number of bits in result
    Define ADC_CLOCK 3 ' Set clock source (3=rc)
    Define ADC_SAMPLEUS 50 ' Set sampling time in uS

    Quanta con 1251 ' +Vref = 5V : Quanta=5V/1023*256=1.251
    Line1 CON $80
    ADval var word ' Create ADval word-sized variable to store result

    TRISA = %11111111 ' Set PORTA to all input
    CMCON = %00000111 ' Disable analog comparators
    ANSEL = %00000001 ' Set PORTA.0 = A/D in, rest digital
    ADCON1 = %10000000 ' Right Justify A/D result
    OSCCON = %01110000 ' INTRC = 8MHz
    Pause 500 ' Wait for LCD to startup

    loop:
    ADCIN 0, ADval ' Read A/D on RA0
    ADval = (ADval*10) */ Quanta
    LCDOUT $FE, 1 ' Clear LCD
    LCDOUT $FE, Line1+3,dec ADval dig 4,".",dec4 ADval,"Vdc"
    Pause 1000
    Goto loop ' Do it forever

    Last edited by Bruce; - 5th September 2004 at 04:01.
    Regards,

    -Bruce
    tech at rentron.com
    http://www.rentron.com

  9. #9
    jswayze's Avatar
    jswayze Guest


    Did you find this post helpful? Yes | No

    Default

    Bruce, you are my hero!

    I can't believe it was that simple. I could get it to display Adval, but couldn't think of a good way to convert to decimal. Man, as simple as DEC and DIG !

    Now, I'm looking through the manual and can't find anything on DECx except for in the reserved word list. I gather that it displays x digits past the decimal point, but is it in the book somewhere? It's not in the math section...

    Anyhow, thank you Bruce! Also, thanks for the info regarding voltage dividers in the other thread. I think I'm pretty well set with the A/D now. My next challenge is to use the LINX Tx and Rx modules I just bought from Rentron to transmit this voltage reading from an R/C plane! Ahh, never a dull moment around here.

    Best Regards,

    Jeff

  10. #10
    Join Date
    Jul 2003
    Posts
    2,405


    Did you find this post helpful? Yes | No

    Default

    You're very welcome. Glad I could help.

    < can't find anything on DECx except for in the reserved word list

    DEC isn't a PBP command. It's what's referred to as a "data modifier", and you'll see it in the manual under the LCDOUT, SERIN2, etc, commands.

    If you're using the TXLC/RXLC modules, just remember to hold the transmitter data input at logic 0 during idle periods.

    These modules are CPCA (carrier present, carrier absent), and super easy to use.

    You're simply turning the transmitter carrier ON with logic 1, and turning it OFF with logic 0. Think of the logic on the transmitter data input as an ON/OFF switch.

    The receiver just reflects the same logic states on its data output. TX input = 1, carrier = ON, RX output = 1. TX input = 0, carrier = OFF, RX output = 0. Doesn't get much easier.

    Very stable receiver output, and incredibly simple to use.

    Enjoy...;o]
    Last edited by Bruce; - 5th September 2004 at 05:09.
    Regards,

    -Bruce
    tech at rentron.com
    http://www.rentron.com

  11. #11
    anj's Avatar
    anj Guest


    Did you find this post helpful? Yes | No

    Default

    Gday Melanie
    Re 16F88s and the statement "ADCON, CMCON etc have no effect on PORTB which is what you're connected to."
    I had problems with a 4line LCD and a 16F88 about 6mths ago.
    Data was on RB4-7.
    The code i had worked perfectly on a 2line LCD but not the 4line unit. Both used the same chipset and initialisation routines.
    I then went and studied the manual, but i couldnt find anything that would account for my problem, however I did note that RB6 and 7 were analogue pins on this chip.
    Grasping at straws, i set ANSEL to force RB6 and RB7 digital prior to initialsing the LCD ( as they start analogue ). This solved my problem, but i'm not sure why.
    Is this something you would "need" to do with this chip, or have i just found something that seems to fix my problem?
    Andrew
    ps original problem was with PBP2.44 and the 16f88 patch off the MEL site
    Last edited by anj; - 9th September 2004 at 22:40.

  12. #12
    Join Date
    Jul 2003
    Posts
    2,358


    Did you find this post helpful? Yes | No

    Default

    I've not used the 16F88 part and assumed (always a bad thing!) that as per earlier Microchip convention they tended to keep the Analogue to PortA and E. If as you say they've put it on PortB for that part, then obviously any pins you assign to the LCD must be set to Digital FIRST otherwise it's not going to work.

Similar Threads

  1. Play with LCD on PICDEM
    By The IceMan in forum mel PIC BASIC
    Replies: 5
    Last Post: - 22nd August 2008, 16:56
  2. Need help with LCD number display.
    By Steve Matson in forum mel PIC BASIC
    Replies: 8
    Last Post: - 26th June 2007, 23:07
  3. 16f88 can't get lcd to work
    By nicjo in forum General
    Replies: 12
    Last Post: - 13th December 2006, 02:20
  4. Why doesn't my code for 18f452 work on 18f252?
    By senojlr in forum mel PIC BASIC Pro
    Replies: 4
    Last Post: - 23rd December 2005, 02:42
  5. 4 line LCD with 16F88
    By anj in forum mel PIC BASIC Pro
    Replies: 1
    Last Post: - 7th February 2004, 09:06

Members who have read this thread : 0

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