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