Getting an LCD working with pic16f886

Discussion in 'Embedded Systems and Microcontrollers' started by Robin66, Aug 24, 2016.

  1. Robin66

    Thread Starter Member

    Jan 5, 2016
    102
    3
    I've been trying to get a HD44780 LCD module working with my pic16f886 for a few nights now. I've resorted to trying a ready made solution but I can't even get that to work. I've put an oscilloscope on D4-7 and used EN as an external trigger and have found that D4-7 only remain high until the next pin is set eg. if RB3 is set high, then it will fall low when RB4 is set (regardless of H or L). I have also seen this when stepping through the code in MPLAB X IDE v3.2. I've tried slowing down the clock/speed by using the int osc and manipulating _XTAL_FREQ but nothing seems to help.

    Any helpful suggestions greatly appreciated, Robin

    Here's the online solution: https://electrosome.com/lcd-pic-mplab-xc8/
    Code (C):
    1.  
    2. void Lcd_Port(char a)
    3. {
    4.     if(a & 1)
    5.         D4 = 1;     // D4 does go high
    6.     else
    7.         D4 = 0;
    8.  
    9.     if(a & 2)
    10.         D5 = 1;     // but falls low here....
    11.     else
    12.         D5 = 0;     // ... or here
    13.  
    The asm looks sensible to me too. I thought it may have been MOVF to PORTB and overwriting the prev values but it's using BCF and BSF, snippet below
    Code ( (Unknown Language)):
    1.  
    2. 4:             void Lcd_Port(char a)
    3. 05D1  00F0     MOVWF __pcstackCOMMON
    4. 5:             {
    5. 6:                 if(a & 1)
    6. 05D2  1C70     BTFSS __pcstackCOMMON, 0x0
    7. 05D3  2DD8     GOTO 0x5D8
    8. 7:                     D4 = 1;
    9. 05D4  1283     BCF STATUS, 0x5
    10. 05D5  1303     BCF STATUS, 0x6
    11. 05D6  1586     BSF PORTB, 0x3
    12. 05D7  2DDB     GOTO 0x5DB
    13. 8:                 else
    14. 9:                     D4 = 0;
    15. 05D8  1283     BCF STATUS, 0x5
    16. 05D9  1303     BCF STATUS, 0x6
    17. 05DA  1186     BCF PORTB, 0x3
    18. 10:          
    19. 11:               if(a & 2)
    20. 05DB  1CF0     BTFSS __pcstackCOMMON, 0x1
    21. 05DC  2DDF     GOTO 0x5DF
    22. 12:                   D5 = 1;
    23. 05DD  1506     BSF PORTB, 0x2
    24. 05DE  2DE0     GOTO 0x5E0
    25. 13:               else
    26. 14:                   D5 = 0;
    27. 05DF  1106     BCF PORTB, 0x2
    28.  
     
    Last edited: Aug 24, 2016
  2. AlbertHall

    Well-Known Member

    Jun 4, 2014
    1,908
    379
    Probably because you are not setting the pins you are using for outputs to digital mode (the default is analog).
    From the data sheet for port B:
    3.4.1 ANSELH REGISTER
    The ANSELH register (Register 3-4) is used to
    configure the Input mode of an I/O pin to analog.
    Setting the appropriate ANSELH bit high will cause all
    digital reads on the pin to be read as ‘0’ and allow
    analog functions on the pin to operate correctly.
    The state of the ANSELH bits has no affect on digital
    output functions. A pin with TRIS clear and ANSELH
    set will still operate as a digital output, but the Input
    mode will be analog. This can cause unexpected
    behavior when executing read-modify-write
    instructions on the affected port.
     
  3. Robin66

    Thread Starter Member

    Jan 5, 2016
    102
    3
    That was it! Thx a lot Albert. It's still not working but at least the D4-7 pins are holding their state correctly. I'm now back to debugging
     
  4. AlbertHall

    Well-Known Member

    Jun 4, 2014
    1,908
    379
    Does adjusting the contrast control display/hide squares where the characters should be?
    If not check the LCD wiring.
     
  5. Robin66

    Thread Starter Member

    Jan 5, 2016
    102
    3
    I don't see any evidence of char squares. I've had the contrast control pinned to Vdd (+5V), and I've tried ~3V, but still no change. I've put an oscilloscope on all the pins to check they're pulsing or sticking to the expected V and it all seems sensible.

    If I'm meant to see the char squares appear when adjusting contrast (regardless of whether it's initialized correctly) then I suspect I have a dud module.
     
  6. AlbertHall

    Well-Known Member

    Jun 4, 2014
    1,908
    379
    Yes you should be able to get squares with just power and VEE connected. You must sort this out first.
    The contrast pin (VEE) should be connected to the wiper of a pot with the track connected across the 5V supply. I believe the correct setting will be with VEE close to 0V.

    Edit: Some LCD modules need VEE to be a negative voltage. Do you have a specification or model number for your display?
     
  7. Robin66

    Thread Starter Member

    Jan 5, 2016
    102
    3
  8. AlbertHall

    Well-Known Member

    Jun 4, 2014
    1,908
    379
    Connect VEE via the pot (10K but not critical) and see what you get.
     
  9. Robin66

    Thread Starter Member

    Jan 5, 2016
    102
    3
    Ok I'll try that when I'm home tonight. VEE = V0 right?
     
  10. AlbertHall

    Well-Known Member

    Jun 4, 2014
    1,908
    379
    If you connect VEE to 0V you should definitely get the squares (I think they will be white on that display if the backlight is on) but it probably won't display characters like that. You need the pot to be able to adjust it until the squares just disappear to get a proper display of characters.
     
  11. Robin66

    Thread Starter Member

    Jan 5, 2016
    102
    3
    Ok. I hardwired a 4k7-4k7 divider thinking that I'm not precious about contrast for testing, but perhaps the usable Vo range is narrower than I assumed
     
  12. AlbertHall

    Well-Known Member

    Jun 4, 2014
    1,908
    379
    There is a fairly small range of VEE voltage where you will get display of characters. If the voltage is too high you will see nothing on the display, too low and you will get only squares. I just checked a similar display which I have and the voltage is between 0.75V and 1V. If you don't want to use a pot you could try 4k7 from VEE to +5V and 1k to ground for testing. You will need the pot to get the best display.

    Incidentally, the necessary voltage changes with temperature so for use over a range of temperatures designs can use either a user adjustable voltage, or circuitry which measures the temperature and automatically adjust the voltage.
     
    Robin66 likes this.
  13. Robin66

    Thread Starter Member

    Jan 5, 2016
    102
    3
    Oh wow, the Vo's I've tried have been miles off from your tested range then. Hopefully it'll be as simple as that. I'll stick a pot in and play. I'll come back in ~7hrs with results.

    I think I've been especially up against it because this is the first time I've used an LCD module AND it's the first time I've coded in C. My prev projects were in asm, so I have 2 sets of things to doubt when it doesn't work.

    Thx for your help.
     
  14. AlbertHall

    Well-Known Member

    Jun 4, 2014
    1,908
    379
    There may be other problems but you can't really investigate until you get VEE right.
     
  15. Robin66

    Thread Starter Member

    Jan 5, 2016
    102
    3
    As an aside, I recognise that the free xc8 compiler only claims to do minimal optimization, but I'm still very surprised at how little it does. eg. there's lots of repetitions of the below in an asm function which only touches bank 0. I'm trying C to try to reduce my dev time, but as a hobbyist I don't want to spend ~£1k on a decent C-->asm optimiser and asm isn't *that* difficult to work with once you get the hang of it.
    1. 05D4 1283 BCF STATUS, 0x5
    2. 05D5 1303 BCF STATUS, 0x6
    PS. I buy this. The free compiler is deliberately inefficient. http://www.t4f.org/articles/optimization-of-microchip-pic-xc8-compiler-in-free-and-pro-mode/
     
    Last edited: Aug 25, 2016
  16. Robin66

    Thread Starter Member

    Jan 5, 2016
    102
    3
    I soldered on a pot in place of the fix divider and it started working immediately. I can't believe how much time I wasted on such a simple bug. Thx a lot for your help Albert
    IMG_4635.JPG
     
  17. AlbertHall

    Well-Known Member

    Jun 4, 2014
    1,908
    379
    Brilliant! I have fought those battles myself so it's good to pass on the experience.
     
  18. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    7,386
    1,605
    What amazes me is this pot is still required on most devices.

    I say "most" because I have at least one display that is quite happy to work correctly without any connection at all on the contrast pin.
     
  19. dannyf

    Well-Known Member

    Sep 13, 2015
    1,779
    360
    Unless you are always working on really simple stuff orr pushing the performance envelope all the time, you will find that coding in a high level language like C iss the way to go.

    It allows you to focus on the value add stuff and let thee computer do the low value add stuff like turning your code into assembly statements.

    There is a reason that embedded work is mostly done in high level language. C alone has. 60 percent of the mjt and increasing.
     
  20. Robin66

    Thread Starter Member

    Jan 5, 2016
    102
    3
    I will continue this project, which is quite involved, in C. However from what I've seen so far from the xc8 asm output I would not be surprised if I rewrite at least some of the slower elements in asm afterwards. I may even be forced to switch to full asm before the end The waste is truly shocking. My code is already taking 5% of the 16f886 program space and it doesn't do anything substantive yet.
     
Loading...