0
\$\begingroup\$

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 ?

\$\endgroup\$
3
  • \$\begingroup\$ So are you running this on a simulator or on real display? What does the AVR code have to do with it, as it might be easier to see what commands and data bytes you send to the display. Also which size display you have? And how the rows and columns are mapped to the display? For example, many 1x16 displays are from the HD44780 point of view 2x8 displays and thus if you don't initialize the display to two lines you get only 1x8 display. \$\endgroup\$
    – Justme
    Commented Jul 6 at 12:47
  • \$\begingroup\$ I run it in simulator "proteus 8", the LCD is 2x16 type and initialised to 4 bits interface mode \$\endgroup\$ Commented Jul 6 at 12:51
  • \$\begingroup\$ Then you can simply try it without AVR and just use pushbuttons in 8-bit mode to test how the LCD simulation works. Simulators are not always 100% correct. \$\endgroup\$
    – Justme
    Commented Jul 6 at 12:56

1 Answer 1

1
\$\begingroup\$

I used an online HD44780 display emulator website and did the following:

  • cmd 0x0F to turn display and blinking cursor on

  • cmd 0x87 to go to address 7

  • cmd 0x05 to set decreasing addresses with display shift

  • sent the letters "HELLO"

and the result was that the website showed the following:

  • 7 empty char cells, blinking cursor on 8th char cell, and text "OLLEH", and three empty char cells.

If Proteus failed to emulate this then it did. If all your four cases what you send to display are identical except for the entry mode set command, then the bug cannot be in your AVR code or connections.

Please be aware that emulators may not work exactly like real world chips do. I did not check your code but emulators may ignore things that you have to take into account with real chips, such as how fast you can send data or how long the display is busy executing a command.

\$\endgroup\$

Not the answer you're looking for? Browse other questions tagged or ask your own question.