- Labornetzteil AliExpress    Werbung      
Ergebnis 1 bis 10 von 18

Thema: Problem mit LCD-DIsplay

Hybrid-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #1
    Neuer Benutzer Öfters hier Avatar von cantforget
    Registriert seit
    24.03.2011
    Ort
    Dortmund
    Beiträge
    8
    Hallo,
    danke für deine schnelle Antwort wkrug. Habe das mal mit deiner Lib ausprobiert, allerdings funktioniert mein LCD immer noch nicht. Aber ich denke mal es liegt daran, dass ich das mit der Adressierung einfach nicht hinbekomme.
    Ich habe es jetzt einmal mit nem anderen Board und LCD ausprobiert (Board und LCD von myAVR), das ganze mit der GCC-LCD-Tutorial Lib in C programmiert und siehe da es funktioniert.

    Hier die lcd-routines.h:
    Code:
    // Ansteuerung eines HD44780 kompatiblen LCD im 4-Bit-Interfacemodus
    // http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial/LCD-Ansteuerung
    //
     
    #ifndef LCD_ROUTINES_H
    #define LCD_ROUTINES_H
     
    ////////////////////////////////////////////////////////////////////////////////
    // Hier die verwendete Taktfrequenz in Hz eintragen, wichtig!
     
    #ifndef F_CPU
    #define F_CPU 3686400
    #endif
     
    ////////////////////////////////////////////////////////////////////////////////
    // Pinbelegung für das LCD, an verwendete Pins anpassen
    // Alle LCD Pins müssen an einem Port angeschlossen sein und die 4
    // Datenleitungen müssen auf aufeinanderfolgenden Pins liegen
     
    //  LCD DB4-DB7 <-->  PORTD Bit PD0-PD3
    #define LCD_PORT      PORTD
    #define LCD_DDR       DDRD
    #define LCD_DB        PD4
     
    //  LCD RS      <-->  PORTD Bit PD4     (RS: 0=Data, 1=Command)
    #define LCD_RS        PD2
     
    //  LCD EN      <-->  PORTD Bit PD5     (EN: 1-Impuls für Daten)
    #define LCD_EN        PD3
     
    ////////////////////////////////////////////////////////////////////////////////
    // LCD Ausführungszeiten (MS=Millisekunden, US=Mikrosekunden)
     
    #define LCD_BOOTUP_MS           15
    #define LCD_ENABLE_US           1
    #define LCD_WRITEDATA_US        46
    #define LCD_COMMAND_US          42
     
    #define LCD_SOFT_RESET_MS1      5
    #define LCD_SOFT_RESET_MS2      1
    #define LCD_SOFT_RESET_MS3      1
    #define LCD_SET_4BITMODE_MS     5
     
    #define LCD_CLEAR_DISPLAY_MS    2
    #define LCD_CURSOR_HOME_MS      2
     
    ////////////////////////////////////////////////////////////////////////////////
    // Zeilendefinitionen des verwendeten LCD
    // Die Einträge hier sollten für ein LCD mit einer Zeilenlänge von 16 Zeichen passen
    // Bei anderen Zeilenlängen müssen diese Einträge angepasst werden
     
    #define LCD_DDADR_LINE1         0x00
    #define LCD_DDADR_LINE2         0x40
    #define LCD_DDADR_LINE3         0x10
    #define LCD_DDADR_LINE4         0x50
     
    ////////////////////////////////////////////////////////////////////////////////
    // Initialisierung: muss ganz am Anfang des Programms aufgerufen werden.
    void lcd_init( void );
     
    ////////////////////////////////////////////////////////////////////////////////
    // LCD löschen
    void lcd_clear( void );
     
    ////////////////////////////////////////////////////////////////////////////////
    // Cursor in die 1. Zeile, 0-te Spalte
    void lcd_home( void );
     
    ////////////////////////////////////////////////////////////////////////////////
    // Cursor an eine beliebige Position 
    void lcd_setcursor( uint8_t spalte, uint8_t zeile );
     
    ////////////////////////////////////////////////////////////////////////////////
    // Ausgabe eines einzelnen Zeichens an der aktuellen Cursorposition 
    void lcd_data( uint8_t data );
     
    ////////////////////////////////////////////////////////////////////////////////
    // Ausgabe eines Strings an der aktuellen Cursorposition 
    void lcd_string( const char *data );
     
    ////////////////////////////////////////////////////////////////////////////////
    // Definition eines benutzerdefinierten Sonderzeichens.
    // data muss auf ein Array[5] mit den Spaltencodes des zu definierenden Zeichens
    // zeigen
    void lcd_generatechar( uint8_t code, const uint8_t *data );
     
    ////////////////////////////////////////////////////////////////////////////////
    // Ausgabe eines Kommandos an das LCD.
    void lcd_command( uint8_t data );
     
     
    ////////////////////////////////////////////////////////////////////////////////
    // LCD Befehle und Argumente.
    // Zur Verwendung in lcd_command
     
    // Clear Display -------------- 0b00000001
    #define LCD_CLEAR_DISPLAY       0x01
     
    // Cursor Home ---------------- 0b0000001x
    #define LCD_CURSOR_HOME         0x02
     
    // Set Entry Mode ------------- 0b000001xx
    #define LCD_SET_ENTRY           0x04
     
    #define LCD_ENTRY_DECREASE      0x00
    #define LCD_ENTRY_INCREASE      0x02
    #define LCD_ENTRY_NOSHIFT       0x00
    #define LCD_ENTRY_SHIFT         0x01
     
    // Set Display ---------------- 0b00001xxx
    #define LCD_SET_DISPLAY         0x08
     
    #define LCD_DISPLAY_OFF         0x00
    #define LCD_DISPLAY_ON          0x04
    #define LCD_CURSOR_OFF          0x00
    #define LCD_CURSOR_ON           0x02
    #define LCD_BLINKING_OFF        0x00
    #define LCD_BLINKING_ON         0x01
     
    // Set Shift ------------------ 0b0001xxxx
    #define LCD_SET_SHIFT           0x10
     
    #define LCD_CURSOR_MOVE         0x00
    #define LCD_DISPLAY_SHIFT       0x08
    #define LCD_SHIFT_LEFT          0x00
    #define LCD_SHIFT_RIGHT         0x04
     
    // Set Function --------------- 0b001xxxxx
    #define LCD_SET_FUNCTION        0x20
     
    #define LCD_FUNCTION_4BIT       0x00
    #define LCD_FUNCTION_8BIT       0x10
    #define LCD_FUNCTION_1LINE      0x00
    #define LCD_FUNCTION_2LINE      0x08
    #define LCD_FUNCTION_5X7        0x00
    #define LCD_FUNCTION_5X10       0x04
     
    #define LCD_SOFT_RESET          0x30
     
    // Set CG RAM Address --------- 0b01xxxxxx  (Character Generator RAM)
    #define LCD_SET_CGADR           0x40
     
    #define LCD_GC_CHAR0            0
    #define LCD_GC_CHAR1            1
    #define LCD_GC_CHAR2            2
    #define LCD_GC_CHAR3            3
    #define LCD_GC_CHAR4            4
    #define LCD_GC_CHAR5            5
    #define LCD_GC_CHAR6            6
    #define LCD_GC_CHAR7            7
     
    // Set DD RAM Address --------- 0b1xxxxxxx  (Display Data RAM)
    #define LCD_SET_DDADR           0x80
     
    #endif
    Hier die lcd-routines.c:
    Code:
    // Ansteuerung eines HD44780 kompatiblen LCD im 4-Bit-Interfacemodus
    // http://www.mikrocontroller.net/articles/HD44780
    // http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial/LCD-Ansteuerung
    //
    // Die Pinbelegung ist über defines in lcd-routines.h einstellbar
     
    #include <avr/io.h>
    #include "lcd-routines.h"
    #include <util/delay.h>
     
    ////////////////////////////////////////////////////////////////////////////////
    // Erzeugt einen Enable-Puls
    static void lcd_enable( void )
    {
        LCD_PORT |= (1<<LCD_EN);     // Enable auf 1 setzen
        _delay_us( LCD_ENABLE_US );  // kurze Pause
        LCD_PORT &= ~(1<<LCD_EN);    // Enable auf 0 setzen
    }
     
    ////////////////////////////////////////////////////////////////////////////////
    // Sendet eine 4-bit Ausgabeoperation an das LCD
    static void lcd_out( uint8_t data )
    {
        data &= 0xF0;                       // obere 4 Bit maskieren
     
        LCD_PORT &= ~(0xF0>>(4-LCD_DB));    // Maske löschen
        LCD_PORT |= (data>>(4-LCD_DB));     // Bits setzen
        lcd_enable();
    }
     
    ////////////////////////////////////////////////////////////////////////////////
    // Initialisierung: muss ganz am Anfang des Programms aufgerufen werden.
    void lcd_init( void )
    {
        // verwendete Pins auf Ausgang schalten
        uint8_t pins = (0x0F << LCD_DB) |           // 4 Datenleitungen
                       (1<<LCD_RS) |                // R/S Leitung
                       (1<<LCD_EN);                 // Enable Leitung
        LCD_DDR |= pins;
     
        // initial alle Ausgänge auf Null
        LCD_PORT &= ~pins;
     
        // warten auf die Bereitschaft des LCD
        _delay_ms( LCD_BOOTUP_MS );
        
        // Soft-Reset muss 3mal hintereinander gesendet werden zur Initialisierung
        lcd_out( LCD_SOFT_RESET );
        _delay_ms( LCD_SOFT_RESET_MS1 );
     
        lcd_enable();
        _delay_ms( LCD_SOFT_RESET_MS2 );
     
        lcd_enable();
        _delay_ms( LCD_SOFT_RESET_MS3 );
     
        // 4-bit Modus aktivieren 
        lcd_out( LCD_SET_FUNCTION |
                 LCD_FUNCTION_4BIT );
        _delay_ms( LCD_SET_4BITMODE_MS );
     
        // 4-bit Modus / 2 Zeilen / 5x7
        lcd_command( LCD_SET_FUNCTION |
                     LCD_FUNCTION_4BIT |
                     LCD_FUNCTION_2LINE |
                     LCD_FUNCTION_5X7 );
     
        // Display ein / Cursor aus / Blinken aus
        lcd_command( LCD_SET_DISPLAY |
                     LCD_DISPLAY_ON |
                     LCD_CURSOR_OFF |
                     LCD_BLINKING_OFF); 
     
        // Cursor inkrement / kein Scrollen
        lcd_command( LCD_SET_ENTRY |
                     LCD_ENTRY_INCREASE |
                     LCD_ENTRY_NOSHIFT );
     
        lcd_clear();
    }
      
    ////////////////////////////////////////////////////////////////////////////////
    // Sendet ein Datenbyte an das LCD
    void lcd_data( uint8_t data )
    {
        LCD_PORT |= (1<<LCD_RS);    // RS auf 1 setzen
     
        lcd_out( data );            // zuerst die oberen, 
        lcd_out( data<<4 );         // dann die unteren 4 Bit senden
     
        _delay_us( LCD_WRITEDATA_US );
    }
     
    ////////////////////////////////////////////////////////////////////////////////
    // Sendet einen Befehl an das LCD
    void lcd_command( uint8_t data )
    {
        LCD_PORT &= ~(1<<LCD_RS);    // RS auf 0 setzen
     
        lcd_out( data );             // zuerst die oberen, 
        lcd_out( data<<4 );           // dann die unteren 4 Bit senden
     
        _delay_us( LCD_COMMAND_US );
    }
     
    ////////////////////////////////////////////////////////////////////////////////
    // Sendet den Befehl zur Löschung des Displays
    void lcd_clear( void )
    {
        lcd_command( LCD_CLEAR_DISPLAY );
        _delay_ms( LCD_CLEAR_DISPLAY_MS );
    }
     
    ////////////////////////////////////////////////////////////////////////////////
    // Sendet den Befehl: Cursor Home
    void lcd_home( void )
    {
        lcd_command( LCD_CURSOR_HOME );
        _delay_ms( LCD_CURSOR_HOME_MS );
    }
     
    ////////////////////////////////////////////////////////////////////////////////
    // Setzt den Cursor in Spalte x (0..15) Zeile y (1..4) 
     
    void lcd_setcursor( uint8_t x, uint8_t y )
    {
        uint8_t data;
     
        switch (y)
        {
            case 1:    // 1. Zeile
                data = LCD_SET_DDADR + LCD_DDADR_LINE1 + x;
                break;
     
            case 2:    // 2. Zeile
                data = LCD_SET_DDADR + LCD_DDADR_LINE2 + x;
                break;
     
            case 3:    // 3. Zeile
                data = LCD_SET_DDADR + LCD_DDADR_LINE3 + x;
                break;
     
            case 4:    // 4. Zeile
                data = LCD_SET_DDADR + LCD_DDADR_LINE4 + x;
                break;
     
            default:
                return;                                   // für den Fall einer falschen Zeile
        }
     
        lcd_command( data );
    }
     
    ////////////////////////////////////////////////////////////////////////////////
    // Schreibt einen String auf das LCD
     
    void lcd_string( const char *data )
    {
        while( *data != '\0' )
            lcd_data( *data++ );
    }
     
    ////////////////////////////////////////////////////////////////////////////////
    // Schreibt ein Zeichen in den Character Generator RAM
     
    void lcd_generatechar( uint8_t code, const uint8_t *data )
    {
        // Startposition des Zeichens einstellen
        lcd_command( LCD_SET_CGADR | (code<<3) );
     
        // Bitmuster übertragen
        for ( uint8_t i=0; i<8; i++ )
        {
            lcd_data( data[i] );
        }
    }
    Und hier das Programm:
    Code:
    /*
     * LCD_Test.c
     *
     * Created: 14.07.2011 08:08:53
     *  Author: Dennis
     */ 
    
    #include <avr/io.h>
    #include <avr/delay.h>
    #include "lcd-routines.h"
     
    int main(void)
    {
      // Initialisierung des LCD
      // Nach der Initialisierung müssen auf dem LCD vorhandene schwarze Balken
      // verschwunden sein
      lcd_init();
        // Text in einzelnen Zeichen ausgeben
      lcd_data( 'T' );
      lcd_data( 'e' );
      lcd_data( 's' );
      lcd_data( 't' );
     
      // Die Ausgabemarke in die 2te Zeile setzen
      lcd_setcursor( 0, 2 );
     
      // erneut Text ausgeben, aber diesmal komfortabler als String
      lcd_string("Hello World!");
      
      while(1)
      {
    
      }
     
      return 0;
    }
    Allerdings hat der Code (mit dem AVR-Studio 5 compiliert) eine Größe von 7036 Byte. Das kann doch nicht sein oder? Da is mein kleiner Mega8 ja schon voll. Kann es sein das er beim brennen der .hex Datei die .h und die .c der Lib auch auf den AVR schreibt?
    Nun werde ich das ganze noch einmal mit dem RN-Mega8-plus Board und dem myavr-LCD ausprobieren, vielleicht ist ja doch nur ein Port kaputt.

    Gruß
    Dennis

  2. #2
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    63
    Beiträge
    5.799
    Allerdings hat der Code (mit dem AVR-Studio 5 compiliert) eine Größe von 7036 Byte.
    Dann machst du irgendetwas falsch:
    Bild  

    Kompiliert mit WinAVR-20100110.
    delay.h befindet sich jetzt in util/
    Angehängte Dateien Angehängte Dateien
    Bild  
    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

  3. #3
    Neuer Benutzer Öfters hier Avatar von cantforget
    Registriert seit
    24.03.2011
    Ort
    Dortmund
    Beiträge
    8
    Hallo,
    aha danke dir Radbruch, ich habe den Fehler gefunden.
    Im AVR-Studio 5 kann man im "Solution Explorer" bei "Solution 'Dateiname'" rechts klicken, danach wählt man den "Configuration Manager" an und stellt bei "Configuration" satt "Debug" "Release" ein. Danach hat mein Programm nun 486 Bytes. Wo allerdings der Unterschied zu deiner Größe kommt, kann ich mir nicht erklären.

    Kompiliert mit WinAVR-20100110.
    delay.h befindet sich jetzt in util/
    Bei mir ging es erst nicht im util/, aber nun geht es seltsamer weise.

    Sag mal Radbruch hast du eine Idee wie ich mein oben beschriebenes LCD mit der Lib die ich gepostet habe zum laufen bekomme?

    Gruß
    Dennis

  4. #4
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    63
    Beiträge
    5.799
    $crystal = 7372800
    ...
    #ifndef F_CPU
    #define F_CPU 3686400
    #endif

    ? Bei falscher Taktfrequenz stimmt das Timeing durch delay.h nicht mehr. Ich muss mich erst mal einlesen (und die Datenblätter suchen) ...

    P.S.: Schwäbisch sparsam kompiliert ;)
    Bild  
    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

  5. #5
    Erfahrener Benutzer Robotik Visionär Avatar von Hubert.G
    Registriert seit
    14.10.2006
    Ort
    Pasching OÖ
    Beiträge
    6.220
    Ich arbeite immer mit der Lib von P.Fleury, in der kann man den KS0073 einstellen. Es gibt da in der Init einen unterschied.
    Angehängte Dateien Angehängte Dateien
    Grüsse Hubert
    ____________

    Meine Projekte findet ihr auf schorsch.at

  6. #6
    Neuer Benutzer Öfters hier Avatar von cantforget
    Registriert seit
    24.03.2011
    Ort
    Dortmund
    Beiträge
    8
    Hallo,
    also Radbruch ist nett von dir wenn du das für mich machst. Also der code sollte im Projekt schon in C geschrieben werden, also ich meinte das im Obersten Post beschriebene LCD und die Lib's aus Post nummer 7. Bei der Taktfrequenz sehe ich auch gerade da habe ich wohl was vertauscht, weil ich 2 Boards hier liegen habe. Die richtige ist 7372800 Hz.
    Das Problem war halt, das ich das 20*4 LCD nicht mit dem RN-MEGA8-plus Board betreiben kann. Die Ports habe ich die von der Display-Buchse genommen.
    Und Hubert.G hast du auch schon mit meinem LCD gearbeitet? Denn ich hatte es zuerst mit der Fleury lib probiert, allerdings kam ich damit auch nicht zu einer funktionierenden Lösung. >Ich sehe gerade, dass es ein paar änderungen in der lib gab, werde mir das später aber nocheinmal genauer ansehen.

    Gruß
    Dennis
    Geändert von cantforget (15.07.2011 um 12:56 Uhr)

  7. #7
    Erfahrener Benutzer Robotik Visionär Avatar von Hubert.G
    Registriert seit
    14.10.2006
    Ort
    Pasching OÖ
    Beiträge
    6.220
    Mit deinem speziellen LCD habe ich noch nicht gearbeitet. Allerdings mit LCDs mit einem KS0073, diese haben nur mit der Einstellung für diesen Kontrollertyp funktioniert.
    Grüsse Hubert
    ____________

    Meine Projekte findet ihr auf schorsch.at

  8. #8
    Neuer Benutzer Öfters hier Avatar von cantforget
    Registriert seit
    24.03.2011
    Ort
    Dortmund
    Beiträge
    8
    Hallo,
    @Hubert.G:
    So habe die lib nun mal umgeschrieben bin mir aber mit der Adressierung unsicher könntest du mal schauen ob die richtig ist?
    Code:
    #define LCD_LINES           4     /**< number of visible lines of the display */
    #define LCD_DISP_LENGTH    20     /**< visibles characters per line of the display */
    #define LCD_LINE_LENGTH  0x20     /**< internal line length of the display    */
    #define LCD_START_LINE1  0x00     /**< DDRAM address of first char of line 1 */
    #define LCD_START_LINE2  0x40     /**< DDRAM address of first char of line 2 */
    #define LCD_START_LINE3  0x10     /**< DDRAM address of first char of line 3 */
    #define LCD_START_LINE4  0x60     /**< DDRAM address of first char of line 4 */
    #define LCD_WRAP_LINES      0     /**< 0: no wrap, 1: wrap at end of visibile line */
    Das ist dieses LCD:
    http://www.robotikhardware.de/downlo...datenblatt.pdf
    Ich hoffe mal ich bekomme das irgendwie nochmal hin. Finde das schon nicht so einfach ein LCD einzubinden.

    Gruß
    Dennis

Ähnliche Themen

  1. Problem mit LCD-Display
    Von Sebasti im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 42
    Letzter Beitrag: 03.04.2011, 11:45
  2. Problem mit LCD-Display
    Von Sebasti im Forum Elektronik
    Antworten: 2
    Letzter Beitrag: 09.03.2011, 18:39
  3. LCD-Display Problem
    Von Soeni im Forum Allgemeines zum Thema Roboter / Modellbau
    Antworten: 8
    Letzter Beitrag: 02.11.2009, 13:46
  4. Problem mit LCD Display
    Von Tredory im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 3
    Letzter Beitrag: 25.02.2009, 17:23
  5. [ERLEDIGT] Display Problem
    Von Gast im Forum Controller- und Roboterboards von Conrad.de
    Antworten: 9
    Letzter Beitrag: 09.04.2004, 21:03

Berechtigungen

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

    Werbung      12V Akku bauen