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).
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).
"If the Earth were a single state, Istanbul would be its capital." Napoleon Bonaparte
If I read post #7 correctly he already is using a 10K resitorOriginally Posted by sayzer
Crossing fingers didn't work on this occasionI have tried 100 nf, 1uf and 10 uF as the MCLR capacitor with 10k to +5.![]()
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.![]()
"If the Earth were a single state, Istanbul would be its capital." Napoleon Bonaparte
I bet on LVP. But i'll have a look to the datasheet of the LCD.
What happen if you use a 4MHZ osc?
Steve
It's not a bug, it's a random feature.
There's no problem, only learning opportunities.
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)HTH,Code:;---- 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 --------------------------------------------
Last edited by Darrel Taylor; - 18th October 2006 at 23:29. Reason: Changed Defines to match original Post
DT
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
> @ 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 ...
were not defined.Code:DEFINE LCD_RWREG PORTD 'LCD read/write port DEFINE LCD_RWBIT 6 'LCD read/write bit
There's a good possibility!
Last edited by Darrel Taylor; - 19th October 2006 at 00:36. Reason: First Post had it too.
DT
Bookmarks