1

我正在用 8255 用 80188 对 LCD 进行编程。我正在编写一个基本代码来显示一些文本,但它不起作用。如下:

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

设置:

; 移动 AX, DATA_SEG ; 移动 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 

液晶显示器

CODE_SEG ENDS 结束

谁能告诉我是否遗漏了什么?

4

2 回答 2

1

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.

于 2014-01-21T06:08:48.300 回答
0

我将假设这是一个“HD44780”字符 LCD,以 8 位模式连接。

我看到了一个汇编语法错误。为了这:

MOV AL, 1 ; 显示 '1' 字母

你可能想要:

MOV AL, '1' ; 显示 '1' 字母

或者这个,如果你的编译器不理解单引号:

MOV AL, 31h ; 显示 '1' 字母

只需在 AL 中输入 1 即可选择 CGRAM 字符之一,这可能不是您想要的。

另一个经常绊倒 LCD 的是引脚 3,“Vo”。这通常需要设置在 1v 左右,如果将其连接到 5v,字符将不可见。

对于初始化,HD44780 及其更现代的“兼容”替代品有点棘手。

从这个线程(https://forum.crystalfontz.com/showthread.php/77),有我尝试过的真正的 8 位初始化代码:

//===========================================
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);
  }
//===========================================
于 2015-08-27T04:52:48.350 回答