Ruth Hendrix

LCD timing issue?

Discussion created by Ruth Hendrix Employee on Jan 19, 2006
This message contains an entire topic ported from a separate forum. The original message and all replies are in this single message. We have seeded this new forum with selected information that we expect will be of value to you as you search for answers to your questions.
 
Posted: Fri Dec 10, 2004 1:13 am    

Hi Folks

I am trying to use 2 x 40 character LCD with HC908GP32 running with a 32.768kHz crystal.

The code below (in assembler) work fine in monitor mode, but, not when programmed into the micro.

I would like to use the busy flag from the LCD so that the code is faster and looks neater.

If anyone has any ideas I would like to hear them.

Note that I am only using Port C with an LED to try to work out where the program actually gets to.

When programmed, it looks like that LCD powers up correctly, then nothing.

Have fun

$BASE 10T ; sets number base to 10 unless otherwise specified.



; Setting labels for the ports
PORTA EQU $0000 ; address of PORTA
PORTB EQU $0001 ; address of PORTB
PORTC EQU $0002 ; address of PORTC
PORTD EQU $0003 ; address of PORTD
PORTE EQU $0008 ; address of PORTE
DDRA EQU $0004 ; data direction control for PORTA
DDRB EQU $0005 ; data direction control for PORTB
DDRC EQU $0006 ; data direction control for PORTC
DDRD EQU $0007 ; data direction control for PORTD
DDRE EQU $000C ; data direction control for PORTE
PTAPUE EQU $000D ; Pullup enable register for PORTA
;PTBPUE Pullup enable register for PORTB does not exist
PTCPUE EQU $000E ; Pullup enable register for PORTC
PTDPUE EQU $000F ; Pullup enable register for PORTD
;PTEPUE Pullup enable register for PORTE does not exist


CONFIG1 EQU $1F ; Configuration register address for COP etc

; Setting the labels for the clock speed of the chip
PCTL EQU $36 ; PLL control register
PBWC EQU $37 ; PLL bandwidth control register
PMSH EQU $38 ; PLL multiplier select register high
PMSL EQU $39 ; PLL multiplier select register low
PMRS EQU $3A ; PLL VCO range select register
PMDS EQU $3B ; PLL reference divider select register
; ******

; Setting other register labels
TBCR EQU $001C ; Timebase Control Register

ADSCR EQU $3C ; A/D Converter Status Control Register
ADR EQU $3D ; A/D data Register



; Uses PORT A data lines for the LCD and PORT E for control lines.
; R/W is on PORT D (0-write to, 1-read from LCD)

; PORT E
; Bit 0 will be the Enable line
; Bit 1 will be the RS (register select) line
; ie data (1) or function (0) mode

LCD EQU $0000 ; For sending info to LCD, actually PORT A

LCD_CONTROL EQU $0008 ; PORT E, controls LCD, the following values are sent here to
; operate LCD.
LCD_D_ON EQU %00000011 ; Sets PORT A value as character for LCD.
LCD_D_OFF EQU %00000010 ; Sends PORT A value as character to LCD.
LCD_F_ON EQU %00000001 ; Sets PORT A value as function command for LCD.
LCD_F_OFF EQU %00000000 ; Sends PORT A value as function command to LCD.




org $FFFE ; Sets the reset vector for programmed chip
FDB INIT

org $9000 ; program loads into memory from location specified

INIT LDA #$00 ; Simply initialisation values
LDX #$00

MOV #$31,CONFIG1 ; MCU runs w/o LVI and COP support





LCD_SETUP

MOV #$FF,DDRA ; Set PORTA as output
MOV #$FF,DDRC ; Set PORTC as output
MOV #$FF,DDRD ; Set PORTD as output
MOV #$03,DDRE ; Set PORT E as output (3 because there are only 2 bits).

MOV #$00,PORTC
MOV #$00,PORTD

LDA #$00
LOOP1 LDX #$00
DBNZX *
COM PORTC
DBNZA LOOP1



; IMPORTANT to set LCD as 4 bit, must send ONLY control code '0010' on the 4 data lines,
; THEN start sending the full 8 bit data/control codes in 2x4 bit nibbles, high nibble first!!!

MOV #$20,LCD ; Sets LCD to 4 bit data
MOV #LCD_F_ON,LCD_CONTROL ; Do NOT use the sub routine LCD_FUNCTION here,
NOP ; as it will send 2x4 bit nibbles.
MOV #LCD_F_OFF,LCD_CONTROL

LDA #$00
LOOP2 LDX #$00
DBNZX *
COM PORTC
DBNZA LOOP2


MOV #$28,LCD ; Sets display as 4 bit data, 2 line, 5x7 matrix
;JSR LCD_FUNCTION

LDA #$00
LOOP3 LDX #$00
DBNZX *
COM PORTC
DBNZA LOOP3

MOV #$01,LCD ; Clears display and sends cursor home
JSR LCD_FUNCTION

MOV #$02,LCD ; Sends cursor and display home
JSR LCD_FUNCTION

MOV #$0F,LCD ; Turns display ON, cursor ON, Blink ON.
JSR LCD_FUNCTION

LDHX #LCD_OK ; Load HX regs with location of message
LDA #'^' ; Load A with ascii value of '^'

TEXT_1 MOV X+,LCD ; Copy the contents of location HX to LCD (PORT A). Note, also increments X.
CMP LCD ; Compare LCD with A
BEQ END_LCD_SETUP ; Exits text routine if reach end-of-text marker '^'
JSR LCD_DATA ; Puts text onto LCD screen
JMP TEXT_1

END_LCD_SETUP

JMP *

;*******

LCD_FUNCTION
LDA LCD

STA LCD ; Moves accumulator to location LCD, loads high 4 bits into the LCD screen
MOV #LCD_F_ON,LCD_CONTROL
NOP
MOV #LCD_F_OFF,LCD_CONTROL
JSR LCD_DELAY

NSA ; nibble swaps the accumulator

STA LCD ; Moves accumulator to location LCD, loads high 4 bits into the LCD screen
MOV #LCD_F_ON,LCD_CONTROL
NOP
MOV #LCD_F_OFF,LCD_CONTROL
JSR LCD_DELAY

RTS
;*******

LCD_DATA
PSHA

LDA LCD ; Moves accumulator to location LCD, loads high 4 bits into the LCD screen
MOV #LCD_D_ON,LCD_CONTROL
NOP
MOV #LCD_D_OFF,LCD_CONTROL
JSR LCD_DELAY

NSA ; nibble swaps the accumulator

STA LCD ; Moves accumulator to location LCD, loads high 4 bits into the LCD screen
MOV #LCD_D_ON,LCD_CONTROL
NOP
MOV #LCD_D_OFF,LCD_CONTROL
JSR LCD_DELAY

PULA

RTS
;*******

LCD_DELAY
MOV #$00,DDRA ; Set PORT A as input
MOV #$FF,PORTD ; Sets LCD to read mode
BRSET 7,PORTA,*
MOV #$00,PORTD ; Sets LCD to write mode
MOV #$FF,DDRA ; Set PORTA to output

RTS
;*******

Org $8000
LCD_OK EQU $8000
DB '<LCD OK>^'

Posted: Sun Dec 12, 2004 10:30 pm   

Not to sure but don't you need to reset the stack pointer.

Posted: Mon Dec 13, 2004 8:18 am     

 am reasonably sure that the stack pointer does not need initilizing and as I only do one set of push/pulls, reseting the stack pointer should not be an issue.

Regardless, the program works with a timed LCD_DELAY and the same push/pulls.


Sad

Posted: Mon Dec 13, 2004 7:13 pm    

Hi,

What's your configuration (ports level + XTAL) in Monitor mode ?

Cheers

Posted: Fri Dec 17, 2004 11:16 am    

Helllo,

in your delay routine you have to togggle the ECLK Pin everytime you read the dataport to get actual data. So you have to use a loop ta wait until D7 is cleared.


LCD_DELAY
MOV #$00,DDRA ; Set PORT A as input
MOV #$FF,PORTD ; Sets LCD to read mode
---> toggle ECLK here
BRSET 7,PORTA,* and go back to LCD_DELAY to read again
MOV #$00,PORTD ; Sets LCD to write mode
MOV #$FF,DDRA ; Set PORTA to output

RTS


Posted: Thu Apr 07, 2005 6:58 am    

Thanks for the help folks, it works wonderfully now.

I finally found the time to sit down and work through it all. There were a pile of things that just weren't quite right, mostly with the way I was thinking about it.

Have fun






Message Edited by RChapman on 01-19-2006 04:47 PM

Outcomes