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:
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:
Ich wäre sehr dankbar, wenn mir jemand einen Einblick geben könnte, warum dies der Fall sein könnte
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.
Lötrauch