- LiTime Speicher und Akkus         
Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 20

Thema: DIP LCD (KS0073) Problem

  1. #1
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    21.04.2005
    Ort
    Hannover
    Beiträge
    190

    DIP LCD (KS0073) Problem

    Anzeige

    LiFePo4 Akku selber bauen - Video
    Hallo zusammen!

    Ich hab schon hier im Forum danach gesucht und es gibt wohl öfter solche Probleme wie ich eins habe.
    Folgendes: Ich habe ein 4*20 LCD in DIP Ausführung mit KS0073 (HD44780 kompatiblen) Kontroller an einen AT89S8252.
    Es funktioniert soweit auch alles nur wird auf dem LCD der letzte Teil der ersten Zeile und der (eigentlich) 2. Zeile immer eine Zeile darunter angezeigt.
    Beispiel (ist n Temperaturfühler):

    Innen : 22.5 °C
    22.5 °C
    Aussen: 18.4 °C
    18.4 °C

    Braucht ja keiner....
    Weiss jemand wie ich das in den Griff bekommen kann?

    Vielen Dank

    Marten83

  2. #2
    Rudi Ratlos
    Gast
    Hallo,

    der Fehler liegt in der falschen Initialisierung. Der Controller ist eben nur fast kompatibel mit dem HD44780.
    Nach dem Umschalten in den 4 Bit-Modus muss ein bestimmtes Bit gesetzt werden (in der Command-Tabelle die Spalte links), dann - und nur dann - kann man den Controller in den 4-Zeilen-Modus umschalten.
    Danach ist zu beachten, dass die Zeile 2 an der Adresse h20, Zeile 3 bei h40 und Zeile 4 bei h60 beginnen.
    Den entsprechenden Code habe ich leider zur Zeit nicht präsent, er ist auch im C-Control-Basic geschrieben.
    Wenn er benötigt wird, dann bitte Nachricht hinterlassen, die Antwort kann sich aber 1 Tag hinziehen.

  3. #3
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    21.04.2005
    Ort
    Hannover
    Beiträge
    190
    Danke schonmal für die Anregung.
    Leider hab ich keinen Plan davon was genau ich wo ändern kann weil ich auch relativ neu auf dem Gebiet bin.
    Wenn du meinst dein Code könnte mir bei der Lösung helfen, dann würde ich mich freuen diesen mal zu sehen.

  4. #4
    ronny_s
    Gast
    Hatte das gleiche Problem, Du mußt bei der Initialisierung des Displays ein "Enable-Bit" setzen (siehe Datenblatt).
    Ich habe mir dazu eine Libray erstellt, die ich dann in Bascom als erstes mit aufrufe.
    Also so:
    Code:
    $regfile = "m8def.dat"                  'für ATMEL ATMEGA8
    $crystal = 4000000                      'Quarz: 4 MHz
    $baud = 19200                            'Baudrate
    $lib "DIP_LCD.lib"                        'Libary einbinden
    initlcd
    ...das Programm...
    kein "config Lcd" oder so, da das die Libary macht.

    Hier noch der Inhalt der Libary:
    Code:
    ;----------------------------------------------------------
    ;Anschlussbelegung mein LCD
    ;----------------------------------------------------------
    ;DB4 = PC3 = PIN11
    ;DB5 = PC2 = PIN12
    ;DB6 = PC1 = PIN13
    :DB7 = PC0 = Pin14
    ;E   = PD6 = PIN6
    ;RS  = PD7 = PIN4
    ;R/W = GND = Pin5
    ;----------------------------------------------------------
    [_Init_LCD]
    ;----------------------------------------------------------
    ;
    ; RW               liegt auf GND da nur geschrieben wird
    ; D3, D2, D1, D0   liegen auf GND da nur 4 Bit-Datenlänge
    ; RS               Low für Befehlsübertragung, High für Datenübertragung
    ; E                Low-High-Low für Übertragungsaktivierung
    ;
    ;Anschlussbelegung LCD
    ; PD6 | PD7 | PC0 PC1 PC2 PC3 | PC0 PC1 PC2 PC3
    ; E   | RS  | D7  D6  D5  D4  | D3  D2  D1  D0
    ;     | 0   | 0   0   1   0   | 0   1   0   0   |  4 Bit-Datenlänge, extension Bit RE=1
    ;     | 0   | 0   0   0   0   | 1   0   0   1   |  4 Zeilen Modus
    ;     | 0   | 0   0   1   0   | 0   0   0   0   |  4 Bit-Datenlänge, extension Bit RE=0
    ;     | 0   | 0   0   0   0   | 0   1   1   0   |  Entry Mode Set Cursor Auto-Increment
    ;     | 0   | 0   0   0   0   | 0   0   0   1   |  LCD Inhalt löschen und Cursor auf Home
    ;     | 0   | 0   0   0   0   | 1   1   0   0   |  Display ein, Cursor aus, Blinken aus
    
    _Init_LCD:
    mov r1, r18                                     ;Registerinhalte sichern
    mov r3, r21
    mov r6, r22
    mov r7, r23
    mov r8, r24
    mov r9, r28
                       rcall LCD_Delay_5ms     ; 5ms LCD-Verarbeitungspause einplanen
                       rcall LCD_Delay_5ms     ; 5ms LCD-Verarbeitungspause einplanen
                       rcall LCD_Delay_5ms     ; 5ms LCD-Verarbeitungspause einplanen
                       rcall LCD_Delay_5ms     ; 5ms LCD-Verarbeitungspause einplanen
                       sbi   DDRC, 0           ; PC3 (D3/D7) als Ausgang konfigurieren
                       sbi   DDRC, 1           ; PC2 (D2/D6) als Ausgang konfigurieren
                       sbi   DDRC, 2           ; PC1 (D1/D5) als Ausgang konfigurieren
                       sbi   DDRC, 3           ; PC0 (D0/D4) als Ausgang konfigurieren
                       sbi   DDRD, 6           ; PD4 (E) als Ausgang konfigurieren
                       sbi   DDRD, 7           ; PD5 (RS) als Ausgang konfigurieren
                       ldi   r24, &B00100100   ; 4 Bit-Datenlänge, extension Bit
                       rcall _Lcd_control
                       ldi   r24, &B00001001   ; 4 Zeilen Modus
                       rcall _Lcd_control
                       ldi   r24, &B00100000   ; 4 Bit-Datenlänge, extension Bit RE=0
                       rcall _Lcd_control
                       ldi   r24, &B00000110   ; Entry Mode Set Cursor Auto-Increment
                       rcall _Lcd_control
                       ldi   r24, &B00001100   ; Display ein, Cursor aus, Blinken aus
                       rcall _Lcd_control
    mov r18, r1                                    ;alte Registerinhalte wieder zurück
    mov r21, r3
    mov r22, r6
    mov r23, r7
    mov r24, r8
    mov r28, r9
    [END]
    
    ;----------------------------------------------------------
    [_Write_lcd]
    ;----------------------------------------------------------
    _Write_lcd:
    mov r1, r18                               ;Registerinhalte sichern
    mov r3, r21
    mov r6, r22
    mov r7, r23
    mov r8, r24
    mov r9, r28
                       sbi   PortD, 7          ; RS High für Datenübertragung
                       rjmp  _Write_lcd_Byte   ; weiter zur Datenübertragung
    _Lcd_control:
                       cbi   PortD, 7          ; RS Low für Befehlsübertragung
    _Write_lcd_Byte:
                       ldi r18, 8                   ;Für Schleife 8 x
    loop:              mov r23, R24                 ;Zu übertragendes Byte wird in R24 bereitgestellt und in R23 für                                                       Bitmanipulation
                       andi  r28, &B00000001        ;nur LSB wird ausgewertet
                       ror r24                      ;R24 wird nach rechts verschoben
                       rol r22                      ;R22 wird nach links verschoben
                       or   r22,  r28               ;R22 und R28 in Register R25 vereinen
                       Dec r18                      ;-1
                       Brne loop                    ;springe zu Schleife wenn R18 > 0
                       mov   r24, r22		         ;R22 wird in R24 bereitgestellt
                       swap  r24			      ;Nibble tauschen die Daten stehen jetzt gespiegelt an PC0 - PC3!!
                       mov   r22, r24          ; Zu übertragendes Byte wird in R24 bereitgestellt und in R22 für die                                                       ;Übertragung des 2. Nibble gesichert
                                               ; H i g h  Nibble muss zuerst übertragen werden
                       swap  R24               ; Nibble tauschen
                       andi  R24, &B00001111   ; nur die unteren 4 Bit (unteres Nibble) berücksichtigen, obere 4 Bit                                                                 (oberes Nibble) auf Null setzen
                       in    R21, PinC         ; PortC in Register R21 einlesen (wegen PC7, PC6, PC5, PC4) diese sollen                                               ; ja nicht überschrieben werden
                       andi  R21, &B11110000   ; nur die oberen 4 Bit (PC7, PC6, PC5, PC4) berücksichtigen, untere 4 Bit                                                      ; (PC3, PC2, PC1, PC0) auf Null setzen
                       or    R24, R21          ; PortC (PC7, PC6, PC5, PC4) mit LCD (PC3, PC2, PC1, PC0) in Register R24                                               ; vereinen
                       out   PortC, R24        ; PortC aus Register R24 setzen
                       rcall LCD_Write_Enable  ; Übertragungsaktivierung
                                               ; L o w  Nibble muss noch übertragen werden
                       andi  R22, &B00001111   ; nur die unteren 4 Bit (unteres Nibble) berücksichtigen, obere 4 Bit                                                ; (oberes Nibble) auf Null setzen
                       or    R22, R21          ; PortC (PC7, PC6, PC5, PC4) mit LCD (PC3, PC2, PC1, PC0) in Register R22                                               ; vereinen
                       out   PortC, R22        ; PortC aus Register R22 setzen
                       rcall LCD_Write_Enable  ; Übertragungsaktivierung
                       rcall LCD_Delay_50us    ; 50us LCD-Verarbeitungspause einplanen
                       ret
    
    LCD_Write_Enable:
                       sbi   PortD, 6          ; E High Übertragungsaktivierung gestartet
                       nop                     ; 3 Taktzyklen warten
                       nop
                       nop
                       cbi   PortD, 6          ; E Low Übertragungsaktivierung beendet
                       ret                     ; Funktionsende
    
    LCD_Delay_5ms:
                       ldi   R24, 255          ; R24 Register mit Delaywert 100 * 50us vorbelegen
    LCD_Delay_5ms2:
                       rcall LCD_Delay_50us    ; 50us Pause
                       dec   R24               ; R24 Registerinhalt um 1 runterzählen
                       brne  LCD_Delay_5ms2    ; Springe bei ungleich zurück zu LCD_Delay_5ms2
                       ret                     ; Funktionsende
    
    LCD_Delay_50us:
                       ldi   R22, 165          ; R22 Register mit Delaywert vorbelegen
    LCD_Delay_50us2:
                       dec   R22               ; R22 Registerinhalt um 1 runterzählen
                       brne  LCD_Delay_50us2   ; Springe bei ungleich zurück zu LCD_Delay_50us2
                       ret                     ; 1 Takt (Befehlszyklus)                                          
    mov r18, r1                          ;alte Registerinhalte wieder zurück
    mov r21, r3
    mov r22, r6
    mov r23, r7
    mov r24, r8
    mov r28, r9
    [END]
    
    ;----------------------------------------------------------
    [_CLS]
    ;----------------------------------------------------------
    _Cls:
    mov r1, r18                                     ;Registerinhalte sichern
    mov r3, r21
    mov r6, r22
    mov r7, r23
    mov r8, r24
    mov r9, r2
                       ldi   R24, &B00000001   ; LCD Inhalt löschen und Cursor auf Home
                       rcall _Lcd_control      ; Befehl an LCD senden
                       rcall LCD_Delay_5ms     ; 5ms LCD-Verarbeitungspause einplanen
                       ret
    mov r18, r1                                 ;alte Registerinhalte wieder zurück
    mov r21, r3
    mov r22, r6
    mov r23, r7
    mov r24, r8
    mov r28, r9
    [END]
    Die Anschlußbelegung steht in der Libary mit drin.

    Gruss

    Ronny Schmiedel
    http://www.ronny-net.de

  5. #5
    ronny_s
    Gast
    SCHE...
    beim posten iss der Text voll durcheinander geraten.
    Die Erläuterung hinter dem ";" kann man ja löschen (auch auf der nächsten Zeile befindliche).
    Auf Wunsch kann ich die libary hier auch noch mal ohne Kommentar posten.

    Gruss

    Ronny

  6. #6
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    21.04.2005
    Ort
    Hannover
    Beiträge
    190
    Hi ronny_s!

    Vielen Dank für den Code!
    Leider sehe ich so meine Probleme damit da ich einen 8051 habe und früher schon einige Befehle wie DDRD und so nicht bearbeitet werden.
    Ich hab auch zu wenig Erfahrung um in Assembler etwas rumzupfuschen.
    Zudem weiss ich auch gar nicht wie man eine Library erstellt (wäre mein kleinstes Problem).

  7. #7
    Rudi Ratlos
    Gast

    Initialisierung KS0073 mit C-Controll

    Nachfolgend meine Initialisierung in Basic für C-Controll.
    Vor dem Versuch, das ganze in Bascom umzumodeln sollte man noch einmal testen, ob nicht in den Bibliotheken bereits die Lösungen stecken.
    Ich habe gelesen, dass es bei der Initalisierung den Parameter 20 * 4a gibt, das wäre wohl schon der Ansatz, die Zeilen richtig anzusprechen.
    Da ich gerade die C-Control einstampfe und mit Bascom starte, kenne ich mich hier noch nicht aus.

    ' KS0073_init.bas --------------------------------
    Code:
    DEFINE DB0 as Port[9]
    DEFINE DB1 as PORT[10]
    DEFINE DB2 as PORT[11]
    DEFINE DB3 as PORT[12]
    DEFINE RW  as PORT[13]
    DEFINE RS  as PORT[14]
    DEFINE EN  as PORT[15]
    
    define bit_RW     as bit[1] ' Zwischenspeicher für RW-Status
    define bit_RS     as bit[2] ' Zwischenspeicher für RS-Status
    define bit_Cursor as bit[3] ' gibt an, ob Cursor sichtbar     = on
    define bit_Blink  as bit[4] ' gibt an, ob Cursor blinken soll = on
    define bit_5      as bit[5]
    define bit_6      as bit[6]
    define bit_7      as bit[7]
    
    define Zeile   as byte  ' globale Variable, die von LCD_POS() ausgewertet wird
    define Spalte  as byte  ' globale Variable, die von LCD_POS() ausgewertet wird
    define DATA    as byte
    define i       as byte
    define j       as byte
    
    ' ---------------------------------------------
    FUNCTION LCD_POS(Zeile as byte, Spalte as byte)
    ' Positioniert den Cursor, dannach kann ins LCD geschrieben werden.
    ' benutzt die Globalen Variablen bit_RW und bit_RS
    bit_RW = RW  ' den Status der Ports sichern
    bit_RS = RS
    
    RW = off ' Auf Befehlsmodus umschalten
    RS = off ' Auf Schreibmodus umschalten
    
    ' nicht plausible Zeilenangaben abfangen
    ' IF (Zeile = 0 or Zeile > 4) THEN Zeile = 1
    ' nicht plausible Spaltenangaben abfangen
    ' IF (Spalte < 1 or Spalte > 20) THEN Spalte = 1
    
    ' Die Position ist nach Datenblatt KS0073:
    ' Zeile1 = 00h, Zeile 2 = 20h, Zeile 3 = 40h, Zeile 4 = 60h
    ' Die Variablen Zeile und Spalte werden missbraucht
    Zeile  = (Zeile -1) * 32 + (Spalte - 1) ' hier steht die LCD-Position
    
    ' siehe SET DDRAM Adress im Datenblatt (Seite 36)
    ' Daten schreiben, zuerst upper nibble, command bit 7 setzen
    
    Spalte = ((Zeile shr 4) or 1000b) ' Bit 4 setzen, Bit 3 - 0 sind Teil der Position
    ' nibble auf Ports übertragen
    BITSET(Spalte)
    PULSE EN ' und senden
    
    ' lower nibble
    ' überflüssig, wird in BITSET behandelt: Spalte = (Zeile and 15) ' 1111
    BITSET(Zeile)
    PULSE EN
    
    RS = bit_RS ' zurück in den ursprünglichen Zustand
    RW = bit_RW '
    
    END FUNCTION
    
    ' ---------------------------------------------
    ' setzt die Ports für die LCD-Ausgabe
    FUNCTION BITSET(Muster as byte)
    DB0 = MUSTER and 1
    DB1 = MUSTER and 2
    DB2 = Muster and 4
    DB3 = Muster and 8
    PAUSE 1
    end function
    
    ' ----------------------------------------------
    ' schaltet einen blinkenden Cursor ein
    FUNCTION DISPLAY_CURSOR()
    '
    bit_RS = RS ' Status sichern
    bit_RW = RW
    RS     = off
    RW     = off
    BITSET(0)  ' upper nibble
    PULSE EN
    
    ' CMD = 1/
    ' Display aus = 0, ein = 1
    ' Cursor aus  = 0, ein = 1
    ' Blink aus   = 0, ein = 1
    
    BITSET(ABS (bit_Cursor * 2 + bit_Blink - 12 ))
    PULSE EN
    RS = bit_RS  ' RS restaurieren
    RW = bit_RW  ' RW restaurieren
    
    end FUNCTION
    ' -------------------------------------------------
    
    ' ---------------------------------------------------
    FUNCTION KS0073_INIT()
    ' Initialisierung des LCDs 4x20 mit Controller KS0073
    
    LCD.INIT    ' Standardinitialisierung
    LCD.OFF     ' sollte eigentlich gar nicht erforderlich sein
    
    ' RW  = off ' immer off im Befehlsmodus
    ' RS  = off ' immer off im Befehlsmodus
    
    ' 3x den 8-Bit-Modus mit Pause dazwischen aufrufen ------------------
    BITSET(3) ' 0011
    PULSE EN
    
    pause 1
    Pulse EN
    
    pause 1
    PULSE EN
    
    ' CMD: 4-Bit-Modus aufrufen ----------------------
    BITSET(2) ' 00000010
    PULSE EN
    
    ' von nun an sind upper und lower nibble getrennt zu senden
    ' CMD: Function Set - upper nibble
    BITSET(2) ' 0010
    PULSE EN
    
    ' lower nibble
    ' 2 Zeilen-Modus, RE-bit
    BITSET(12) ' 1100
    PULSE EN
    
    ' CMD: extended Function Set + RE ---------------------
    ' upper nibble
    BITSET(0)
    PULSE EN
    
    ' lower nibble
    ' Cmd, 5-dot-Font, normaler Cursor, 4-line-display
    BITSET(9) '1001
    PULSE EN
    
    ' ----------------------------------------------
    ' CMD: Function Set - upper nibble
    BITSET(2) ' 0010
    PULSE EN
    
    ' lower nibble
    ' 2 Zeilen-Modus, RE-bit-aus
    BITSET(8) ' 1000
    PULSE EN
    
    ' CMD: clear display -----------------------------------------
    BITSET(0)
    PULSE EN
    
    BITSET(1)  ' 0001
    PULSE EN
    
    
    ' CMD: cursor display shift ------------------------------------------
    ' upper nibble
    BITSET(1)  ' 0001
    PULSE EN
    
    ' lower nibble
    ' Cursor shift, R/L shift
    BITSET(0)
    PULSE EN
    
    ' CDM: display on/off control ------------------------------------------
    ' upper nibble
    BITSET(0)
    PULSE EN
    
    ' Cmd, Display ein, Cursor off, Blink off
    BITSET(12) ' 1100
    PULSE EN
    
    END FUNCTION
    ' ---------------------------------------------------------------------
    
    
    KS0073_init()
    
    #start
    
    Pause 100
    
    LCD.INIT switchonly
    
    for i = 1 to 4
    for j = 1 to 20
    'pause 1
        LCD_POS(i, j)
        LCD.PRINT "*"
    next j
    next i
    LCD.CLEAR
    
    goto start
    ' PS. Der Smilie, den ich im Code gesehen habe, der gehört da nicht hin - vielleicht ist er aber auch schon wieder weg - wer weiss ..


    Edit: Bitte Code-Tags verwenden, dein Moddy

  8. #8
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    21.04.2005
    Ort
    Hannover
    Beiträge
    190
    Habe gerade im Internet gelesen dass man eine schon vorhandene Library für das lcd verändern kann, oder dieses bit, welches noch gesetzt werden muss seperat einfügen kann und dann einfach das ganze re-initialisiert.
    Ist das richtig??

  9. #9
    ronny_s
    Gast
    Das ist wohl richtig, nur die Libaries sind halt nunmal in Assembler geschrieben. Da Du Dich mit Assembler nicht so auskennst, wie willst Du dann in der Initialisierungsroutine das Extension-Bit richtig setzen.
    Die Reihenfolge (siehe meine Libary) der Initialisierung muß schon stimmen.
    Wünsche Dir aber trotzdem viel Erfolg und Assembler ist gar nicht so schwer, Tutorials gibt es genügend.

    Gruss Ronny

  10. #10
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    21.04.2005
    Ort
    Hannover
    Beiträge
    190
    Hi Ronny!
    Auch wenn ich nicht soo viel Ahnung von Assembler habe ist es doch hilfreich zu wissen wo diese Library ist weil ich mir dann erstens den Code für einen 8051 angucken kann und dann auch nicht deinen Code erst mühselig umarbeiten muss. Denn ich habe das ganze so verstanden, dass man im grunde nur ein paar wenige Zeilen schreiben muss um dieses Bit zu setzen, richtig?
    Wenn mir bei der Library jemand weiterhelfen könnte wäre mir echt schon geholfen!
    Vielen Dank an Alle die mir bisher geholfen haben!
    Marten83

Seite 1 von 2 12 LetzteLetzte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

LiFePO4 Speicher Test