Reply by Active8 February 5, 20042004-02-05
On 3 Feb 2004 14:34:31 -0800, larkmore@aol.com said...
> I have an Optrex LCD (DMC-20481NY-LY-AGE) that is 4x20 characters and > driven by a Microchip PIC16F877 running at 20MHz.
<snip> I haven't used Optrex yet but My biggest prob getting those black lines to go away and everything else to init was that I left the R/W line open. The controller inputs have internal weak pullups so you have to either tie R/W low or drive it with the PIC. The other thing I found was that the home command was pretty useless or something like that. It didn't do what the HDwhatever Spec sheet said. I have to use Clear Display. Also, resetting the PIC which runs my LCD init code sometimes doesn't give the LCD enough time to do whatever it needs to do, I have to power down the LCD. I'm not sure, but for the 4 bit interface, I may have had to run the init code twice. Once to get it in 4 bit mode and again once it's there. -- Best Regards, Mike
Reply by Active8 February 5, 20042004-02-05
On Wed, 04 Feb 2004 14:21:52 GMT, NoSpam@att.net said...
> CWatters wrote: > > > > "Will" <larkmore@aol.com> wrote in message > > news:5faf6114.0402031434.38db8ce2@posting.google.com... > > > > > with 10KOhm pulldown resistors to ground on ALL of the lines on the > > > > I think one pin on the most PICs is open collector. > > > Ah yes ... the famous open collector gotcha. That's another trap for > amateurs. It still bites me from time to time, even after upteen > Microchip projects. >
/MCLR is OC when used as a data line - isn't that one of 'em? Works as an out only, IIRC. -- Best Regards, Mike
Reply by Egads February 5, 20042004-02-05
Make sure you give the LCD time to power up.  I just hooked
up a Optrex 2x16 display to a TI MSP430 and I had to put in huge
delays before I ever started initializing the LCD.  After I did
that all of my problems went away....

-- 
Greg Deuerling
Fermi National Accelerator Laboratory
P.O.Box 500 MS368  Batavia, IL 60510
(630)840-4629     FAX  (630)840-5406
Electronic Systems Engineering Group
Work: egads_AT_fnal.gov, remove '_AT_'
Reply by Stefan Heinzmann February 4, 20042004-02-04
Will wrote:
> Ok, I've had limited success so far. Circuit-wise I have removed the > capacitors from the data lines but left the series and pulldown > resisitors alone. Program-wise I have added enourmous delays to the > initialization routines and reordered some of the commands. The > combination seems to have done the trick for initializing the display > since I now get a blinking cursor and some letters. I say some > letters, because there is still a timing glitch I can't seem to track > down. I know it has to do with trying to use the Busy Flag instead of > hard coded delays, but despite searching the web and pouring over > cryptic datasheets I cannot find a solution that works. If someone > familiar with PIC assembly could post a WORKING snippet of code for a > 20MHz crystal, or if someone could just post a graphical plot of > signals versus time for checking the busy flag I would greatly > appreciate it! My new code is appended below. Thanks for all the > help!
I seem to remember that you were saying the Busy flag was connected to bit 6 Port B. Odd, because the busy flag is the highest data bit (bit 7) if I remember this right. Can you check your busy flag definition against the data sheet of the LCD chip? Have you got the data sheet of the HD44780, which is the prototypical chip everyone emulates?
> CheckBusyFlag MACRO > LOCAL JumpPoint > JumpPoint > bcf RS > bsf RW > nop > nop > bsf ENABLE > nop > nop > nop > nop > nop > bcf ENABLE > btfsc BUSY_FLAG > goto JumpPoint > ENDM
I consider it advisable to change the order of the bcf and btfsc instructions, because the former disables the output of the data that you are reading with the second. -- Cheers Stefan
Reply by Bob Stephens February 4, 20042004-02-04
On Wed, 4 Feb 2004 10:52:04 PST, Everett M. Greene wrote:

> larkmore@aol.com (Will) writes: >> I have an Optrex LCD (DMC-20481NY-LY-AGE) that is 4x20 characters and >> driven by a Microchip PIC16F877 running at 20MHz. I know I got this >> exact same physical LCD to work before but for the life of me I can't >> recall what trick I used to do so. Attached at the end is my >> software. I get power to the LCD, but all I see is lines 1 and 3 as >> all dark and lines 2 and 4 as all clear. Hunting around newsgroups >> leads me to think my initialization routines aren't working (gee, ya >> think?!?!) but as near as I can tell I have met or exceeded all of the >> timing requirements for data transfer. PLEASE HELP!!!!! If it >> matters, I am using a dedicated 5V DC supply to drive both the PIC and >> the LCD. The PIC is connected to the LCD through 330 Ohm resistors, >> with 10KOhm pulldown resistors to ground on ALL of the lines on the >> PIC side. This was because I was seeing a lot of glitches on powerup >> due to ports being inputs. Each line also has a .01uF cap to ground >> and there is a bypass capacitor on the 5V line to ground next to the >> PIC. The BusyFlag is also connected directly from the LCD to the PIC >> on PORTB, 6. Thanks for any insight! > > No comment on the hardware aspect of your design, but > putting caps on data lines is unusual to say the least. > > The main problem with getting Optrex LCDs to work is the > initialization. The info provided by Optrex is only > approximately accurate with respect to the time delays. > I've had to insert looooong delays at each initialization > step and then shorten them until failure, thus finding > that some had to be substantially longer than Optrex > says. >
I had exactly the same experience - took many frustrating hours to figure out and Optrex was zero help.
> There's also a gotcha with the BUSY flag -- it doesn't > start working at the point in the initialization > process that Optrex states. A wait loop has to be > used at each step until the end of initialization. > The BUSY flag can and should be used from there onward.
Yup
Reply by Everett M. Greene February 4, 20042004-02-04
larkmore@aol.com (Will) writes:
> I have an Optrex LCD (DMC-20481NY-LY-AGE) that is 4x20 characters and > driven by a Microchip PIC16F877 running at 20MHz. I know I got this > exact same physical LCD to work before but for the life of me I can't > recall what trick I used to do so. Attached at the end is my > software. I get power to the LCD, but all I see is lines 1 and 3 as > all dark and lines 2 and 4 as all clear. Hunting around newsgroups > leads me to think my initialization routines aren't working (gee, ya > think?!?!) but as near as I can tell I have met or exceeded all of the > timing requirements for data transfer. PLEASE HELP!!!!! If it > matters, I am using a dedicated 5V DC supply to drive both the PIC and > the LCD. The PIC is connected to the LCD through 330 Ohm resistors, > with 10KOhm pulldown resistors to ground on ALL of the lines on the > PIC side. This was because I was seeing a lot of glitches on powerup > due to ports being inputs. Each line also has a .01uF cap to ground > and there is a bypass capacitor on the 5V line to ground next to the > PIC. The BusyFlag is also connected directly from the LCD to the PIC > on PORTB, 6. Thanks for any insight!
No comment on the hardware aspect of your design, but putting caps on data lines is unusual to say the least. The main problem with getting Optrex LCDs to work is the initialization. The info provided by Optrex is only approximately accurate with respect to the time delays. I've had to insert looooong delays at each initialization step and then shorten them until failure, thus finding that some had to be substantially longer than Optrex says. There's also a gotcha with the BUSY flag -- it doesn't start working at the point in the initialization process that Optrex states. A wait loop has to be used at each step until the end of initialization. The BUSY flag can and should be used from there onward.
Reply by Will February 4, 20042004-02-04
Ok, I've had limited success so far.  Circuit-wise I have removed the
capacitors from the data lines but left the series and pulldown
resisitors alone.  Program-wise I have added enourmous delays to the
initialization routines and reordered some of the commands.  The
combination seems to have done the trick for initializing the display
since I now get a blinking cursor and some letters.  I say some
letters, because there is still a timing glitch I can't seem to track
down.  I know it has to do with trying to use the Busy Flag instead of
hard coded delays, but despite searching the web and pouring over
cryptic datasheets I cannot find a solution that works.  If someone
familiar with PIC assembly could post a WORKING snippet of code for a
20MHz crystal, or if someone could just post a graphical plot of
signals versus time for checking the busy flag I would greatly
appreciate it!  My new code is appended below.  Thanks for all the
help!
-Will

;	LCD Control Software
;
;	Software uses a 20MHz crystal
;	for timing.
;

;******************************************************************
Stall	MACRO
		LOCAL	  Stall_Jump
		goto Stall_Jump
Stall_Jump
	ENDM
;******************************************************************
Wait_15ms MACRO
	LOCAL OuterLoop
	LOCAL InnerLoop

	movlw .59
	movwf OUTER_COUNTER
OuterLoop
	movlw .255
	movwf INNER_COUNTER
InnerLoop
	Stall
	decfsz INNER_COUNTER, F
	goto InnerLoop
	decfsz OUTER_COUNTER, F
	goto OuterLoop
	ENDM
;******************************************************************
Wait_4.1ms MACRO
	LOCAL OuterLoop
	LOCAL InnerLoop

	movlw .17
	movwf OUTER_COUNTER
OuterLoop
	movlw .255
	movwf INNER_COUNTER
InnerLoop
	Stall
	decfsz INNER_COUNTER, F
	goto InnerLoop
	decfsz OUTER_COUNTER, F
	goto OuterLoop
	ENDM
;******************************************************************
Wait_100us MACRO
	LOCAL InnerLoop

	movlw .100
	movwf INNER_COUNTER
InnerLoop
	Stall
	decfsz INNER_COUNTER, F
	goto InnerLoop
	ENDM
;******************************************************************
CheckBusyFlag MACRO
	LOCAL JumpPoint
JumpPoint
	bcf RS
	bsf RW
	nop
	nop
	bsf ENABLE
	nop
	nop
	nop
	nop
	nop
	bcf ENABLE
	btfsc BUSY_FLAG
	goto JumpPoint
	ENDM
;******************************************************************
	list p=16F877

	; Include file, change directory	if	needed
	include "p16f877.inc"

#define ENABLE 		PORTE, 2
#define RS 				PORTE, 1
#define RW 				PORTE, 0

#define DATA_PORT 	PORTD
#define BUSY_FLAG 	PORTB, 6

OUTER_COUNTER		equ 0x20
INNER_COUNTER		equ 0x21

W_TEMP				equ 0x70
STATUS_TEMP			equ 0x71
PCLATH_TEMP			equ 0x72


;//Reset Vector
 Org 0x00
	clrf	 PCLATH				 ;	ensure page	bits are	cleared
	goto	 Initialize

;//Interrupt Vector
 ORG 0x04
	MOVWF   W_TEMP          ;Copy W to TEMP register
	SWAPF   STATUS,W        ;Swap status to be saved into W
	CLRF    STATUS          ;bank 0, regardless of current bank, Clears
IRP,RP1,RP0
	MOVWF   STATUS_TEMP     ;Save status to bank zero STATUS_TEMP
register
	MOVF    PCLATH, W       ;Only required if using pages 1, 2 and/or 3
	MOVWF   PCLATH_TEMP     ;Save PCLATH into W
	CLRF    PCLATH          ;Page zero, regardless of current page

	;TO DO:  Fill in for interrupt vectoring

	banksel PCLATH_TEMP
	MOVF    PCLATH_TEMP, W  ;Restore PCLATH
	MOVWF   PCLATH          ;Move W into PCLATH
	SWAPF   STATUS_TEMP,W   ;Swap STATUS_TEMP register into W
			                  ;(sets bank to original state)
	MOVWF   STATUS          ;Move W into STATUS register
	SWAPF   W_TEMP,F        ;Swap W_TEMP
	SWAPF   W_TEMP,W        ;Swap W_TEMP into W
	retfie						; return	from interrupt

;//Initialization from powerup
Initialize
	clrf INTCON
	clrf INTCON
CGIE
	bcf	 INTCON,	GIE
	btfsc	 INTCON,	GIE
	goto	 CGIE
	clrf INTCON

;	//Declare port/pin definitions
	banksel TRISA
	movlw  B'00000111'
	movwf  ADCON1			; Port A is all digital
	movlw	 B'00000000'
	movwf	 TRISA			; Port A is OOOOOOOO
	movlw	 B'01000000'
	movwf	 TRISB			; Port B is OIOOOOOO
	movlw	 B'10000001'
	movwf	 TRISC			; Port C is IOOOOOOI
	movlw	 B'00000000'
	movwf	 TRISD			; Port D is OOOOOOOO
	bcf TRISE, PSPMODE	; Turn off the parallel port
	bcf TRISE, 0			; Port E is -----OOO
	bcf TRISE, 1
	bcf TRISE, 2
	bsf OPTION_REG, 7		;Turn off port B pullups

	banksel PORTB
	call Big_Delay
	call Big_Delay
	call Big_Delay
	call Big_Delay

	banksel OUTER_COUNTER
	bsf PORTB, 7

	Wait_15ms
	Wait_15ms

	bcf PORTB, 7

	bcf RS
	bcf RW
	movlw b'00111000'
	call StrobeData

	Wait_15ms
	Wait_15ms

	bcf RS
	bcf RW
	movlw b'00111000'
	call StrobeData

	Wait_15ms
	Wait_15ms

	bcf RS
	bcf RW
	movlw b'00111000'
	call StrobeData

	Wait_15ms
	Wait_15ms

	bcf RS
	bcf RW
	movlw b'00111000'
	call StrobeData

	Wait_15ms
	Wait_15ms

	call DisplayOFF_CursorOFF_BlinkOFF
	Wait_15ms
	Wait_15ms

	call ClearDisplay
	Wait_15ms
	Wait_15ms

	call EntryModeSet
	Wait_15ms
	Wait_15ms

	call DisplayON_CursorON_BlinkON
	Wait_15ms
	Wait_15ms

	movlw b'01001000' ;H
	call SendChar
	movlw b'01100101' ;e
	call SendChar
	movlw b'01101100' ;l
	call SendChar
	movlw b'01101100' ;l
	call SendChar
	movlw b'01101111' ;o
	call SendChar
	movlw b'01010111' ;W
	call SendChar
	movlw b'01101111' ;o
	call SendChar
	movlw b'01110010' ;r
	call SendChar
	movlw b'01101100' ;l
	call SendChar
	movlw b'01100100' ;d
	call SendChar

Eternal
	bsf PORTB, 0
	nop
	bcf PORTB, 0
	goto Eternal
	
;-----------
StrobeData
	nop
	bsf ENABLE
	nop
	nop
	movwf DATA_PORT
	nop
	nop
	bcf ENABLE
	return
;-----------
EntryModeSet
	CheckBusyFlag
	bcf RW
	movlw b'00000110'
	call StrobeData
	return
;-----------
SendChar
	CheckBusyFlag
	bsf RS
	bcf RW
	call StrobeData
	return
;-----------
ClearDisplay
	CheckBusyFlag
	bcf RW
	movlw 0x01
	call StrobeData
	return
;-----------
HomeCursor
	CheckBusyFlag
	bcf RW
	movlw 0x02
	call StrobeData
	return
;-----------
DisplayOFF_CursorOFF_BlinkOFF
	CheckBusyFlag
	bcf RW
	movlw b'00001000'
	call StrobeData
	return
;-----------
DisplayOFF_CursorOFF_BlinkON
	CheckBusyFlag
	bcf RW
	movlw b'00001001'
	call StrobeData
	return
;-----------
DisplayOFF_CursorON_BlinkOFF
	CheckBusyFlag
	bcf RW
	movlw b'00001010'
	call StrobeData
	return
;-----------
DisplayOFF_CursorON_BlinkON
	CheckBusyFlag
	bcf RW
	movlw b'00001011'
	call StrobeData
	return
;-----------
DisplayON_CursorOFF_BlinkOFF
	CheckBusyFlag
	bcf RW
	movlw b'00001100'
	call StrobeData
	return
;-----------
DisplayON_CursorOFF_BlinkON
	CheckBusyFlag
	bcf RW
	movlw b'00001101'
	call StrobeData
	return
;-----------
DisplayON_CursorON_BlinkOFF
	CheckBusyFlag
	bcf RW
	movlw b'00001110'
	call StrobeData
	return
;-----------
DisplayON_CursorON_BlinkON
	CheckBusyFlag
	bcf RW
	movlw b'00001111'
	call StrobeData
	return
;-----------
ShiftCursorRight
	CheckBusyFlag
	bcf RW
	movlw b'00010100'
	call StrobeData
	return
;-----------
ShiftCursorLeft
	CheckBusyFlag
	bcf RW
	movlw b'00010000'
	call StrobeData
	return
;-----------
ShiftDisplayRight
	CheckBusyFlag
	bcf RW
	movlw b'00011100'
	call StrobeData
	return
;-----------
ShiftDisplayLeft
	CheckBusyFlag
	bcf RW
	movlw b'00011000'
	call StrobeData
	return
;-----------
;******************************************************************
Little_Delay
	Stall
	Stall
	Stall
	Stall
	Stall
	Stall
	Stall
	Stall
	Stall
	Stall
	Stall
	Stall
	Stall
	Stall
	Stall
	Stall
	Stall
	Stall
	Stall
	Stall
	Stall
	Stall
	Stall
	Stall
	Stall
	Stall
	Stall
	Stall
	Stall
	Stall
	Stall
	Stall
	Stall
	Stall
	Stall
	Stall
	Stall
	Stall
	Stall
	Stall
	Stall
	Stall
	Stall
	Stall
	Stall
	Stall
	Stall
	Stall
	Stall
	Stall
	Stall
	Stall
	Stall
	Stall
	Stall
	Stall
	Stall
	Stall
	Stall
	Stall
	Stall
	Stall
	Stall
	Stall
	Stall
	Stall
	Stall
	Stall
	Stall
	Stall
	return
Big_Delay
   call Little_Delay
   call Little_Delay
   call Little_Delay
   call Little_Delay
   call Little_Delay
   call Little_Delay
   call Little_Delay
   call Little_Delay
   call Little_Delay
   call Little_Delay
   call Little_Delay
   call Little_Delay
Medium_Delay
   call Little_Delay
   call Little_Delay
   call Little_Delay
   call Little_Delay
   call Little_Delay
   call Little_Delay
   call Little_Delay
   call Little_Delay
   call Little_Delay
   call Little_Delay
   call Little_Delay
   call Little_Delay
   call Little_Delay
   return
;-----------
 END
Reply by Meindert Sprang February 4, 20042004-02-04
"Will" <larkmore@aol.com> wrote in message
news:5faf6114.0402040514.57b699fd@posting.google.com...
> "Meindert Sprang" <mhsprang@NOcustomSPAMware.nl> wrote in message
news:<40209d2c$1@news.nb.nu>...
> > Your strobedata routine is too fast. Many LCD displays have a cycle time
of
> > 500ns to 1000ns, where the E has to be kept high for 300 to 500ns or
longer.
> > I'm not sure how you're arriving at that conclusion.
By reading the datasheets and experience. Driving earlier LCD's from a '51 bus was already a problem. You had to use nifty adressing tricks to get it running as a memory mapped device. the other solution was to drive the port pins directly. But I strongly suggest to remove the caps. Your signals do not have the proper rise and fall time requirements. And they simply block a strobe as as short as a microsecond. Meindert
Reply by Michael February 4, 20042004-02-04
CWatters wrote:
> > "Will" <larkmore@aol.com> wrote in message > news:5faf6114.0402031434.38db8ce2@posting.google.com... > > > with 10KOhm pulldown resistors to ground on ALL of the lines on the > > I think one pin on the most PICs is open collector.
Ah yes ... the famous open collector gotcha. That's another trap for amateurs. It still bites me from time to time, even after upteen Microchip projects.
Reply by Michael February 4, 20042004-02-04
Will wrote:
> > I have an Optrex LCD (DMC-20481NY-LY-AGE) that is 4x20 characters and > driven by a Microchip PIC16F877 running at 20MHz. I know I got this > exact same physical LCD to work before but for the life of me I can't > recall what trick I used to do so. Attached at the end is my > software. I get power to the LCD, but all I see is lines 1 and 3 as > all dark and lines 2 and 4 as all clear. Hunting around newsgroups > leads me to think my initialization routines aren't working (gee, ya > think?!?!) but as near as I can tell I have met or exceeded all of the > timing requirements for data transfer. PLEASE HELP!!!!! If it > matters, I am using a dedicated 5V DC supply to drive both the PIC and > the LCD. The PIC is connected to the LCD through 330 Ohm resistors, > with 10KOhm pulldown resistors to ground on ALL of the lines on the > PIC side. This was because I was seeing a lot of glitches on powerup > due to ports being inputs. Each line also has a .01uF cap to ground > and there is a bypass capacitor on the 5V line to ground next to the > PIC. The BusyFlag is also connected directly from the LCD to the PIC > on PORTB, 6. Thanks for any insight! > -Will
(Maybe it's obvious from your code .... but I didn't read it.) The first thing I'd do is get rid of all the pulldowns and caps; you can add 'em all later if you really-really have to. I've driven half a dozen different LCDs with three kinds of PICs for several years and never needed all that extra hardware. The most persistant bug in my LCD boilerplate setup routines is that it's 5x8 dots, 2x20 display and the LCD I've got hooked up is different from those. I recall being in the same boat as you are now ... for days! ... gnashing my teeth because I _knew_ the code worked (I was looking at at earlier project that used the same code), and I _knew_ the LCD was OK (because it worked when hooked up to a different project). Yes, it was a case of operator error; the display that wouldn't initialize was not a 2x20 but a 1x16.