I want to simulate **the Entry set mode ** function of and LCD based on HITACHI 44780 Controller. (Here is the datasheet.)
The "Entry set mode" is given the following code of the 8 bits data bus "0 0 0 0 0 1 I/D S"
The datasheet says:
I/D=0 Decrements the DDRAM address by 1 when a code is written or read
I/D=1 Increments the DDRAM address by 1 when a code is written or read
S=1 Shifts the entire display either to the right (I/D=0) or to the left (I/D=1)
In summary: this function sets the LCD to write from left to right or from right to left and the codes to simulate are (0x04
, 0x05
, 0x06
and 0x07
, these are the combinations of Entry set mode code.)
Here is my AVR assembly program use to simulate these codes (combinations)
; VARIABLES
;====================================================================
.EQU RS=0
.EQU RW=1
.EQU EN=2
.EQU _5us=254
.EQU _100us=155
.EQU _5ms=215
;Init_Stack pointer
LDI R16,HIGH(RAMEND)
OUT SPH,R16
LDI R16,LOW(RAMEND)
OUT SPL,R16
;Configure PORTS
LDI R16,0xFF
OUT DDRA,R16 ;Config PORTA as output
OUT DDRB,R16 ;Config PORTB as output
LDI R18,0x00
OUT PORTB,R18
;POWER ON THE LCD
LDI R20,_5ms
RCALL DELAY
RCALL LCD_init
RCALL DELAY
;================================================================================================
;Set the Entry mode
LDI R16,0x05 ;Right shift display (Decrement the cursor and enable shift)
RCALL CMD_WRT
;================================================================================================
;Display my message with a shift to right
;I set the cursor at the 7th address of the display range of LCD (0x07)
;and I expect the display to be written in the revers order " OLLEH "
;with a shift to the right starting form 0x07 of LCD
;Display First message starting from 7 position of 1st line
LDI R16,0x87 ;Set the cursor at the 7 address (0x07) of the LCD display
RCALL CMD_WRT
LDI ZH,HIGH(MSG1<<1)
LDI ZL,LOW(MSG1<<1)
RCALL MS_DISP
HERE:
RJMP HERE
;====================================================================
LCD_init:
PUSH R16
PUSH R20
LDI R20,_5ms
LDI R16,0x33 ;Start initialization
RCALL CMD_WRT
RCALL DELAY
LDI R16,0x32 ;Initialization process
RCALL CMD_WRT
RCALL DELAY
LDI R16,0x28 ;Function set to 4bit mode with 2 lines and 5x8 dots
RCALL CMD_WRT
RCALL DELAY
LDI R16,0x0F;..... ;Display ON, Cursor ON,Blinking ON, change the value of R16 for test
RCALL CMD_WRT
RCALL DELAY
LDI R16,0x01 ;Clear Display
RCALL CMD_WRT
RCALL DELAY
LDI R16,0x06;..... ;Set Entry Mode to shift left
RCALL CMD_WRT
RCALL DELAY
POP R20
POP R16
RET
CMD_WRT:
PUSH R27
PUSH R20
;High nibble manipulation
MOV R27,R16
ANDI R27,0xF0 ;Mask the low nibble and keep the high one
OUT PORTA,R27
CBI PORTB,RS ;Set RS=0 for commands
SBI PORTB,EN ;Set EN=1 to generate a pulse
LDI R20,_5us
RCALL DELAY ;Delays the pulse (duration)
CBI PORTB,EN ;Reset EN=0 to latch the data
LDI R20,_100us ;
RCALL DELAY
;Low nibble manipulation
MOV R27,R16
SWAP R27 ;Swap the content of R16 to get the low nibbles
ANDI R27,0xF0 ;Mask the low nibble and keep the high one
OUT PORTA,R27
CBI PORTB,RS ;Set RS=0 for command write
SBI PORTB,EN ;Set EN=1
LDI R20,_5us
RCALL DELAY
CBI PORTB,EN
LDI R20,_100us
RCALL DELAY
POP R20
POP R27
RET
DATA_WRT:
PUSH R27
PUSH R20
MOV R27,R16 ;Load R27 with the content of R16
ANDI R27,0xF0 ;Mask low nibble and keep high nibble
OUT PORTA,R27
SBI PORTB,RS ;Set RS=1 for data write
SBI PORTB,EN ;Set EN=1 to allow data latch
LDI R20,_5us
RCALL DELAY ;Duration of the pulse
CBI PORTB,EN
LDI R20,_100us
RCALL DELAY
;Low nibble manipulation
MOV R27,R16
SWAP R27 ;Swap the content of R27
ANDI R27,0xF0 ;Mask the low nibble and keep the high one
OUT PORTA,R27 ;Send data to the output port
SBI PORTB,RS ;Set RS=1 for data sent
SBI PORTB,EN ;Set EN=1 for data latch
RCALL DELAY
CBI PORTB,EN
LDI R20,_100us
RCALL DELAY
POP R20
POP R27
RET
MS_DISP:
PUSH R16
PUSH R20
LDI R20,_5ms
_DISP:LPM R16,Z+
RCALL DATA_WRT
RCALL BIG_DELAY
CPI R16,0
BRNE _DISP
POP R20
POP R16
RET
DELAY:
PUSH R17
OUT TCNT0,R20 ;Load TCNT0 with the appropriate prescale
LDI R17,0x01
CPI R20,_100us
BRNE L1
LDI R17,0x02
L1:CPI R20,_5ms
BRNE L2
LDI R17,0x05
L2:OUT TCCR0,R17 ;Normal mode,Int Clk,Prescal=8 for us delay and 1024 for ms delay
AGAIN:IN R17,TIFR
SBRS R17,TOV0
RJMP AGAIN
LDI R17,0x00
OUT TCCR0,R17 ;Turn OFF the timer0
LDI R17,1<<TOV0
OUT TIFR,R17
POP R17
RET
BIG_DELAY:
PUSH R21
PUSH R20
LDI R20,_5ms
LDI R21,0x55
S_DELAY:RCALL DELAY
DEC R21
BRNE S_DELAY
POP R20
POP R21
RET
.ORG 0x200
MSG1: .DB "HELLO ",0
When I simulate my program with the following codes of Entry set mode:
- 0x04, the message is displayed from right to left starting from the desired DDRAM address (works as expected)
0x06
, the message is displayed from left to right starting from de desired LCD position (Works as expected)0x07
, the message is displayed form left to right with a shift starting from de desired LCD position (Works as expected)
But when I provide 0x05
code as in my program, I expect the display to start from position 7 and shift to the right, and the final display should be " OLLEH", but it does not work as it is expected and nothing is displayed (the LCD is like if it is cleared).
Could anyone please explain to me this fact? and what did I miss ?