Die 8051-LCD-Schnittstelle funktioniert in Proteous, aber nicht in Hardware

Ich arbeite an diesem Projekt mit einem 8051-Mikrocontroller (AT89S51) und es beinhaltet die Interaktion mit einem LCD. Das Schema des Projekts, an dem ich arbeite, ist unten dargestellt:

Geben Sie hier die Bildbeschreibung ein

Und ich habe einen sehr einfachen Code für das LCD geschrieben, um Inhalte anzuzeigen. Der Code lautet wie folgt:

ORG 0000H
SJMP INIT_MAIN          ;For interrupts

INIT_MAIN:
      ;Initializing the LCD Display with the initial commands:
      MOV A, #38H       ;Setting up the LCD to operate in 8 bit mode
      ACALL CMD
      MOV A, #0FH       ;Turning the display on
      ACALL CMD
      MOV A, #01H       ;Clearing the curser 
      ACALL CMD
      MOV A, #06H       ;Putting the curser incriment mode to be left to right
      ACALL CMD
      MOV A, #3CH       ;Activating the second line of the LCD
      ACALL CMD
      MOV A, #80H       ;Putting the curser to be at position 1 (the first place)
      ACALL CMD

     ;Writing serially on the LCD
      MOV DPTR, #WELCOME1   ;Pointing the data pointer at the data array WELCOME1
      MOV 41H, #13H     ;Specifying the message's length
      LCALL LCD_SERIAL      ;Giving the command to the uC to print it on the LCD

      MOV A, #0C0H      ;Jump to second line position one
      ACALL CMD

      MOV DPTR, #WELCOME2   ;Pointing the data pointer at the data array WELCOME1
      MOV 41H, #13H     ;Specifying the message's length
      LCALL LCD_SERIAL      ;Giving the command to the uC to print it on the LCD

      MOV A, #094H      ;Jump to third line position one
      ACALL CMD

      MOV DPTR, #WELCOME3   ;Pointing the data pointer at the data array WELCOME1
      MOV 41H, #13H     ;Specifying the message's length
      LCALL LCD_SERIAL      ;Giving the command to the uC to print it on the LCD

      MOV A, #0D4H      ;Jump to fourth line position one
      ACALL CMD

      MOV DPTR, #WELCOME4   ;Pointing the data pointer at the data array WELCOME1
      MOV 41H, #10H     ;Specifying the message's length
      LCALL LCD_SERIAL      ;Giving the command to the uC to print it on the LCD

      MOV A, #0FFH      ;Pointing the curser away from the screen
      ACALL CMD

MAIN:
      SJMP MAIN
;-------------------------------------DELAY SUBROUTINES-------------------------------------
DELAY_1ms:          ;delay for 1ms subroutine
      MOV 39H,#0FAH         ;Load 0FA into the register 39H
      MOV 40H,#0FAH     ;Load 0FA into the register 40H
      LABEL1: DJNZ 39H,LABEL1   ;Decrease 39H by one and jump if not zero
      LABEL2: DJNZ 40H,LABEL2   ;Decrease 40H by one and jump if not zero
      RET

;-------------------------------------LCD SUBROUTINES---------------------------------------
CMD:                    ;Commands used in intializations
      MOV P1, A         ;Move the values of A to Pin 1. These will be the commands we want to transfer
      CLR P3.5          ;This makes the RS equal to 0. When RS is zero, 
      CLR P3.6          ;This makes the RW equal to 0. When RW is zero,
      SETB P3.7         ;This control the latch. Setting it and resetting it, latches the data
      CLR P3.7          ;This control the latch. Setting it and resetting it, latches the data
      ACALL DELAY_1ms   ;A delay is required because on practical LCDs, it takes some time to change
      RET

LCD_SERIAL:             ;Used to display strings onto the LCD
      MOV R0, #00H
REPEAT:
      MOV A,R0
      MOVC A,@A+DPTR        ;obtain LCD lookup table
      ACALL LCD_DISPLAY     ;Display the character on the screen
      INC R0                ;Increment R0
      DJNZ 41H, REPEAT
      RET

LCD_DISPLAY:            ;Used to display info onto the LCD
      MOV P1, A         ;Move the values of A to pin 1. The data will now be on Port 1
      SETB P3.5         ;This makes RS equal to 1. When RS is one, 
      CLR P3.6          ;This makes the RW equal to 0. When RW is one,
      SETB P3.7         ;This control the latch. Setting it and resetting it, latches the data
      CLR P3.7          ;This control the latch. Setting it and resetting it, latches the data
      ACALL DELAY_1ms       ;A delay is required because on practical LCDs, it takes some time to change
      RET

;--------------------------------------LOOK UP TABLES---------------------------------------
WELCOME1:
DB 'WELCOME TO THE BANK'

WELCOME2:
DB 'PREVIOUS NUMBER 000'

WELCOME3:
DB 'YOUR NUMBER IS: ---'

WELCOME4:
DB 'HAVE A GOOD DAY!'


END

Der obige Code ist nicht der vollständige Code, den ich geschrieben habe, sondern nur die Teile, die für das LCD-Display relevant sind.

Dieser Code funktioniert gut in der proteösen Simulation (wie aus dem Bild ersichtlich). Es funktioniert jedoch überhaupt nicht, wenn ich es auf einer echten Schaltung konstruiere. Manchmal schaltete sich die LCD-Hintergrundbeleuchtung einfach ein und es wurde nichts angezeigt (nicht einmal schwarze Quadrate), selbst wenn ich das Potentiometer einstellte. Manchmal wurden die schwarzen Quadrate angezeigt, aber beim Zurücksetzen des 8051 verschwanden sie.

Falls es darauf ankommt, der Programmierer, den ich verwende, ist der MikroE 8051-Programmierer.

Folgendes habe ich gestern beim Aufbau der Schaltung gemacht:

  1. Stellen Sie sicher, dass alle meine Jumper tatsächlich leitend waren, indem Sie sie zuerst an einer LED überprüften.
  2. Versuchte diesen Code mit mehreren LCD-Displays, keiner von ihnen funktionierte
  3. Versuchte diesen Code auf einem anderen 8051-Chip, es funktionierte immer noch nicht
  4. Ich habe online einen Beispielcode von jemandem erhalten, der einen 8051 mit einem LCD verbindet, und meine LCDs haben immer noch nicht funktioniert

Ich wäre sehr dankbar, wenn mir jemand einen Einblick geben könnte, warum dies der Fall sein könnte

Antworten (2)

Der LCD-Controller befindet sich möglicherweise im 4-Bit-Modus und noch schlimmer in der Mitte zwischen dem ersten und dem zweiten Nibble. Ihr erster Befehl wird also möglicherweise nicht verstanden. Senden Sie es dreimal, um jede Situation zu lösen.

Zusätzlich haben die realen LCDs zeitliche Beschränkungen. IIRC Einige davon benötigen etwas mehr Zeit als 1 ms nach dem Initialisieren von Befehlen. Bitte lesen Sie das Datenblatt des von Ihnen verwendeten Teils. Auch nach dem Einschalten kann es einige Zeit dauern, bis das LCD bereit ist, Befehle anzunehmen.

Überprüfen Sie zuletzt, ob Ihre Verzögerung wirklich 1 ms beträgt.

Überprüfen Sie erneut Ihr LCD-Datenblatt.

In allen LCD-Datenblättern, die ich habe, liegt Masse an Pin 1, Strom an Pin 2 und Kontrast an Pin 3.

Zustimmen. Ungeachtet des gesamten Codes scheinen Ihre Vss, Vdd, Vee falsch zu sein. Proteus emuliert diese wahrscheinlich nicht richtig, wenn überhaupt.