SparkFun Forums 

Where electronics enthusiasts find answers.

Have questions about a SparkFun product or board? This is the place to be.
By traverc
#159526
I'm using a 3.3V microcontroller to write to the LCD-09053 display, with 4-bit mode. I'm not checking the busy signal, just using long delays. The control signals seem to match the specs on the logic analyzer, but the display only displays a single row of black squares. Increasing Vdd from 3.3V to 4.5V does cause a second row of black squares to appear. Any ideas what might be wrong? Even a suggestion about whether it might be timing or voltage levels would be helpful.
Code: Select all
By traverc
#159546
I've tried many variations, but here is the simplest version, which should just set up the display and blank it. I've included the C program and the assembly routine that it calls.
Code: Select all
//Global temperature variables go here
unsigned char indoorTemp = 0;
unsigned char outdoorTemp = 0;

#include <hidef.h> /* for EnableInterrupts macro */
#include "derivative.h" /* include peripheral declarations */

//Prototypes subroutines:
//-----------------------------------------------------------
void msleep(unsigned long sleeptime);
void updateTemps(void);
void LCDSetup(void);
void writeData(void);
void GetTemp(void);

void main(void) {

  EnableInterrupts; /* enable interrupts */
  /* include your code here */
 msleep(1000);     //delay 1 second to wait for power up of LCD display
 PTBDD = 0xFF;     //set port B bits to be outputs
 LCDSetup();       //initialize the LCD

  for(;;) {
    __RESET_WATCHDOG(); /* feeds the dog */
  } /* loop forever */
  /* please make sure that you never leave main */
}

void msleep(unsigned long sleeptime){             //Roughly 1msec per count @ 4MHz
    unsigned long x;
    unsigned long maxtime;
    unsigned long y;
    maxtime=(unsigned long)sleeptime*11;
    for(x=0; x<maxtime;x++){
          __RESET_WATCHDOG(); /* feeds the dog */
         y=x;  //Does nothing except help calibrate timing
        }
 }

void updateTemps(void){
  
//  unsigned char * inTemp = (unsigned char *)0x67;
//  unsigned char * outTemp = (unsigned char *)0x68;
/*modified to match the actual assembly code locations */
    unsigned char * inTemp = (unsigned char *)0x66;
    unsigned char * outTemp = (unsigned char *)0x67;
    //Sample the indoor and outdoor temperatures from the sensors
  //and update the LCD screen
  //-----------------------------------------------------------
  GetTemp();       //changed from getTemp to GetTemp
              
  //Copy the values written by the (assembly code) 
  indoorTemp = *inTemp;
  outdoorTemp = *outTemp;              
}

;SUBROUTINE LCDSetup********************************
LCDSetup:
		sthx $68			; save Index Register in $68:$69
		sta $65				; save A in $65

   	;Wait 200ms to let display initialize
	;(Not needed if already >= 200ms since power-on)

		bset E, $02		; Ensure E line is high	(inactive)
		bclr RS, $02
		lda $02
		and #$0f
		ora #$20
		sta $02			;Set data bus to $2

;		bclr E, $02		; bring E line low 
;		jsr wait_100us		;Wait 100us
;		bset E, $02		; bring E line high
		mov #$28, $70		;Set "OUTPUT" = 0x28 - Function set - 4-bit, 2-line, 5x8 dots
		jsr write_control_Byte	
		mov #$0C, $70		; $0C -> $70  - Display ON/OFF - on, cursor off, blinking off
		jsr write_control_Byte	; write control char ($70)
		mov #$01, $70			; $01 -> $70 - Clear display 
		jsr write_control_Byte	; write control char ($70)
		
		jsr delay_2ms		; delay 2ms

		mov #$06, $70			; $06 -> $70 - Entry mode set - cursor moves right, no shift of entire display
		jsr write_control_Byte	; write control char ($70)
		mov #$02, $70			; $02 -> $70- Return cursor home
		jsr write_control_Byte	; write control char ($70)
		jsr delay_2ms
		rts
; END SUBROUTINE LCDSetup**************************************

;SUBROUTINE wait_100us
wait_100us:
		mov #50, $61 
count_100:	
	 	;nop
	 	nop
		dec $61
		bne count_100
		sta $1800
		rts
;END SUBROUTINE wait_100us************************

; SUBROUTINE write_control_Byte*****************
; control byte to be sent is in address $70

write_control_Byte:
		bset E, $02	; ensure E high
		bclr RS, $02	; clear RS 

		lda $70
		and #$f0		; clear low nibble
		sta $71		; store high nibble in $71
		lda $02		; PTB -> A
		and #$0f		; clear high nibble
		ora $71		; add high nibble from $71 to A
		sta $02		; store result in PTB

		bclr E, $02	; clear E
		jsr wait_100us

		bset E, $02	; E is high

		lda $70
		nsa			; swap nibbles
		and #$f0		; clear low nibble
		sta $71		; store high nibble in $71
		lda $02		; PTB -> A
		and #$0f		; clear high nibble
		ora $71		; add high nibble from $71 to A
		sta $02		; store result in PTB

		bclr E, $02	; clear E
		jsr wait_100us
		bset E, $02
		jsr wait_100us
		rts
;END SUBROUTINE write_control_Byte*****************

;SUBROUTINE delay_2ms***************
delay_2ms:
		mov #20, $60			;Wait 2ms
wait_2ms:
		jsr wait_100us
		dec $60
		bne wait_2ms

		lda $65				; restore A
		ldhx $68				; restore IX
		rts
;END SUBROUTINE delay_2ms

By Blackfin
#159559
Assuming you've got the control signals and databus correctly connected you might re-visit the datasheet for the LCD controller. For example, in the datasheet linked to on the product page:

http://www.sparkfun.com/datasheets/LCD/st7066.pdf

the 4-bit initialization sequence contains three writes to the controller that might be coded as:
Code: Select all
;SUBROUTINE LCDSetup********************************
LCDSetup:
      sthx $68         ; save Index Register in $68:$69
      sta $65            ; save A in $65

      ;Wait 200ms to let display initialize
   ;(Not needed if already >= 200ms since power-on)

      bset E, $02      ; Ensure E line is high   (inactive)
      bclr RS, $02
      lda $02
      and #$0f
      ora #$20
      sta $02         ;Set data bus to $2

;      bclr E, $02      ; bring E line low
;      jsr wait_100us      ;Wait 100us
;      bset E, $02      ; bring E line high

; add code starting here...
      mov #$30, $70      ;initial write of 0x03 3x per datasheet
      jsr write_control_nibble
      jsr delay_2ms        ;wait >15mS (or you could write a 16mS delay func...)
      jsr delay_2ms
      jsr delay_2ms
      jsr delay_2ms
      jsr delay_2ms
      jsr delay_2ms
      jsr delay_2ms
      jsr delay_2ms

      mov #$30, $70      ;initial write of 0x03
      jsr write_control_nibble   
      jsr delay_2ms        ;wait >4.1ms
      jsr delay_2ms
      jsr delay_2ms

      mov #$30, $70      ;initial write of 0x03 3x
      jsr write_control_nibble   
      jsr wait_100us    ;wait > 100uS
      jsr wait_100us

; ...to here

      mov #$28, $70      ;Set "OUTPUT" = 0x28 - Function set - 4-bit, 2-line, 5x8 dots
      jsr write_control_Byte   
      mov #$0C, $70      ; $0C -> $70  - Display ON/OFF - on, cursor off, blinking off
      jsr write_control_Byte   ; write control char ($70)
      mov #$01, $70         ; $01 -> $70 - Clear display
      jsr write_control_Byte   ; write control char ($70)
.
.
.

; add func to write one nibble to LCD
write_control_nibble:
      bset E, $02   ; ensure E high
      bclr RS, $02   ; clear RS

      lda $70
      and #$f0      ; clear low nibble
      sta $71      ; store high nibble in $71
      lda $02      ; PTB -> A
      and #$0f      ; clear high nibble
      ora $71      ; add high nibble from $71 to A
      sta $02      ; store result in PTB

      bclr E, $02   ; clear E
      jsr wait_100us
      bset E, $02   ; E is high

      jsr wait_100us
      rts
;END SUBROUTINE write_control_nibble*****************

By traverc
#159584
Blackfin wrote:Assuming you've got the control signals and databus correctly connected you might re-visit the datasheet for the LCD controller. For example, in the datasheet linked to on the product page:

http://www.sparkfun.com/datasheets/LCD/st7066.pdf

the 4-bit initialization sequence contains three writes to the controller that might be coded as:
----
Changing the delays did change the behavior of the display, in that it flashes from one row of rectangles to two rows, and then settles at one row, but still no luck displaying characters. I'm going to look at the delays in the data writes next.

Any idea why the initialization flowchart in the datasheet says to wait for Vcc > 4.5V, yet it is advertised to work with a 2.7 - 5V supply?
By Blackfin
#159626
Good question. Check some of the comments on the product page at Sparkfun. It appears you're not the only one to see some issues running at 3.3V.

Are you sure you have the contrast setting correct?
By traverc
#159627
I have Vo tied to ground. The contrast seems fine, at least those black rectangles display beautifully. I have tried running it at 4.5V. The behavior is a little different, but still not correct. Thanks for responding. Still working on the problem. Will post a solution if I find one.
By traverc
#159716
The potentiometer helped, thank you! It is still not displaying characters, but at least it is blanking.
I found a discrepency between the 4-bit initialization flowchart and the instruction table on the datasheet. The flowchart for the 4-bit interface shows the "Function Set" bit pattern so that N and F are in the D5 D4 positions. In the instruction table (and the instruction explanations), they are in the D7 D6 position. I don't think this is the problem, but it is giving me less confidence about following the datasheet.