LCD Programmierung Nibble verschwinden



  • @DirkB Hätte ich vielleicht schreiben sollen. Ich habe die Temperatur schon in Zeile 1 Spalte 0, zeile 1 Spalte 8, Zeile 2 Spalte 0 und Zeile 2 Spalte 8 ausgegeben. Egal in welcher Konstellation ich die Texte ausgebe, auch wenn ich zuerst etwas in Zeile 1 und dann in Zeile 2 ausgebe. Der erste ausgegebene Text ist an der richtigen Position. Der 2. 3. und 4. ausgegebene Text ist immer in der richtigen zeile aber in Spalte 11 der jeweiligen Spalte.



  • Laut Datenblatt mußt du immer jeweils die drei Bits RE, RS und RW passend setzen (sowie dann die entsprechenden Data-Bits).
    Für "Cursor / Display Shift" also

    LCD_RE_LOW;
    LCD_RS_LOW;
    LCD_RW_LOW;
    

    Außerdem scheint das nur eine relative Positionierung zu sein (keine absolute). Dafür müßtest du dann selber die aktuelle Position dir merken und die Differenz (x / y) ausrechnen.



  • @Th69 so wie ich das verstanden habe werden Befehle immer dann vom Display eingelesen, wenn der Enable Pin von 1 auf 0 wechselt, also bei fallender Flanke. Wenn ich aber den Enable Pin auf 0 setze, bevor ich den Befehl an die Datenleitungen anlege, werden die Daten in dem Fall dann bei steigender Flanke übertragen?



  • @DirkB
    Hier ist nochmal meine überarbeitete init ohne "Magic Numbers" 😉

    void init_lcd()                                          
    {
        delay_display=LCD_BOOTUP/FAKTOR_US;                                             //Warten, bis Display bereit ist  
        while (delay_display);
        LCD_RS_LOW;                                                                     //RS Pin auf "low" -> Befehl
        delay_display=LCD_SET_PIN/FAKTOR_US;
        while (delay_display);
        LCD_RW_LOW;                                                                     //RW Pin auf "low" -> write
        delay_display=LCD_SET_PIN/FAKTOR_US;
        while (delay_display);
        LCD_EN_HIGH;                                                                    //Enable Pin auf "high"
        delay_display=LCD_SET_PIN/FAKTOR_US;
        while (delay_display);
        LCD_OUT(Function_Set_8Bit);                                                     //0x03 8Bit-Modus
        LCD_EN_PULSE();    
        delay_display=LCD_8BIT/FAKTOR_US;
        while (delay_display);
        LCD_OUT(Function_Set_8Bit);                                                     //0x03 8Bit-Modus
        LCD_EN_PULSE();    
        delay_display=LCD_8BIT/FAKTOR_US;
        while (delay_display);
        LCD_OUT(Function_Set_8Bit);                                                     //0x03 8Bit-Modus
        LCD_EN_PULSE();    
        delay_display=LCD_8BIT/FAKTOR_US;
        while (delay_display);
        LCD_OUT(Function_Set_4Bit);                                                     //0x02 4Bit-Modus
        LCD_EN_PULSE();    
        delay_display=LCD_4BIT/FAKTOR_US;
        while (delay_display);
        LCD_COMMAND_OUT(Function_Set_Reg1);                                             //0x24 Function Set extension register = 1
        delay_display=50/FAKTOR_US;
        while (delay_display);
        LCD_COMMAND_OUT(Extend_Function_Set);                                           //0x09 extend Function set 5dot font width, normal cursor,4-line display
        delay_display=50/FAKTOR_US;
        while (delay_display);
        LCD_COMMAND_OUT(Function_Set_Reg0);                                             //0x20 Function Set extension register = 0
        delay_display=50/FAKTOR_US;
        while (delay_display);
        LCD_COMMAND_OUT(CURSOR_AT_HOME);                                                //0x02 Cursor At Home
        delay_display=2000/FAKTOR_US;
        while (delay_display);
        LCD_COMMAND_OUT(LCD_ALL_ON);                                                    //0x0F Display On/Off Control display on, cursor on, cursor blink on
        delay_display=50/FAKTOR_US;
        while (delay_display);
        LCD_COMMAND_OUT(LCD_CLEAR);                                                     //0x01 Display löschen und Cursor auf Home
        delay_display=2000/FAKTOR_US;
        while (delay_display);
        LCD_COMMAND_OUT(LCD_ENTRY_MODE_SET);                                            //0x06 Entry Mode Set Cursor Moving Direction increment, shift enable bit=disable
        delay_display=50/FAKTOR_US;
        while (delay_display);
        LCD_COMMAND_OUT(Function_Set_End);                                              //Function Set: 4bit, 2-line, RE=0,dot scroll,reverse bit normal
        delay_display=50/FAKTOR_US;
        while (delay_display);  
        
    }
    


  • @Th69 das RE Bit ist ja nur für das extension Register oder? Das sit bei mir nach der init immer auf 0.



  • Ich hätte noch eine andere Frage:
    Die Befehle, welche ich übertrage werden ja in den CG RAM geschrieben oder? Also wenn ich ein Byte senden will, dann wird das zuerst übertragene Nibble in den CG RAM geschrieben bis das zweite Nibble übertragen wird.
    Gibt es eine möglichkeit, dieses zu löschen?



  • @IchBins Nein.
    CG steht für Charakter Generator. Da stehen die Muster für die Zeichen drin.
    Im ROM halt fest codiert und im RAM kannst du noch 8 Zeichen selber definieren.

    Der Anzeigetext steht im DDRAM (DisplayData)

    Hier noch das Datenblatt für den Controller: https://cdn-reichelt.de/documents/datenblatt/A500/DS_SSD1803.pdf



  • @DirkB Oh, das habe ich verwechselt. Ist es dann möglich, den DDRAM zu leeren?



  • @IchBins sagte in LCD Programmierung Nibble verschwinden:

    @DirkB Oh, das habe ich verwechselt. Ist es dann möglich, den DDRAM zu leeren?

    Ja, dann ist die Anzeige leer.

    Du möchtest aber irgendwie das Interface reseten, oder?



  • @DirkB Ich habe das Gefühl, dass in dem DDRAM am Ende meiner Textausgabe noch 1 Nibble steckt, welches dann als oberes Nibble für den Nächsten Befehl benutzt wird. Das würde ich gerne heraus löschen, ohne aber das gesamte Display zu löschen.



  • @IchBins sagte in LCD Programmierung Nibble verschwinden:

    @DirkB Ich habe das Gefühl, dass in dem DDRAM am Ende meiner Textausgabe noch 1 Nibble steckt, welches dann als oberes Nibble für den Nächsten Befehl benutzt wird. Das würde ich gerne heraus löschen, ohne aber das gesamte Display zu löschen.

    Dann dürften deine Buchstaben auch nicht richtig ankommen.

    Du solltest dir das Datenblatt vom Controller nochmal ansehen und dann das Timing anpassen.

    RS = 0, RW = 0, E = 1, D7 bis D4 anlegen, E = 0, (warten 0,25 µs), E = 1, D3 bis D0 anlegen, E = 0.
    Die Wartezeiten sind unter 1 µs
    und dann das BUSY-Flag auswerten. Ohne Timer.



  • @DirkB Tut mir Leid, dass ich mich so spät zurück melde. Die Wartezeiten müssten alle stimmen. Ich werde mich jetzt aber mal an das BUSY-Flag heranwagen. Danke für die Antwort.



  • @IchBins Es gibt Wartezeiten auf dem Bus (wie lange muss ein Signal anliegen, bis ein anderes sich ändern darf) und Wartezeiten für die Aktion vom Display (dafür ist das Busy-Flag da)



  • Okay Alles klar. Bin gerade noch dabei heraus zu finden, wie das mit dem busy Flag funktioniert.



  • Habe ich das richtig verstanden? Um das Busy Flag auszulesen müssen folgende Schritte gemacht werden:

    1. Dateinleitung 7 auf Output stellen
    2. R/W auf Read (auf 1)
    3. Enable von 1 auf 0 und wieder auf 1
    4. Das Display setzt das Busy-Flag, wenn es noch nicht fertig ist auf 1, sobald es bereit für das nächste Kommando ist auf 0
      5.R/W auf Write (auf 0)
    5. Dateinleitung 7 auf Input.

    Schritt 5 und 6 sind optional. Wenn diese nicht in der Busy Flag Funktion ausgeführt werden, dann müssen sie vor dem nächsten Befehl ausgeführt werden.



  • Nachtrag: In Schritt 1 muss auf Input und in Schritt 5 auf Output gestellt werden.



  • @IchBins Wenn ich das Timingdiagramm richtig lese, musst du schon alle 8 Bit (also 2x4) lesen.
    Die anderen 7 Bit geben den Adress Counter.


Log in to reply