PDA

View Full Version : LCD will not start



btaylor
- 16th October 2006, 05:56
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

Darrel Taylor
- 16th October 2006, 07:09
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...
[************************** 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...
StartLCD:
pause 500
It uses another half second doing nothing again.

Then here...
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...
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.

btaylor
- 16th October 2006, 11:46
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

mister_e
- 16th October 2006, 14:21
And a simple add at the bottom of the List...

@ 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!

btaylor
- 17th October 2006, 22:37
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

mister_e
- 17th October 2006, 23:08
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?

btaylor
- 18th October 2006, 00:06
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

mister_e
- 18th October 2006, 00:30
try...



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 :(

btaylor
- 18th October 2006, 01:55
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.

paul borgmeier
- 18th October 2006, 04:15
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

Darrel Taylor
- 18th October 2006, 05:35
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>

btaylor
- 18th October 2006, 07:57
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/electus/products_uploaded/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

sayzer
- 18th October 2006, 08:43
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).

malc-c
- 18th October 2006, 09:19
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 ;)

sayzer
- 18th October 2006, 09:26
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. :)

mister_e
- 18th October 2006, 13:04
I bet on LVP. But i'll have a look to the datasheet of the LCD.

What happen if you use a 4MHZ osc?

Darrel Taylor
- 18th October 2006, 20:00
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)
;---- 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,

btaylor
- 18th October 2006, 23:26
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

Darrel Taylor
- 19th October 2006, 00:16
> @ 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 ...


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

There's a good possibility!

btaylor
- 19th October 2006, 01:35
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

mister_e
- 19th October 2006, 01:48
I second the following...

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.

Darrel Taylor
- 19th October 2006, 01:59
Can I Third that?

or is that double dipping?
<br>

btaylor
- 19th October 2006, 03:08
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

btaylor
- 19th October 2006, 04:01
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

mister_e
- 19th October 2006, 14:21
<img src="http://img8.picsplace.to/img8/22/Thumbs-up.gif">

JohnPaul
- 21st May 2007, 01:15
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


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

skimask
- 21st May 2007, 01:58
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.

JohnPaul
- 21st May 2007, 04:17
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

skimask
- 21st May 2007, 05:04
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.

Archangel
- 21st May 2007, 09:36
' 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

JohnPaul
- 22nd May 2007, 03:24
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

JohnPaul
- 22nd May 2007, 03:32
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

JohnPaul
- 22nd May 2007, 03:39
ski,

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

Regards,
JohnPaul

skimask
- 22nd May 2007, 03:47
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.

JohnPaul
- 22nd May 2007, 05:06
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

skimask
- 22nd May 2007, 05:30
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 :)

JohnPaul
- 22nd May 2007, 05:43
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

skimask
- 22nd May 2007, 05:46
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 :D

Archangel
- 22nd May 2007, 08:15
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

JohnPaul
- 22nd May 2007, 12:18
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

skimask
- 22nd May 2007, 14:08
MCLR / Vdd - 5v (if running a 5v power supply, otherwise, take all these reading and divide them down accordingly)

Vss - 0v

OSC1 / OSC2 - with an external oscillator/crystal, somewhere around 2.5v give or take, because the meter is really reading DC, it's catching the average of the DC, which since it's going high/low/high/etc, is around 2.5v.

Pins set to an input will most likely read about 2.5v, or a suitable fraction of the main power supply voltage.

Pins set to output and logic low will be between 0v and about .6v

Pins set to output and logic high will be around 7/10 of the main power voltage.

All interconnects on your breadboard should be practically a dead short, like less than about 10 ohms or so. Don't forget to check your multimeter leads themselves for resistance.

Hopefully this is what you were asking about. Sounds a tad bit basic to me, but that's just me...

By checking the new chip against the old chip alongside it in identical circuits, you are doing what I call a 'signature check', good troubleshooting technique, but it really only works if you've got a couple of known good working setups to verify another bad setup.

Archangel
- 22nd May 2007, 22:53
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
Hi JP,
Pretty much as skimask said, just check from the leads of the components to where they are supposed to be connected ( the other component ). These breadboards get really spooky over time. Darrel told me he only uses them once. That's too rich for my blood but my time is perhaps less valuable. Certainly I do not do this for a living. I dissasembled my old breadboards and was very surprised at what I found in the way of wear and corrosion. This is especially important on the VSS & VDD connections so power flows through the device in the way it's designers intended, otherwise very strange current paths can exist and FRY something.
JS

JohnPaul
- 23rd May 2007, 04:58
Hey, folks. No progress today... Hehehe... I actually mean I slacked off. I could not find my other 627A. Use of magnifier did not helped. I would try the 84A but have to use OSC chip or I have to use my 40 pins. I could not wait for the weekend to come.

What is the most advanced PIC chip one could wish for? I like my 627A since it has internal OSC.

I am reserving my 40 pins for more complexed project in the future.


Cheers!

John Paul

JohnPaul
- 23rd May 2007, 05:06
JohnS,
I bought this regulated variable PS. They go by 1.5, 3, 4.5, 6, 9v, 12v.
No +5v! I like it because it's so portable than those high Amp PS. So I was playing with the PIC with 4.5v and ocassionally switching to 6v. Could I have caused the untimely dead of my PIC?
Later, I retrieve one of my breadboard with a T7805. Just to make sure the LCD and Chip now has the recommended (or was it REQUIRED) voltage?
Hahaha...

Regards,
JohnPaul

skimask
- 23rd May 2007, 05:15
JohnS, I bought this regulated variable PS. They go by 1.5, 3, 4.5, 6, 9v, 12v. No +5v! I like it because it's so portable than those high Amp PS. So I was playing with the PIC with 4.5v and ocassionally switching to 6v. Could I have caused the untimely dead of my PIC? Later, I retrieve one of my breadboard with a T7805. Just to make sure the LCD and Chip now has the recommended (or was it REQUIRED) voltage?
Hahaha...
Regards,
JohnPaul

The PIC (and everything else mentioned so far) will run just fine off 4.5v, and the occassional switchover to 6v probably won't hurt it much either. Datasheets say 7V is 'absolute maximum' rating, not recommended for any length of time. I've accidentally ran a couple of my PIC's at 9v before, they still run, not saying they're not damaged and won't fail before the others, but they do still work.

JohnPaul
- 23rd May 2007, 13:17
Ski,

I might have pulled the PIC while the power is on. Also, I might have pulled a wire while powered on. I am using a breadboard wire that I like because they are more flexible and easy to insert but I wondered could high current be generated with "loose" connection?
Hehehe... I have done my testimony. Guilty for the dead of my pic? Hahahaha..... I would play with the pic16f84a tonight and catch up with you and Joe.

Regards,
JohnPaul

skimask
- 23rd May 2007, 13:41
Ski, I might have pulled the PIC while the power is on. Also, I might have pulled a wire while powered on. I am using a breadboard wire that I like because they are more flexible and easy to insert but I wondered could high current be generated with "loose" connection? Hehehe... I have done my testimony. Guilty for the dead of my pic? Hahahaha..... I would play with the pic16f84a tonight and catch up with you and Joe.
Regards,
JohnPaul

Every 'wire', every circuit trace, everything, is an inductor of sorts, a small one, but an inductor nonetheless. You open a closed circuit, what little magnetic field that had been developed along a specific traces, collapses and induces a voltage (which in turn has a current), and that voltage/current has to go somewhere, usually to ground, sometimes thru a part to ground.
So, I don't think it's the fact that you had 'high current' with that loose connection, I think it would be more to the fact that you might've been jiggling a loose connection causing some really small arcs to occur and putting voltage spikes on whatever wire you were hooked up to.

And there's really nothing wrong with the ol' white, solderless breadboards and those wires that go with them....so long as you realize their limitations as far as frequency and durability go. They don't really like high frequencies, much above about 10Mhz or so because of the parasitic capacitance, causes those nice sharp edges on square waves to get rounded off. And the connections tend to open up and get looser over time.
Keep that in mind while your using those boards, replace them once in awhile, like a few of us around here have started doing, and you'll be alright...
I used to use the large boards, the ones with 3,220 points. I chucked that one and got a handful of the smaller 800 point boards. Much cheaper to replace one of those than the big ones.

JohnPaul
- 24th May 2007, 02:24
Ski,

I see. Make very good sense. Thanks.

Regards,
JohnPaul

JohnPaul
- 24th May 2007, 02:29
Hello, all.

Any advise on PICs for advanced project? I am ordering a few to stack up. Once I get off the ground, I would like doing timer relay project with the LEDs, Security Systems and Stepper Motors. Which PICs are best choices for most advanced... beyond listed above? Also, Is 627A good for beginner like me? I think I would get a couple to stack up. I like it particularly for the internal OSC.

Regards,
Juanito

JohnPaul
- 24th May 2007, 02:30
Hello, all.

Any advise on PICs for advanced project? I am ordering a few to stack up. Once I get off the ground, I would like doing timer relay project with the LEDs, Security Systems and Stepper Motors. Which PICs are best choices for most advanced... beyond listed above? Also, Is 627A good for beginner like me? I think I would get a couple to stack up. I like it particularly for the internal OSC.

Regards,
John Paul ( I should have posted)