- fchao-Sinus-Wechselrichter AliExpress         
Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 18

Thema: Problem mit LCD-DIsplay

  1. #1
    Neuer Benutzer Öfters hier Avatar von cantforget
    Registriert seit
    24.03.2011
    Ort
    Dortmund
    Beiträge
    8

    Problem mit LCD-DIsplay

    Anzeige

    Powerstation Test
    Hallo,
    ich habe ein Problem mit meinem Board (RN-MEGA8PLUS V1.5). Dazu habe ich noch den RN-LCD Adapter (BSLCDADAPT) und dieses LCD Display (EADIP204) auch aus dem RN Shop.
    Nun habe ich alles angeschlossen (Display Adapter am Display Port), danach habe ich den aufgeführten Code aufgespielt. Jedoch funktioniert das Display Überhaubt nicht. Es blinkt mitsamt der Status Balkenanzeige.

    Code:
    $regfile = "m8def.dat"
    
    '$crystal = 16000000                      'Quarzfrequenz
    $crystal = 7372800                                          'Alternative Quarzfrequenz
    
    ' Falls ein LCD Display angeschlossen ist
    Config Portd = Output
    Config Portc = Output
    Config Lcd = 20 * 4
    Config Lcdpin = Pin , Db4 = Portd.2 , Db5 = Portd.3 , Db6 = Portd.4 , Db7 = Portd.5 , E2 = Portd.7 , Rs = Portc.2
    Config Lcdbus = 4
    Cls
    'Initlcd
    
    
    Do
    Locate 1 , 1
    Lcd "Hallo Welt"
    'Waitms 500
    Loop
    Gruß
    Dennis

  2. #2
    Erfahrener Benutzer Roboter-Spezialist Avatar von Thegon
    Registriert seit
    21.01.2011
    Beiträge
    562
    Hallo Dennis,
    ich habe auch einmal mit diesen Displays herumgefuchst und mir gings beim ersten Versuch genauso.
    Dann hab ich ein bisschen herumprobiert und auf einmal hat es funktioniert. Ich habe damals die Zeile
    config Lcdbus = 4
    weggelassen. Dann hat es funktioniert. Ich habe nicht die geringste Ahnung warum, aber es hat dann auf anhieb funktioniert. Villeicht weiß ja jemand hier im Forum warum.
    Das könntest du auch einmal ausprobieren, villeicht funktionier es dann ja.
    Warum schreibst du eigentlich E2? reicht da nicht schon E für Enable?
    Und du könntest alles mit anderen Output-pins versuchen, bei mir war nämlich einmal einer kaputt und dann hat auch alles nicht funktioniert.
    Bin schon gespannt, ob das mit dem lcdbus = 4 weglassen auch bei jemandem anderen funktioniert.
    Mfg Thegon

  3. #3
    Neuer Benutzer Öfters hier Avatar von cantforget
    Registriert seit
    24.03.2011
    Ort
    Dortmund
    Beiträge
    8
    Hallo Thegon,
    Danke für deine Antwort. Ich werde deinen Vorschlag morgen direkt mal ausprobieren. Das E2 habe ich aus einem Beispielprogramm. Ich denke das LCD ist ein 2-Chip Display. Daher das 2. Enable. Werde dann morgen über den "hoffentlich" Erfolg berichten.

    Schönen Abend noch
    Dennis

  4. #4
    Erfahrener Benutzer Robotik Einstein Avatar von wkrug
    Registriert seit
    17.08.2006
    Ort
    Dietfurt
    Beiträge
    2.214
    Ich denk mal, das es nicht funktionieren wird.
    Das EA204DIP nutzt zwar ein ähnliches Protokoll wie die üblichen HD44780 Displays.
    Im Prinzip geht es da beim 4 Zeiligen Display um ein Kommando und andere Adressen für die einzelnen Stellen.

    In C sieht das so aus:
    Code:
    _lcd_maxx=lcd_columns;
    _base_y[0]=0x00;
    _base_y[1]=lcd_columns + 0x0C;
    _base_y[2]=lcd_columns + 0x2C;
    _base_y[3]=lcd_columns + 0x4C;
    
    _long_delay();
    _long_delay();
    _lcd_init_write(0x20);  // 4 Bit Modus + RE Bit clear
    _long_delay();
    
    _lcd_init_write(0x24);  // 4 Bit Modus + RE Bit set
    _long_delay();
    
    _lcd_init_write(0x09); 
    _long_delay();
    
    _lcd_init_write(0x20);  // 4 Bit Modus + RE Bit clear
    _long_delay();
    
    _lcd_init_write(0x0C);  // Display On
    _long_delay();
    
    _lcd_init_write(0x01);  // Clear Display
    _long_delay();
    
    _lcd_init_write(0x06);  //Auto Increment on
    _long_delay();
    Beim HD44780 so:

    Code:
    _lcd_maxx=lcd_columns;
    _base_y[2]=lcd_columns+0x80;
    _base_y[3]=lcd_columns+0xc0;
    _long_delay();
    _lcd_init_write(0x30);
    _long_delay();
    _lcd_init_write(0x30);
    _long_delay();
    _lcd_init_write(0x30);
    _long_delay();
    _lcd_init_write(0x20);
    _long_delay();
    _lcd_write_data(0x28);
    _long_delay();
    _lcd_write_data(4);
    _long_delay();
    _lcd_write_data(0x85);
    _long_delay();
    Wie das nun in Bascom zu machen ist, kann ich Dir leider auch nicht sagen.
    Eventuell hat da aber schon jemand eine fertige LIB für dieses Display.

  5. #5
    Neuer Benutzer Öfters hier Avatar von cantforget
    Registriert seit
    24.03.2011
    Ort
    Dortmund
    Beiträge
    8
    Hallo,
    erstmal zu deiner Idee Thegon:
    Ich es mal probiert das LCD durch weglassen der Bus-Configuration zum Sprechen zu bewegen, allerdings ohne Erfolg. Bist also noch der einzige mit disem Phänomen.
    Nun zu dir wkrug:
    Also mein Gedanke dahinter war, mal eben nen bisschen Bascom-Code zu Schreiben, um zu Testen ob das Display geht. Allerdings soll das Projekt, welches daraus entsteht in C programmiert werden. Morgen werde ich mal die Lib aus dem AVR-GCC-Tutorial ausprobieren um zu schauen ob es so geht. Kannst du mir vielleicht sagen was genau ich in der lcd-routines.h anpassen muss, damit es mit meinem 20*4 Zeichen Display funktioniert? Stehe da irgendwie wie ein Ochse vorm Berg mit den Adressen.

    Gruß
    Dennis

  6. #6
    Erfahrener Benutzer Robotik Einstein Avatar von wkrug
    Registriert seit
    17.08.2006
    Ort
    Dietfurt
    Beiträge
    2.214
    Die Adressen und Ansteuer Sequenzen stehen im Datenblatt des Displays - Nur zur Info

    Nicht für AVR GCC aber für CodeVision...
    Hier die lcddip.h
    Code:
    /* LCD driver routines
    
      CodeVisionAVR C Compiler
      (C) 1998-2000 Pavel Haiduc, HP InfoTech S.R.L.
    
      BEFORE #include -ING THIS FILE YOU
      MUST DECLARE THE I/O ADDRESS OF THE
      DATA REGISTER OF THE PORT AT WHICH
      THE LCD IS CONNECTED!
    
      EXAMPLE FOR PORTB:
    
        #asm
            .equ __lcd_port=0x18
        #endasm
        #include <lcddip.h>
    Copy the File LCDDIP204.lib into the entire folder
    
    */
    
    #ifndef _LCD_INCLUDED_
    #define _LCD_INCLUDED_
    
    #pragma used+
    
    void _lcd_ready(void);
    void _lcd_write_data(unsigned char data);
    
    // write a byte to the LCD character generator or display RAM
    void lcd_write_byte(unsigned char addr, unsigned char data);
    
    // read a byte from the LCD character generator or display RAM
    unsigned char lcd_read_byte(unsigned char addr);
    
    // set the LCD display position  x=0..39 y=0..3
    void lcd_gotoxy(unsigned char x, unsigned char y);
    
    // clear the LCD
    void lcd_clear(void);
    
    void lcd_putchar(char c);
    
    // write the string str located in SRAM to the LCD
    void lcd_puts(char *str);
    
    // write the string str located in FLASH to the LCD
    void lcd_putsf(char flash *str);
    
    // initialize the LCD controller
    unsigned char lcd_init(unsigned char lcd_columns);
    
    #pragma used-
    #pragma library LCDDIP204.c
    
    #endif
    Die dazugehörige LCDDIP204.c
    Code:
    /* LCD driver routines
    
      CodeVisionAVR C Compiler
      (C) 1998-2004 Pavel Haiduc, HP InfoTech S.R.L.
    */
    
    #asm
        .equ __lcd_direction=__lcd_port-1
        .equ __lcd_pin=__lcd_port-2
        .equ __lcd_rs=0
        .equ __lcd_rd=1
        .equ __lcd_enable=2
        .equ __lcd_busy_flag=7
    #endasm
    
    #pragma used+
    static unsigned char _base_y[4]={0x80,0xc0};
    unsigned char _lcd_x,_lcd_y,_lcd_maxx;
    #pragma used-
    
    void _lcd_ready(void)
    {
    #asm
        in    r26,__lcd_direction
        andi  r26,0xf                 ;set as input
        out   __lcd_direction,r26
        sbi   __lcd_port,__lcd_rd     ;RD=1
        cbi   __lcd_port,__lcd_rs     ;RS=0
    __lcd_busy:
        rcall __lcd_delay
        sbi   __lcd_port,__lcd_enable ;EN=1
        rcall __lcd_delay
        in    r26,__lcd_pin
        cbi   __lcd_port,__lcd_enable ;EN=0
        rcall __lcd_delay
        sbi   __lcd_port,__lcd_enable ;EN=1
        rcall __lcd_delay
        cbi   __lcd_port,__lcd_enable ;EN=0
        sbrc  r26,__lcd_busy_flag
        rjmp  __lcd_busy
    #endasm
    }
    
    #asm
    __lcd_write_nibble:
        andi  r26,0xf0
        or    r26,r27
        out   __lcd_port,r26          ;write
        sbi   __lcd_port,__lcd_enable ;EN=1
        rcall __lcd_delay
        cbi   __lcd_port,__lcd_enable ;EN=0
    __lcd_delay:
        ldi   r31,15
    __lcd_delay0:
        dec   r31
        brne  __lcd_delay0
        ret
    #endasm
    
    void _lcd_write_data(unsigned char data)
    {
    #asm
        cbi  __lcd_port,__lcd_rd       ;RD=0
        in    r26,__lcd_direction
        ori   r26,0xf7                ;set as output
        out   __lcd_direction,r26
        in    r27,__lcd_port
        andi  r27,0xf
        ld    r26,y
        rcall __lcd_write_nibble      ;RD=0, write MSN
        ld    r26,y
        swap  r26
        rcall __lcd_write_nibble      ;write LSN
        sbi   __lcd_port,__lcd_rd     ;RD=1
    #endasm
    }
    
    /* write a byte to the LCD character generator or display RAM */
    #if funcused lcd_write_byte
    void lcd_write_byte(unsigned char addr, unsigned char data)
    {
    _lcd_ready();
    _lcd_write_data(addr);
    _lcd_ready();
    #asm
        sbi   __lcd_port,__lcd_rs     ;RS=1
    #endasm
    _lcd_write_data(data);
    }
    #endif
    
    #if funcused lcd_read_byte || funcused lcd_init
    #asm
    __lcd_read_nibble:
        sbi   __lcd_port,__lcd_enable ;EN=1
        rcall __lcd_delay
        in    r30,__lcd_pin           ;read
        cbi   __lcd_port,__lcd_enable ;EN=0
        rcall __lcd_delay
        andi  r30,0xf0
        ret
    #endasm
    
    static unsigned char lcd_read_byte0(void)
    {
    #asm
        rcall __lcd_delay
        rcall __lcd_read_nibble       ;read MSN
        mov   r26,r30
        rcall __lcd_read_nibble       ;read LSN
        cbi   __lcd_port,__lcd_rd     ;RD=0
        swap  r30
        or    r30,r26
    #endasm
    }
    #endif
    
    #if funcused lcd_read_byte
    /* read a byte from the LCD character generator or display RAM */
    unsigned char lcd_read_byte(unsigned char addr)
    {
    _lcd_ready();
    _lcd_write_data(addr);
    _lcd_ready();
    #asm
        in    r26,__lcd_direction
        andi  r26,0xf                 ;set as input
        out   __lcd_direction,r26
        sbi   __lcd_port,__lcd_rs     ;RS=1
    #endasm
    return lcd_read_byte0();
    }
    #endif
    
    /* set the LCD display position x=0..39 y=0..3 */
    #if funcused lcd_gotoxy || funcused lcd_putchar || funcused lcd_puts || funcused lcd_putsf
    void lcd_gotoxy(unsigned char x, unsigned char y)
    {
    _lcd_ready(); // RS=0
    _lcd_write_data(_base_y[y]+x+0x80);
    _lcd_x=x;
    _lcd_y=y;
    }
    #endif
    
    // clear the LCD
    #if funcused lcd_clear || funcused lcd_init
    void lcd_clear(void)
    {
    _lcd_ready();         // RS=0
    _lcd_write_data(2);   // cursor home
    _lcd_ready();
    _lcd_write_data(0xc); // cursor off
    _lcd_ready();
    _lcd_write_data(1);   // clear
    _lcd_x=_lcd_y=0;
    }
    #endif
    
    #if funcused lcd_putchar || funcused lcd_puts || funcused lcd_putsf
    #pragma keep+
    void lcd_putchar(char c)
    {
    #asm
        push r30
        push r31
        ld   r26,y
        set
        cpi  r26,10
        breq __lcd_putchar1
        clt
    #endasm
    ++_lcd_x;
    if (_lcd_x>_lcd_maxx)
       {
       #asm("__lcd_putchar1:")
       ++_lcd_y;
       lcd_gotoxy(0,_lcd_y);
       #asm("brts __lcd_putchar0")
       };
    #asm
        rcall __lcd_ready
        sbi  __lcd_port,__lcd_rs ;RS=1
        ld   r26,y
        st   -y,r26
        rcall __lcd_write_data
    __lcd_putchar0:
        pop  r31
        pop  r30
    #endasm
    }
    #pragma keep-
    #endif
    
    // write the string str located in SRAM to the LCD
    #if funcused lcd_puts
    void lcd_puts(char *str)
    {
    #ifdef _MODEL_TINY_
    #asm
        clr  r31
    #endasm
    #endif
    
    #ifdef _MODEL_SMALL_
    #asm
        ldd  r31,y+1
    #endasm
    #endif
    
    #asm
        ld   r30,y
    __lcd_puts0:
        ld   r26,z+
        tst  r26
        breq __lcd_puts1
        st   -y,r26    
        rcall _lcd_putchar
        rjmp __lcd_puts0
    __lcd_puts1:
    #endasm
    }
    #endif
    
    // write the string str located in FLASH to the LCD
    #if funcused lcd_putsf
    void lcd_putsf(char flash *str)
    {
    #asm
        ld   r30,y
        ldd  r31,y+1
    __lcd_putsf0:
    #endasm
    #if defined _CHIP_ATMEGA128_ || defined _CHIP_ATMEGA128L_
    #asm("elpm")
    #else
    #asm("lpm")
    #endif
    #asm
        tst  r0
        breq __lcd_putsf1
        adiw r30,1
        st   -y,r0
        rcall _lcd_putchar
        rjmp __lcd_putsf0
    __lcd_putsf1:
    #endasm
    }
    #endif
    
    #if funcused lcd_init
    static void _long_delay(void)
    {
    #asm
        clr   r26
        clr   r27
    __long_delay0:
        sbiw  r26,1         ;2 cycles
        brne  __long_delay0 ;2 cycles
    #endasm
    }
    
    static void _lcd_init_write(unsigned char data)
    {
    #asm
        cbi  __lcd_port,__lcd_rd       ;RD=0
        in    r26,__lcd_direction
        ori   r26,0xf7                ;set as output
        out   __lcd_direction,r26
        in    r27,__lcd_port
        andi  r27,0xf
        ld    r26,y
        rcall __lcd_write_nibble      ;RD=0, write MSN
        ld    r26,y
        swap  r26
        rcall __lcd_write_nibble      ;write LSN
        sbi   __lcd_port,__lcd_rd     ;RD=1
    #endasm
    }
    
    // initialize the LCD controller
    unsigned char lcd_init (unsigned char lcd_columns)
    {
    #asm
        cbi   __lcd_port,__lcd_enable ;EN=0
        cbi   __lcd_port,__lcd_rs     ;RS=0
    #endasm
    _lcd_maxx=lcd_columns;
    _base_y[0]=0x00;
    _base_y[1]=lcd_columns + 0x0C;
    _base_y[2]=lcd_columns + 0x2C;
    _base_y[3]=lcd_columns + 0x4C;
    
    _long_delay();
    _long_delay();
    _lcd_init_write(0x20);  // 4 Bit Modus + RE Bit clear
    _long_delay();
    
    _lcd_init_write(0x24);  // 4 Bit Modus + RE Bit set
    _long_delay();
    
    _lcd_init_write(0x09); 
    _long_delay();
    
    _lcd_init_write(0x20);  // 4 Bit Modus + RE Bit clear
    _long_delay();
    
    _lcd_init_write(0x0C);  // Display On
    _long_delay();
    
    _lcd_init_write(0x01);  // Clear Display
    _long_delay();
    
    _lcd_init_write(0x06);  //Auto Increment on
    _long_delay();
    
    #asm
        in    r26,__lcd_direction
        andi  r26,0xf                 ;set as input
        out   __lcd_direction,r26
        sbi   __lcd_port,__lcd_rd     ;RD=1
    #endasm
    if (lcd_read_byte0()!=5) return 0;
    _lcd_ready();
    _lcd_write_data(6);
    lcd_clear();
    return 1;
    }
    #endif
    Und die dazugehörigen Ports mit Adresszuweisung:
    // Alphanumeric LCD Module functions
    #asm
    .equ __lcd_port=0x02 ;PORTA
    #endasm
    #include "lcddip.h"

    Und die Init Sequenz mit ein wenig Text:
    lcd_init(20);

    lcd_gotoxy(0,0);
    lcd_putsf("4 Chan. MiDi Merger\n");
    lcd_putsf("Ver. 1.2\n");
    lcd_putsf("Date: 10.Feb.2011");

    Und die Anschlußbelegung:
    RS (pin4) ------ bit 0
    RD (pin 5) ------ bit 1
    EN (pin 6) ------ bit 2
    DB4 (pin 11) --- bit 4
    DB5 (pin 12) --- bit 5
    DB6 (pin 13) --- bit 6
    DB7 (pin 14) --- bit 7

    Eventuell kannst Du die GCC lib entsprechend anpassen.
    Auch mit dieser lib zickt das Display ztw. rum. Die Zeile 3 und 4 lässt sich so bei jedem 20 Start nicht richtig ansprechen.
    Ansonstan geht alles wie es soll.
    Geändert von wkrug (14.07.2011 um 16:38 Uhr)

  7. #7
    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

  8. #8
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    61
    Beiträge
    5.799
    Blog-Einträge
    8
    Allerdings hat der Code (mit dem AVR-Studio 5 compiliert) eine Größe von 7036 Byte.
    Dann machst du irgendetwas falsch:
    Klicke auf die Grafik für eine größere Ansicht

Name:	speicherplatz.jpg
Hits:	4
Größe:	69,3 KB
ID:	19334

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

  9. #9
    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

  10. #10
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    61
    Beiträge
    5.799
    Blog-Einträge
    8
    $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 hier  
    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

Seite 1 von 2 12 LetzteLetzte

Ähnliche Themen

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

Berechtigungen

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

Labornetzteil AliExpress