PDA

View Full Version : Can't get LCD to work with 16F88



jswayze
- 3rd September 2004, 05:36
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):



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

carl_schell
- 3rd September 2004, 06:22
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

Melanie
- 3rd September 2004, 08:56
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

jswayze
- 3rd September 2004, 14:07
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

jswayze
- 3rd September 2004, 22:05
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?



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

Bruce
- 3rd September 2004, 22:17
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

jswayze
- 5th September 2004, 02:17
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

Bruce
- 5th September 2004, 03:50
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

jswayze
- 5th September 2004, 04:49
Bruce, you are my hero! :D

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

Bruce
- 5th September 2004, 04:58
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]

anj
- 9th September 2004, 22:33
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

Melanie
- 10th September 2004, 11:05
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.