student001
student001

Reputation: 533

LCD programming 80188 8255

I am programming LCD with 80188, using 8255. I am writing a basic code to display some text,but it doesnt work. As follows:

STI
PORTA   EQU     0080H
PORTB   EQU     0081H
PORTC   EQU     0082H
CWR     EQU     0083H

;set 8255 output
MOV AL, 89H       
MOV DX, CWR
OUT DX, AL        ;send the control word

NEXT:

call far ptr lcd
JMP NEXT

lcd proc far

PUSH    DX
PUSH    CX
PUSH    BX
PUSH    AX

SETUP:

; mov AX, DATA_SEG ; mov AX,AX ; mov ES,AX

;The following sends all the necessary commands to the LCD
MOV AL, 38H ;initialize LCD for 2 lines & 5*7 matrix
CALL COMNDWRT ;write the command to LCD 
CALL DELAY ;wait before issuing the next command
CALL DELAY 
;this command needs lots of delay
CALL DELAY
MOV AL, 0EH ;send command for LCD on, cursor on 0000 1110b 
CALL COMNDWRT
CALL DELAY
MOV AL, 01   ;clear LCD
CALL COMNDWRT
CALL DELAY
MOV AL, 06   ;command for shifting cursor right
CALL COMNDWRT
CALL DELAY

COMNDWRT PROC ;this procedure writes commands to LCD
    PUSH DX ;save DX
    MOV DX, PORTB  ; connected to LCD
    OUT DX, AL   ;send the code to Port B
    MOV DX, PORTC
    MOV AL, 00000100B ;RS=0,R/W=0,E=1 for H-To-L pulse
    OUT DX, AL ; send setup to PORT C
    NOP
    NOP
    MOV AL, 00000000B ;RS=0,R/W=0,E=0 for H-To-L pulse
    OUT DX, AL
    POP DX
    RET
COMNDWRT ENDP

MOV AL, 1 ;display ‘1’ letter
CALL DATWRIT ;issue it to LCD
CALL DELAY ;wait before issuing the next character
MOV AL, 2 ;display ‘2’ letter
CALL DATWRIT ;issue it to LCD
CALL DELAY ;wait before issuing the next character
MOV AL, 5 ;display ‘5’ letter
CALL DATWRIT ;issue it to LCD
CALL DELAY ;wait
;data write to LCD without checking the busy flag
;AL = char sent to LCD

DATWRIT PROC
    PUSH DX  ;save DX
    MOV DX, PORTB  ;DX=port B address
    OUT DX, AL ;issue the char to LCD
    MOV AL, 00000101B ;RS=1,R/W=0, E=1 for H-to-L pulse
    MOV DX, PORTC ;port C address
    OUT DX, AL  ;make enable high
    MOV AL, 00000001B ;RS=1,R/W=0 and E=0 for H-to-L pulse
    OUT DX, AL
    POP DX
    RET
DATWRIT ENDP

DELAY PROC
    MOV CX, 1325  ;1325*15.085 usec = 20 msec
    PUSH AX
    W1: IN AL, 61H
    AND AL, 00010000B
    CMP AL, AH
    JE W1
    MOV AH, AL
    LOOP W1
    POP AX
    RET
DELAY ENDP

;JMP SETUP
POP AX
POP BX
POP CX
POP DX
ret 

lcd endp

CODE_SEG ENDS END

Can anyone tell if I am missing something?

Upvotes: 1

Views: 674

Answers (2)

Baxsie
Baxsie

Reputation: 1

I am going to assume this is an "HD44780" character LCD, connected in 8-bit mode.

I see what looks like an assembly syntax error. For this:

MOV AL, 1 ;display ‘1’ letter

You probably want:

MOV AL, '1' ;display ‘1’ letter

or maybe this, if your compiler does not understand the single-quotes:

MOV AL, 31h ;display ‘1’ letter

Just putting 1 in AL is going to select one of the CGRAM characters, which is likely not what you want.

Another thing that often trips up LCD is pin 3, "Vo". This typically needs to be set at around 1v, if you connect it to 5v the characters will be invisible.

For initialization, the HD44780 and its more modern "compatible" replacements are a bit tricky.

From this thread ( https://forum.crystalfontz.com/showthread.php/77 ), there is my tried and true 8-bit initialization code:

//===========================================
void LCD_Initialize(void)
  {
  //This sequence is from the initialization on page 45 of the
  //HD44780U Data Sheet.
  DelayMs(20);
  //Blind_Write_LCD_Control writes without checking the busy bit first.
  Blind_Write_LCD_Control(0x30);
  //Yes, the data sheet says write it twice.
  DelayMs(5);
  Blind_Write_LCD_Control(0x30);
  //Yes, the data sheet says write it three times.
  DelayUs(125);
  Blind_Write_LCD_Control(0x30);
  //Yes, the data sheet says write it four times, but at least this
  //one counts.
  //038h is Function set:
  //8bit,
  //2 line
  //F = (5x8)
  DelayUs(125);
  Blind_Write_LCD_Control(0x38);
  //"Display off"
  Write_LCD_Control(0x08);
  //"Display clear"
  Write_LCD_Control(0x01);
  //This delay is needed  for the Sitronix ST7066 controller. No
  //reasonable explanation, I found it empirically. Not needed for
  //Samsung or Hitachi controllers.
  DelayMs(2);
  //Write_LCD_Control waits for the busy bit to go low, then writes
  //the to the control register.
  //006h is Entry mode set, increment, no shift
  Write_LCD_Control(0x06);
  //Display on, cursor on, blinking
  Write_LCD_Control(0x0F);
  //Clear the display again. This seems to fix a power-up problem
  //where the display shows "{{{{{" in a couple of places.
  Write_LCD_Control(0x01);
  }
//===========================================

Upvotes: 0

Abd M. Srour
Abd M. Srour

Reputation: 11

mov al, 00000100B ; this will reset PC2

mov al, 00000000B ; this will also reset but here for PC0

you said the first one set E then reset it. so lets say E was connected with PC0 and you want rise and then back it to zero that mean a negative edge then you code is:

mov al, 00000001B
mov al, 00000000B

This is a negative edge, also remember you don't know the brev. value of this wire so don't wait for positive edge then negative edge, it's only negative edge.

Upvotes: 1

Related Questions