- 3D-Druck Einstieg und Tipps         
Seite 4 von 6 ErsteErste ... 23456 LetzteLetzte
Ergebnis 31 bis 40 von 53

Thema: LCD-Probleme

  1. #31
    Erfahrener Benutzer Roboter-Spezialist Avatar von schorsch_76
    Registriert seit
    25.03.2012
    Ort
    Kurz vor Neuschwanstein
    Alter
    47
    Beiträge
    456
    Anzeige

    Powerstation Test
    Zitat Zitat von White_Fox Beitrag anzeigen
    Pinbelegung:
    Code:
    LCD     AVR
    DB0     PC0
    DB1     PC1
    DB2     PC2
    DB3     PC3
    DB4     PC4
    DB5     PC5
    DB6     PC6
    DB7     PC7
    
    RS      PA5
    RW     PA6
    E        PC7
    Fällt dir hier bei PortC Pin 7 was auf?

    E == Databit7 == doppelt belegt.

    - - - Aktualisiert - - -

    Hier ist das hexfile mit

    // Belegung: Port C: Databits
    // Port A: 5=RS / 6=RW / 7 = E

    Datenintegrität:
    sha1sum lcd.hex
    42f8c995d4e36a1db1aedf668a075646addf47cc lcd.hex
    Size: 958 lcd.hex

    Download:
    http://www.file-upload.net/download-...0/lcd.hex.html

    Source: mit avr-gcc 4.8.2 übersetzt.

    Es sind insgesamt 21 oder 22 sec wartezeit drin....

    Code:
    #include <avr/io.h>
    #include <util/delay.h>
    
    void toggle_e()
    {
        _delay_ms(1000);
        PORTA |= (1<<7);
        _delay_ms(1000);
        PORTA &= ~(1<<7);
        _delay_ms(1000);
    }
    int main(int argc, char** argv)
    {
        // everything output
        DDRA = 0b1111111;
        DDRB = 0b1111111;
        DDRC = 0b1111111;
        DDRD = 0b1111111;
    
        PORTA = 0x00;
        PORTB = 0x00;
        PORTC = 0x00;
        PORTD = 0x00;
    
        // Belegung: Port C: Databits
        //           Port A: 5=RS / 6=RW / 7 = E
    
        // wait until display power is on
        _delay_ms(1000);
    
        // function set
        PORTC = 0b00111000;
    
        toggle_e();
    
        // display on
        PORTC=0b00001111; // everything on, that we see the most
    
        toggle_e();
    
        // display clear
        PORTC=0b00000001;
    
        toggle_e();
    
        // entry mode set
        PORTC=0b00000110;
    
        toggle_e();
    
        // cursor home
        PORTC=0b00000010;
    
        toggle_e();
    
        // try to write character
        PORTA |= (1<<5); // RS
        _delay_ms(1000);
    
        PORTC = 'W';
        _delay_ms(1000);
    
        toggle_e();
    
        while(1);
    }

  2. #32
    Erfahrener Benutzer Robotik Visionär Avatar von oberallgeier
    Registriert seit
    01.09.2007
    Ort
    Oberallgäu
    Beiträge
    8.652
    ... @oberallgeier: Welche Bibliothek benutzt du denn? Die von Fleury? ...
    Anfangs, ja. Kam mir nicht so wirklich gut vor, ich hatte danach den Code von Markus Frejek übernommen und den aufmerksam/kritisch durchgearbeitet und angepasst. Gewählt im wesentlichen weil ich a) Markus´ Testknecht nachgebaut hatte und b) er die Texte ins EEPROM verlegt hatte. Seither nehme ich diesen Code, nibbelorientiert und ich weiß jetzt einigermassen was ich tue ... (nen, was der Code macht).
    Ciao sagt der JoeamBerg

  3. #33
    Erfahrener Benutzer Robotik Visionär Avatar von oberallgeier
    Registriert seit
    01.09.2007
    Ort
    Oberallgäu
    Beiträge
    8.652
    Zitat Zitat von White_Fox Beitrag anzeigen
    ... Sind in dem Code doch noch Fehler? Ich habe 8 LEDs an Port B gehängt ...
    Hallo Fox,

    es scheinen ja mehrere Fehler drin zu sein, aber wo . . . ich zieh das mal anders auf. Dazu bitte dieses Posting ERST fertig lesen, überlegen, evtl. den hex-File runterladen und in den 644er flashen. Beachte!!! Die Belegung ist für einen PortB im vierbittigen Modus, die entsprechenden Pinns sind im C-Quelltext genannt. WENN der hexcode bei Dir funktioniert, könnten wir, könntest Du, auf dieser Basis weitermachen.

    Du hattest anfangs von ner 8bittigen Verbindung vom Port C geschrieben, nun hängen die LEDs am Port B. Deswegen habe ich eine kurze Routine in C für ein LCD geschrieben:
    mega644, interner Oszillator, 8 MHz
    LCD 2x16 am Port B angeschlossen im vierbittigen Modus,
    4-bittige Datenübergabe ans LCD

    Dazu gibts diese Hex:
    HTML-Code:
    :100000000C9438000C944D000C944D000C944D0051
    :100010000C944D000C944D000C944D000C944D002C
    :100020000C944D000C944D000C944D000C944D001C
    :100030000C944D000C944D000C944D000C944D000C
    :100040000C944D000C944D000C944D000C944D00FC
    :100050000C944D000C944D000C944D000C944D00EC
    :100060000C944D000C944D000C944D000C944D00DC
    :1000700011241FBECFEFD0E1DEBFCDBF11E0A0E065
    :10008000B1E0ECE8F2E002C005900D92A232B107B7
    :10009000D9F70E94FC000C9444010C94000095B127
    :1000A000282F22952F70907F292B25B93DE0932F83
    :1000B0009A95F1F72D9A2AE1922F9A95F1F72D98BA
    :1000C00095B18F70907F982B95B93A95F1F72D9A4D
    :1000D0002A95F1F72D9880EA8A95F1F785B1807F0E
    :1000E00085B908952C980E944F0008952C9A0E947B
    :1000F0004F0008952D9A8AE18A95F1F72D98089579
    :1001000081E00E94720080E197E20197F1F7089583
    :1001100084B18F6384B980E69AEE0197F1F785B1D7
    :10012000807E836085B92D9A9AE1892F8A95F1F7AF
    :100130002D98E0E1F7E23197F1F72D9A892F8A9512
    :10014000F1F72D9820ED37E0F9013197F1F72D9A6D
    :10015000892F8A95F1F72D98F9013197F1F785B13B
    :10016000807E826085B9F9013197F1F72D9A9A95D1
    :10017000F1F72D98C9010197F1F788E20E9472000A
    :100180008CE00E94720086E00E9472000E94800053
    :100190000895CF93DF93EC0103C00E94760021966F
    :1001A00088818823D1F7DF91CF9108950F931F9312
    :1001B000CF93DF938B01880F880F880F80640E9494
    :1001C0007200C0E0D0E0F801EC0FFD1F80810E94BA
    :1001D00076002196C830D105B1F7DF91CF911F91FC
    :1001E0000F91089520E436E004C0F9013197F1F74A
    :1001F00001970097D1F7089511B89FEF92B98FE753
    :1002000084B980E885B980EC87B98FE388B91AB8DA
    :100210009BB90E9488000E94800088EE93E020E451
    :1002200036E0F9013197F1F70197D9F780E091E0D5
    :100230000E94C90088EE93E020E436E0F90131978E
    :10024000F1F70197D9F780EC0E94720081E191E00B
    :100250000E94C90080E090E00895CF93DF93EC0105
    :10026000CE010E943C01882321F00E947600219655
    :10027000F7CFDF91CF910895F999FECF92BD81BD5F
    :0C028000F89A992780B50895F894FFCFF4
    :10028C00477275DF6F626572616C6C676569657268
    :10029C00002020536F206765687473203B2D292044
    :0202AC00200030
    :00000001FF
    ...die läuft bei mir (aber bei MIR für nen mega1284); ist hier, für den eben gezeigten hex-File, für DEINEN mega644 compiliert.

    Dazu der C-Quelltext - damit Du weißt, was vor sich geht:
    Code:
    /* >> 
      Stand  ..\C3\tstu\tstu_644.c
     =============================================================================== =
      *** Aufgabenstellung : LCD auf Port B !!! des mega644/8 MHz int. Osc.
     ============================================================================== */
      #define F_CPU     8e6
    // - - - - - - - - - - - - - - - -
      #include <lcd_162_xta.c>      // LCD-Lib ähnlich Tr-Tester, akt. PORTB, PB0..7
    
    // ============================================================================= =
    
    
    // ============================================================================= =
    // ============================================================================= =
    //### Programm pausieren lassen  !! Der Pausenwert ist nur experimentell !
      void wms(uint16_t ms)        //
      { 
        for(; ms>0; ms--) 
        { 
          uint16_t __c = 1600; 
          __asm__ volatile ( 
             "1: sbiw %0,1" "\n\t" 
             "brne 1b" 
             : "=w" (__c) 
             : "0" (__c) 
          ); 
        } 
      } 
    // ============================================================================= =
                                    
                                    
    // ============================================================================= =
    // ===  HAUPTProgramm ========================================================== =
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     int main(void)                 //
     {                              //
    // - - - - - - - - - - - - - - -
      DDRA  = 0b00000000;   // Alles auf Eingang mit (0)
      PORTA = 0b11111111;   //   mit PullUp (1)
                            //
      DDRB  = 0b01111111;   // Ausgänge mit (1)
      PORTB = 0b10000000;   //
                            //
      DDRC  = 0b11000000;   // 
      PORTC = 0b00111111;   // 
                            // 
      DDRD  = 0b00000000;   //
      PORTD = 0b11111111;   //
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    // - - - - - - - - - - - - - - -
    // ####>>>>     Initialisierung/Anschlüsse von PORT B für LCD DEM 16x2
    //   "WS" bedeutet für mich - die Anschlüsse an meinem Wannenstecker
    //     data bit 4        PB0  0 A  WS Pin1 | 
    //     data bit 5        PB1  1 A     Pin2 | -- Der 10-polige Wannenstecker
    //     data bit 6        PB2  2 A     Pin3 |    ist an die Belegung
    //     data bit 7   SCK, PB3  3 A     Pin4 |    des Transitortester angepasst
    //     RS line           PB4  RS      Pin5 |    es kommen noch
    //     ENABLE line xxxx, PB5  EN1     Pin6 |    Pin  9  GND und
    //     R/W (offen) xxxx, PB6  R/W     Pin7 |    Pin 10  Vcc dazu
    //     NC (TasteC) xxx,  PB7  NC      Pin8 |___________________________
    //     GND                            Pin9   
    //     Vcc                            Pn10      | Anmerkg: ENABLE line !
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      lcd_init();                   //
      lcd_clear();                  // Vor LCD-Ausgabe Display leeren
    // - - - - - - - - - - - - - - -
      wms( 1000 );                  // Wait
    
    // - - - - - - - - - - - - - - -
      lcd_string("Grußoberallgeier");
    
    // - - - - - - - - - - - - - - -
    //void wms(uint16_t ms)         // Waitroutine
      wms( 1000 );          // Wait
    
    // - - - - - - - - - - - - - - -
      Line2();                      // An den Anfang der 2. Zeile springen
      lcd_string("  So gehts ;-)  ");       // Zeile löschen
    
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      return 0;             //
     }                      //        
    // =====  Ende des Testabschnittes, er kann aus mehreren Abschnitten bestehen ====
    // ===============================================================================
    In der Quelle ist auch GENAU beschrieben, wie das LCD angeschlossen wird. MEIN LCD läuft damit ordentlich - und ich bin relativ sicher, dass es an einem 644er auch laufen wird.

    Wenn Du jetzt in der *.lls den Assemblercode verfolgen willst, so kannst Du das hier tun. Dazu die *.lls öffnen und möglichst die C-Quelle daneben betrachten.
    Code:
    tstu.elf:     file format elf32-avr
    
    Sections:
    Idx Name          Size      VMA       LMA       File off  Algn
      0 .data         00000022  00800100  0000028c  00000300  2**0
                      CONTENTS, ALLOC, LOAD, DATA
      1 .text         0000028c  00000000  00000000  00000074  2**1
                      CONTENTS, ALLOC, LOAD, READONLY, CODE
      2 .debug_aranges 00000020  00000000  00000000  00000322  2**0
                      CONTENTS, READONLY, DEBUGGING
      3 .debug_pubnames 000000ae  00000000  00000000  00000342  2**0
                      CONTENTS, READONLY, DEBUGGING
      4 .debug_info   00000798  00000000  00000000  000003f0  2**0
                      CONTENTS, READONLY, DEBUGGING
      5 .debug_abbrev 0000017b  00000000  00000000  00000b88  2**0
                      CONTENTS, READONLY, DEBUGGING
      6 .debug_line   0000049b  00000000  00000000  00000d03  2**0
                      CONTENTS, READONLY, DEBUGGING
      7 .debug_frame  000000c0  00000000  00000000  000011a0  2**2
                      CONTENTS, READONLY, DEBUGGING
      8 .debug_str    0000014f  00000000  00000000  00001260  2**0
                      CONTENTS, READONLY, DEBUGGING
      9 .debug_loc    00000257  00000000  00000000  000013af  2**0
                      CONTENTS, READONLY, DEBUGGING
    
    Disassembly of section .text:
    
    00000000 <__vectors>:
       0:    0c 94 38 00     jmp    0x70    ; 0x70 <__ctors_end>
       4:    0c 94 4d 00     jmp    0x9a    ; 0x9a <__bad_interrupt>
       8:    0c 94 4d 00     jmp    0x9a    ; 0x9a <__bad_interrupt>
       c:    0c 94 4d 00     jmp    0x9a    ; 0x9a <__bad_interrupt>
      10:    0c 94 4d 00     jmp    0x9a    ; 0x9a <__bad_interrupt>
      14:    0c 94 4d 00     jmp    0x9a    ; 0x9a <__bad_interrupt>
      18:    0c 94 4d 00     jmp    0x9a    ; 0x9a <__bad_interrupt>
      1c:    0c 94 4d 00     jmp    0x9a    ; 0x9a <__bad_interrupt>
      20:    0c 94 4d 00     jmp    0x9a    ; 0x9a <__bad_interrupt>
      24:    0c 94 4d 00     jmp    0x9a    ; 0x9a <__bad_interrupt>
      28:    0c 94 4d 00     jmp    0x9a    ; 0x9a <__bad_interrupt>
      2c:    0c 94 4d 00     jmp    0x9a    ; 0x9a <__bad_interrupt>
      30:    0c 94 4d 00     jmp    0x9a    ; 0x9a <__bad_interrupt>
      34:    0c 94 4d 00     jmp    0x9a    ; 0x9a <__bad_interrupt>
      38:    0c 94 4d 00     jmp    0x9a    ; 0x9a <__bad_interrupt>
      3c:    0c 94 4d 00     jmp    0x9a    ; 0x9a <__bad_interrupt>
      40:    0c 94 4d 00     jmp    0x9a    ; 0x9a <__bad_interrupt>
      44:    0c 94 4d 00     jmp    0x9a    ; 0x9a <__bad_interrupt>
      48:    0c 94 4d 00     jmp    0x9a    ; 0x9a <__bad_interrupt>
      4c:    0c 94 4d 00     jmp    0x9a    ; 0x9a <__bad_interrupt>
      50:    0c 94 4d 00     jmp    0x9a    ; 0x9a <__bad_interrupt>
      54:    0c 94 4d 00     jmp    0x9a    ; 0x9a <__bad_interrupt>
      58:    0c 94 4d 00     jmp    0x9a    ; 0x9a <__bad_interrupt>
      5c:    0c 94 4d 00     jmp    0x9a    ; 0x9a <__bad_interrupt>
      60:    0c 94 4d 00     jmp    0x9a    ; 0x9a <__bad_interrupt>
      64:    0c 94 4d 00     jmp    0x9a    ; 0x9a <__bad_interrupt>
      68:    0c 94 4d 00     jmp    0x9a    ; 0x9a <__bad_interrupt>
      6c:    0c 94 4d 00     jmp    0x9a    ; 0x9a <__bad_interrupt>
    
    00000070 <__ctors_end>:
      70:    11 24           eor    r1, r1
      72:    1f be           out    0x3f, r1    ; 63
      74:    cf ef           ldi    r28, 0xFF    ; 255
      76:    d0 e1           ldi    r29, 0x10    ; 16
      78:    de bf           out    0x3e, r29    ; 62
      7a:    cd bf           out    0x3d, r28    ; 61
    
    0000007c <__do_copy_data>:
      7c:    11 e0           ldi    r17, 0x01    ; 1
      7e:    a0 e0           ldi    r26, 0x00    ; 0
      80:    b1 e0           ldi    r27, 0x01    ; 1
      82:    ec e8           ldi    r30, 0x8C    ; 140
      84:    f2 e0           ldi    r31, 0x02    ; 2
      86:    02 c0           rjmp    .+4          ; 0x8c <.do_copy_data_start>
    
    00000088 <.do_copy_data_loop>:
      88:    05 90           lpm    r0, Z+
      8a:    0d 92           st    X+, r0
    
    0000008c <.do_copy_data_start>:
      8c:    a2 32           cpi    r26, 0x22    ; 34
      8e:    b1 07           cpc    r27, r17
      90:    d9 f7           brne    .-10         ; 0x88 <.do_copy_data_loop>
      92:    0e 94 fc 00     call    0x1f8    ; 0x1f8 <main>
      96:    0c 94 44 01     jmp    0x288    ; 0x288 <_exit>
    
    0000009a <__bad_interrupt>:
      9a:    0c 94 00 00     jmp    0    ; 0x0 <__vectors>
    
    0000009e <lcd_send>:
    
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    //Eigentliche LCD-Zugriffs-Funktion; 4-Bit-Modus
    void lcd_send(unsigned char data) {
       // oberes Nibble setzen
      LCD_PORT = (LCD_PORT & 0xF0) | ((data >> 4) & 0x0F);
      9e:    95 b1           in    r25, 0x05    ; 5
      a0:    28 2f           mov    r18, r24
      a2:    22 95           swap    r18
      a4:    2f 70           andi    r18, 0x0F    ; 15
      a6:    90 7f           andi    r25, 0xF0    ; 240
      a8:    29 2b           or    r18, r25
      aa:    25 b9           out    0x05, r18    ; 5
        can be achieved.
    */
    void
    _delay_loop_1(uint8_t __count)
    {
        __asm__ volatile (
      ac:    3d e0           ldi    r19, 0x0D    ; 13
      ae:    93 2f           mov    r25, r19
      b0:    9a 95           dec    r25
      b2:    f1 f7           brne    .-4          ; 0xb0 <lcd_send+0x12>
    
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    // erzeugt den Enable-Puls
    void lcd_enable(void)
    {
        LCD_PORT |= (1<<LCD_EN1);
      b4:    2d 9a           sbi    0x05, 5    ; 5
      b6:    2a e1           ldi    r18, 0x1A    ; 26
      b8:    92 2f           mov    r25, r18
      ba:    9a 95           dec    r25
      bc:    f1 f7           brne    .-4          ; 0xba <lcd_send+0x1c>
        _delay_us(10);                   // kurze Pause
       // Bei Problemen ggf. Pause gemäß Datenblatt des LCD Controllers verlängern
       // http://www.mikrocontroller.net/topic/80900
       LCD_PORT &= ~(1<<LCD_EN1);
      be:    2d 98           cbi    0x05, 5    ; 5
       // oberes Nibble setzen
      LCD_PORT = (LCD_PORT & 0xF0) | ((data >> 4) & 0x0F);
      _delay_us(5);
      lcd_enable();
       // unteres Nibble setzen
      LCD_PORT = (LCD_PORT & 0xF0) | (data & 0x0F);
      c0:    95 b1           in    r25, 0x05    ; 5
      c2:    8f 70           andi    r24, 0x0F    ; 15
      c4:    90 7f           andi    r25, 0xF0    ; 240
      c6:    98 2b           or    r25, r24
      c8:    95 b9           out    0x05, r25    ; 5
      ca:    3a 95           dec    r19
      cc:    f1 f7           brne    .-4          ; 0xca <lcd_send+0x2c>
    
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    // erzeugt den Enable-Puls
    void lcd_enable(void)
    {
        LCD_PORT |= (1<<LCD_EN1);
      ce:    2d 9a           sbi    0x05, 5    ; 5
      d0:    2a 95           dec    r18
      d2:    f1 f7           brne    .-4          ; 0xd0 <lcd_send+0x32>
        _delay_us(10);                   // kurze Pause
       // Bei Problemen ggf. Pause gemäß Datenblatt des LCD Controllers verlängern
       // http://www.mikrocontroller.net/topic/80900
       LCD_PORT &= ~(1<<LCD_EN1);
      d4:    2d 98           cbi    0x05, 5    ; 5
      d6:    80 ea           ldi    r24, 0xA0    ; 160
      d8:    8a 95           dec    r24
      da:    f1 f7           brne    .-4          ; 0xd8 <lcd_send+0x3a>
       // unteres Nibble setzen
      LCD_PORT = (LCD_PORT & 0xF0) | (data & 0x0F);
      _delay_us(5);
      lcd_enable();
      _delay_us(60);  
      LCD_PORT &= 0xF0;
      dc:    85 b1           in    r24, 0x05    ; 5
      de:    80 7f           andi    r24, 0xF0    ; 240
      e0:    85 b9           out    0x05, r24    ; 5
    }
      e2:    08 95           ret
    
    000000e4 <lcd_command>:
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    // sendet einen Befehl an das LCD
    
    void lcd_command(unsigned char temp1)
    {
       LCD_PORT &= ~(1<<LCD_RS);        // RS auf 0 setzen
      e4:    2c 98           cbi    0x05, 4    ; 5
       lcd_send(temp1);
      e6:    0e 94 4f 00     call    0x9e    ; 0x9e <lcd_send>
    }
      ea:    08 95           ret
    
    000000ec <lcd_data>:
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    // sendet ein Datenbyte an das LCD
    
    void lcd_data(unsigned char temp1)
    {
       LCD_PORT |= (1<<LCD_RS);        // RS auf 1 setzen
      ec:    2c 9a           sbi    0x05, 4    ; 5
       lcd_send(temp1);
      ee:    0e 94 4f 00     call    0x9e    ; 0x9e <lcd_send>
    }
      f2:    08 95           ret
    
    000000f4 <lcd_enable>:
    
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    // erzeugt den Enable-Puls
    void lcd_enable(void)
    {
        LCD_PORT |= (1<<LCD_EN1);
      f4:    2d 9a           sbi    0x05, 5    ; 5
      f6:    8a e1           ldi    r24, 0x1A    ; 26
      f8:    8a 95           dec    r24
      fa:    f1 f7           brne    .-4          ; 0xf8 <lcd_enable+0x4>
        _delay_us(10);                   // kurze Pause
       // Bei Problemen ggf. Pause gemäß Datenblatt des LCD Controllers verlängern
       // http://www.mikrocontroller.net/topic/80900
       LCD_PORT &= ~(1<<LCD_EN1);
      fc:    2d 98           cbi    0x05, 5    ; 5
    }
      fe:    08 95           ret
    
    00000100 <lcd_clear>:
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    // Sendet den Befehl zur Löschung des Displays
     
    void lcd_clear(void)
    {
       lcd_command(CLEAR_DISPLAY);
     100:    81 e0           ldi    r24, 0x01    ; 1
     102:    0e 94 72 00     call    0xe4    ; 0xe4 <lcd_command>
        milliseconds can be achieved.
     */
    void
    _delay_loop_2(uint16_t __count)
    {
        __asm__ volatile (
     106:    80 e1           ldi    r24, 0x10    ; 16
     108:    97 e2           ldi    r25, 0x27    ; 39
     10a:    01 97           sbiw    r24, 0x01    ; 1
     10c:    f1 f7           brne    .-4          ; 0x10a <lcd_clear+0xa>
       _delay_ms(5);
    }
     10e:    08 95           ret
    
    00000110 <lcd_init>:
    // Initialisierung: 
    // Muss ganz am Anfang des Programms aufgerufen werden.
     
    void lcd_init(void)
    {
        LCD_DDR = LCD_DDR | 0x0F | (1<<LCD_RS) | (1<<LCD_EN1);   // Port auf Ausgang schalten
     110:    84 b1           in    r24, 0x04    ; 4
     112:    8f 63           ori    r24, 0x3F    ; 63
     114:    84 b9           out    0x04, r24    ; 4
     116:    80 e6           ldi    r24, 0x60    ; 96
     118:    9a ee           ldi    r25, 0xEA    ; 234
     11a:    01 97           sbiw    r24, 0x01    ; 1
     11c:    f1 f7           brne    .-4          ; 0x11a <lcd_init+0xa>
        // muss 3mal hintereinander gesendet werden zur Initialisierung
        _delay_ms(30);
        LCD_PORT = (LCD_PORT & 0xF0 & ~(1<<LCD_RS)) | 0x03;
     11e:    85 b1           in    r24, 0x05    ; 5
     120:    80 7e           andi    r24, 0xE0    ; 224
     122:    83 60           ori    r24, 0x03    ; 3
     124:    85 b9           out    0x05, r24    ; 5
    
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    // erzeugt den Enable-Puls
    void lcd_enable(void)
    {
        LCD_PORT |= (1<<LCD_EN1);
     126:    2d 9a           sbi    0x05, 5    ; 5
        can be achieved.
    */
    void
    _delay_loop_1(uint8_t __count)
    {
        __asm__ volatile (
     128:    9a e1           ldi    r25, 0x1A    ; 26
     12a:    89 2f           mov    r24, r25
     12c:    8a 95           dec    r24
     12e:    f1 f7           brne    .-4          ; 0x12c <lcd_init+0x1c>
        _delay_us(10);                   // kurze Pause
       // Bei Problemen ggf. Pause gemäß Datenblatt des LCD Controllers verlängern
       // http://www.mikrocontroller.net/topic/80900
       LCD_PORT &= ~(1<<LCD_EN1);
     130:    2d 98           cbi    0x05, 5    ; 5
        milliseconds can be achieved.
     */
    void
    _delay_loop_2(uint16_t __count)
    {
        __asm__ volatile (
     132:    e0 e1           ldi    r30, 0x10    ; 16
     134:    f7 e2           ldi    r31, 0x27    ; 39
     136:    31 97           sbiw    r30, 0x01    ; 1
     138:    f1 f7           brne    .-4          ; 0x136 <lcd_init+0x26>
    
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    // erzeugt den Enable-Puls
    void lcd_enable(void)
    {
        LCD_PORT |= (1<<LCD_EN1);
     13a:    2d 9a           sbi    0x05, 5    ; 5
        can be achieved.
    */
    void
    _delay_loop_1(uint8_t __count)
    {
        __asm__ volatile (
     13c:    89 2f           mov    r24, r25
     13e:    8a 95           dec    r24
     140:    f1 f7           brne    .-4          ; 0x13e <lcd_init+0x2e>
        _delay_us(10);                   // kurze Pause
       // Bei Problemen ggf. Pause gemäß Datenblatt des LCD Controllers verlängern
       // http://www.mikrocontroller.net/topic/80900
       LCD_PORT &= ~(1<<LCD_EN1);
     142:    2d 98           cbi    0x05, 5    ; 5
        milliseconds can be achieved.
     */
    void
    _delay_loop_2(uint16_t __count)
    {
        __asm__ volatile (
     144:    20 ed           ldi    r18, 0xD0    ; 208
     146:    37 e0           ldi    r19, 0x07    ; 7
     148:    f9 01           movw    r30, r18
     14a:    31 97           sbiw    r30, 0x01    ; 1
     14c:    f1 f7           brne    .-4          ; 0x14a <lcd_init+0x3a>
    
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    // erzeugt den Enable-Puls
    void lcd_enable(void)
    {
        LCD_PORT |= (1<<LCD_EN1);
     14e:    2d 9a           sbi    0x05, 5    ; 5
        can be achieved.
    */
    void
    _delay_loop_1(uint8_t __count)
    {
        __asm__ volatile (
     150:    89 2f           mov    r24, r25
     152:    8a 95           dec    r24
     154:    f1 f7           brne    .-4          ; 0x152 <lcd_init+0x42>
        _delay_us(10);                   // kurze Pause
       // Bei Problemen ggf. Pause gemäß Datenblatt des LCD Controllers verlängern
       // http://www.mikrocontroller.net/topic/80900
       LCD_PORT &= ~(1<<LCD_EN1);
     156:    2d 98           cbi    0x05, 5    ; 5
        milliseconds can be achieved.
     */
    void
    _delay_loop_2(uint16_t __count)
    {
        __asm__ volatile (
     158:    f9 01           movw    r30, r18
     15a:    31 97           sbiw    r30, 0x01    ; 1
     15c:    f1 f7           brne    .-4          ; 0x15a <lcd_init+0x4a>
        lcd_enable();
    
        _delay_ms(1);
        lcd_enable();
        _delay_ms(1);
        LCD_PORT = (LCD_PORT & 0xF0 & ~(1<<LCD_RS)) | 0x02;
     15e:    85 b1           in    r24, 0x05    ; 5
     160:    80 7e           andi    r24, 0xE0    ; 224
     162:    82 60           ori    r24, 0x02    ; 2
     164:    85 b9           out    0x05, r24    ; 5
     166:    f9 01           movw    r30, r18
     168:    31 97           sbiw    r30, 0x01    ; 1
     16a:    f1 f7           brne    .-4          ; 0x168 <lcd_init+0x58>
    
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    // erzeugt den Enable-Puls
    void lcd_enable(void)
    {
        LCD_PORT |= (1<<LCD_EN1);
     16c:    2d 9a           sbi    0x05, 5    ; 5
        can be achieved.
    */
    void
    _delay_loop_1(uint8_t __count)
    {
        __asm__ volatile (
     16e:    9a 95           dec    r25
     170:    f1 f7           brne    .-4          ; 0x16e <lcd_init+0x5e>
        _delay_us(10);                   // kurze Pause
       // Bei Problemen ggf. Pause gemäß Datenblatt des LCD Controllers verlängern
       // http://www.mikrocontroller.net/topic/80900
       LCD_PORT &= ~(1<<LCD_EN1);
     172:    2d 98           cbi    0x05, 5    ; 5
        milliseconds can be achieved.
     */
    void
    _delay_loop_2(uint16_t __count)
    {
        __asm__ volatile (
     174:    c9 01           movw    r24, r18
     176:    01 97           sbiw    r24, 0x01    ; 1
     178:    f1 f7           brne    .-4          ; 0x176 <lcd_init+0x66>
        _delay_ms(1);
        lcd_enable();
        _delay_ms(1);
    
        // 4Bit / 2 Zeilen / 5x7
        lcd_command(CMD_SetIFOptions | 0x08);
     17a:    88 e2           ldi    r24, 0x28    ; 40
     17c:    0e 94 72 00     call    0xe4    ; 0xe4 <lcd_command>
    
        // Display ein / Cursor aus / kein Blinken
        lcd_command(CMD_SetDisplayAndCursor | 0x04);
     180:    8c e0           ldi    r24, 0x0C    ; 12
     182:    0e 94 72 00     call    0xe4    ; 0xe4 <lcd_command>
    
        // inkrement / kein Scrollen    
        lcd_command(CMD_SetEntryMode | 0x02);    
     186:    86 e0           ldi    r24, 0x06    ; 6
     188:    0e 94 72 00     call    0xe4    ; 0xe4 <lcd_command>
        lcd_clear();
     18c:    0e 94 80 00     call    0x100    ; 0x100 <lcd_clear>
    }
     190:    08 95           ret
    
    00000192 <lcd_string>:
     
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    // Schreibt einen String auf das LCD
     
    void lcd_string(char *data)
    {
     192:    cf 93           push    r28
     194:    df 93           push    r29
     196:    ec 01           movw    r28, r24
     198:    03 c0           rjmp    .+6          ; 0x1a0 <lcd_string+0xe>
        while(*data) {
            lcd_data(*data);
     19a:    0e 94 76 00     call    0xec    ; 0xec <lcd_data>
            data++;
     19e:    21 96           adiw    r28, 0x01    ; 1
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    // Schreibt einen String auf das LCD
     
    void lcd_string(char *data)
    {
        while(*data) {
     1a0:    88 81           ld    r24, Y
     1a2:    88 23           and    r24, r24
     1a4:    d1 f7           brne    .-12         ; 0x19a <lcd_string+0x8>
            lcd_data(*data);
            data++;
        }
    }
     1a6:    df 91           pop    r29
     1a8:    cf 91           pop    r28
     1aa:    08 95           ret
    
    000001ac <lcd_generatechar>:
    
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    // Schreibt ein Zeichen in den Character Generator RAM
    // Daten liegen direkt im RAM
      void lcd_generatechar(uint8_t code, const uint8_t *data)
     {                             //
     1ac:    0f 93           push    r16
     1ae:    1f 93           push    r17
     1b0:    cf 93           push    r28
     1b2:    df 93           push    r29
     1b4:    8b 01           movw    r16, r22
      lcd_command(LCD_SET_CGADR|(code<<3)); // Startposition des Zeichens einstellen
     1b6:    88 0f           add    r24, r24
     1b8:    88 0f           add    r24, r24
     1ba:    88 0f           add    r24, r24
     1bc:    80 64           ori    r24, 0x40    ; 64
     1be:    0e 94 72 00     call    0xe4    ; 0xe4 <lcd_command>
     1c2:    c0 e0           ldi    r28, 0x00    ; 0
     1c4:    d0 e0           ldi    r29, 0x00    ; 0
      for (uint8_t i=0; i<8; i++)           // Bitmuster übertragen
      {                             //
        lcd_data(data[i]);          //
     1c6:    f8 01           movw    r30, r16
     1c8:    ec 0f           add    r30, r28
     1ca:    fd 1f           adc    r31, r29
     1cc:    80 81           ld    r24, Z
     1ce:    0e 94 76 00     call    0xec    ; 0xec <lcd_data>
     1d2:    21 96           adiw    r28, 0x01    ; 1
    // Schreibt ein Zeichen in den Character Generator RAM
    // Daten liegen direkt im RAM
      void lcd_generatechar(uint8_t code, const uint8_t *data)
     {                             //
      lcd_command(LCD_SET_CGADR|(code<<3)); // Startposition des Zeichens einstellen
      for (uint8_t i=0; i<8; i++)           // Bitmuster übertragen
     1d4:    c8 30           cpi    r28, 0x08    ; 8
     1d6:    d1 05           cpc    r29, r1
     1d8:    b1 f7           brne    .-20         ; 0x1c6 <lcd_generatechar+0x1a>
      {                             //
        lcd_data(data[i]);          //
      }                             //
     }              // Ende void lcd_generatechar(uint8_t code,
     1da:    df 91           pop    r29
     1dc:    cf 91           pop    r28
     1de:    1f 91           pop    r17
     1e0:    0f 91           pop    r16
     1e2:    08 95           ret
    
    000001e4 <wms>:
      void wms(uint16_t ms)        //
      { 
        for(; ms>0; ms--) 
        { 
          uint16_t __c = 1600; 
          __asm__ volatile ( 
     1e4:    20 e4           ldi    r18, 0x40    ; 64
     1e6:    36 e0           ldi    r19, 0x06    ; 6
     1e8:    04 c0           rjmp    .+8          ; 0x1f2 <wms+0xe>
     1ea:    f9 01           movw    r30, r18
     1ec:    31 97           sbiw    r30, 0x01    ; 1
     1ee:    f1 f7           brne    .-4          ; 0x1ec <wms+0x8>
    // ============================================================================= =
    // ============================================================================= =
    //### Programm pausieren lassen  !! Der Pausenwert ist nur experimentell !
      void wms(uint16_t ms)        //
      { 
        for(; ms>0; ms--) 
     1f0:    01 97           sbiw    r24, 0x01    ; 1
     1f2:    00 97           sbiw    r24, 0x00    ; 0
     1f4:    d1 f7           brne    .-12         ; 0x1ea <wms+0x6>
             "brne 1b" 
             : "=w" (__c) 
             : "0" (__c) 
          ); 
        } 
      } 
     1f6:    08 95           ret
    
    000001f8 <main>:
    // ===  HAUPTProgramm ========================================================== =
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     int main(void)                 //
     {                              //
    // - - - - - - - - - - - - - - -
      DDRA  = 0b00000000;   // Alles auf Eingang mit (0)
     1f8:    11 b8           out    0x01, r1    ; 1
      PORTA = 0b11111111;   //   mit PullUp (1)
     1fa:    9f ef           ldi    r25, 0xFF    ; 255
     1fc:    92 b9           out    0x02, r25    ; 2
                            //
      DDRB  = 0b01111111;   // Ausgänge mit (1)
     1fe:    8f e7           ldi    r24, 0x7F    ; 127
     200:    84 b9           out    0x04, r24    ; 4
      PORTB = 0b10000000;   //
     202:    80 e8           ldi    r24, 0x80    ; 128
     204:    85 b9           out    0x05, r24    ; 5
                            //
      DDRC  = 0b11000000;   // 
     206:    80 ec           ldi    r24, 0xC0    ; 192
     208:    87 b9           out    0x07, r24    ; 7
      PORTC = 0b00111111;   // 
     20a:    8f e3           ldi    r24, 0x3F    ; 63
     20c:    88 b9           out    0x08, r24    ; 8
                            // 
      DDRD  = 0b00000000;   //
     20e:    1a b8           out    0x0a, r1    ; 10
      PORTD = 0b11111111;   //
     210:    9b b9           out    0x0b, r25    ; 11
    //     R/W (offen) MISO, PB6  R/W     Pin7 |    Pin 10  Vcc dazu
    //     NC (TasteC) SCK,  PB7  NC      Pin8 |___________________________
    //     GND                            Pin9   
    //     Vcc                            Pn10      | Anmerkg: ENABLE line !
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      lcd_init();                   //
     212:    0e 94 88 00     call    0x110    ; 0x110 <lcd_init>
      lcd_clear();                  // Vor LCD-Ausgabe Display leeren
     216:    0e 94 80 00     call    0x100    ; 0x100 <lcd_clear>
     21a:    88 ee           ldi    r24, 0xE8    ; 232
     21c:    93 e0           ldi    r25, 0x03    ; 3
      void wms(uint16_t ms)        //
      { 
        for(; ms>0; ms--) 
        { 
          uint16_t __c = 1600; 
          __asm__ volatile ( 
     21e:    20 e4           ldi    r18, 0x40    ; 64
     220:    36 e0           ldi    r19, 0x06    ; 6
     222:    f9 01           movw    r30, r18
     224:    31 97           sbiw    r30, 0x01    ; 1
     226:    f1 f7           brne    .-4          ; 0x224 <main+0x2c>
    // ============================================================================= =
    // ============================================================================= =
    //### Programm pausieren lassen  !! Der Pausenwert ist nur experimentell !
      void wms(uint16_t ms)        //
      { 
        for(; ms>0; ms--) 
     228:    01 97           sbiw    r24, 0x01    ; 1
     22a:    d9 f7           brne    .-10         ; 0x222 <main+0x2a>
      lcd_clear();                  // Vor LCD-Ausgabe Display leeren
    // - - - - - - - - - - - - - - -
      wms( 1000 );                  // Wait
    
    // - - - - - - - - - - - - - - -
      lcd_string("Grußoberallgeier");
     22c:    80 e0           ldi    r24, 0x00    ; 0
     22e:    91 e0           ldi    r25, 0x01    ; 1
     230:    0e 94 c9 00     call    0x192    ; 0x192 <lcd_string>
     234:    88 ee           ldi    r24, 0xE8    ; 232
     236:    93 e0           ldi    r25, 0x03    ; 3
      void wms(uint16_t ms)        //
      { 
        for(; ms>0; ms--) 
        { 
          uint16_t __c = 1600; 
          __asm__ volatile ( 
     238:    20 e4           ldi    r18, 0x40    ; 64
     23a:    36 e0           ldi    r19, 0x06    ; 6
     23c:    f9 01           movw    r30, r18
     23e:    31 97           sbiw    r30, 0x01    ; 1
     240:    f1 f7           brne    .-4          ; 0x23e <main+0x46>
    // ============================================================================= =
    // ============================================================================= =
    //### Programm pausieren lassen  !! Der Pausenwert ist nur experimentell !
      void wms(uint16_t ms)        //
      { 
        for(; ms>0; ms--) 
     242:    01 97           sbiw    r24, 0x01    ; 1
     244:    d9 f7           brne    .-10         ; 0x23c <main+0x44>
    // - - - - - - - - - - - - - - -
    //void wms(uint16_t ms)         // Waitroutine
      wms( 1000 );          // Wait
    
    // - - - - - - - - - - - - - - -
      Line2();                      // An den Anfang der 2. Zeile springen
     246:    80 ec           ldi    r24, 0xC0    ; 192
     248:    0e 94 72 00     call    0xe4    ; 0xe4 <lcd_command>
      lcd_string("  So gehts ;-)  ");       // Zeile löschen
     24c:    81 e1           ldi    r24, 0x11    ; 17
     24e:    91 e0           ldi    r25, 0x01    ; 1
     250:    0e 94 c9 00     call    0x192    ; 0x192 <lcd_string>
    
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      return 0;             //
     }                      //        
     254:    80 e0           ldi    r24, 0x00    ; 0
     256:    90 e0           ldi    r25, 0x00    ; 0
     258:    08 95           ret
    
    0000025a <lcd_eep_string>:
    }
    
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    //String aus EEPROM laden und an LCD senden
      void lcd_eep_string(const unsigned char *data)
     {                            //
     25a:    cf 93           push    r28
     25c:    df 93           push    r29
     25e:    ec 01           movw    r28, r24
      unsigned char c;
      while(1)                      //
      {                             //
        c = eeprom_read_byte(data); //
     260:    ce 01           movw    r24, r28
     262:    0e 94 3c 01     call    0x278    ; 0x278 <__eerd_byte_m644>
        if(c==0) return;            //
     266:    88 23           and    r24, r24
     268:    21 f0           breq    .+8          ; 0x272 <lcd_eep_string+0x18>
        lcd_data(c);                //
     26a:    0e 94 76 00     call    0xec    ; 0xec <lcd_data>
        data++;                     //
     26e:    21 96           adiw    r28, 0x01    ; 1
     270:    f7 cf           rjmp    .-18         ; 0x260 <lcd_eep_string+0x6>
      }
     }              // Ende void lcd_eep_string(const
     272:    df 91           pop    r29
     274:    cf 91           pop    r28
     276:    08 95           ret
    
    00000278 <__eerd_byte_m644>:
     278:    f9 99           sbic    0x1f, 1    ; 31
     27a:    fe cf           rjmp    .-4          ; 0x278 <__eerd_byte_m644>
     27c:    92 bd           out    0x22, r25    ; 34
     27e:    81 bd           out    0x21, r24    ; 33
     280:    f8 9a           sbi    0x1f, 0    ; 31
     282:    99 27           eor    r25, r25
     284:    80 b5           in    r24, 0x20    ; 32
     286:    08 95           ret
    
    00000288 <_exit>:
     288:    f8 94           cli
    
    0000028a <__stop_program>:
     28a:    ff cf           rjmp    .-2          ; 0x28a <__stop_program>
    Ciao sagt der JoeamBerg

  4. #34
    Erfahrener Benutzer Roboter-Spezialist Avatar von witkatz
    Registriert seit
    24.05.2006
    Ort
    NRW
    Alter
    53
    Beiträge
    540
    Blog-Einträge
    17
    @White_Fox: Ich fand noch eine Beschreibung deines TC1602E-1 im Netz: TC1602E-01.pdf vielleicht nützt es was. Auch hier findet man den gleichen Init-Flowchart wieder, den ich schon mal gepostet hab. Ich bin der Meinung (ohne jegliche AVR-Erfahrung), dass dein Code an der markierten Stelle immer noch nicht exakt umgesetzt ist:
    Klicke auf die Grafik für eine größere Ansicht

Name:	Unbenannt.GIF
Hits:	11
Größe:	47,9 KB
ID:	29057
    Hier steht es bei dir:
    Zitat Zitat von White_Fox Beitrag anzeigen
    ...
    ;Display on/off Controll
    ldi R16, 0b00001111
    out PORTC, R16
    out PORTB, R16
    sbi PORTA, 7
    rcall Warte_1s
    cbi PORTA, 7
    rcall Warte_1s
    ...[/Code]
    Du hast doch schon den Aufwand getrieben, die Ausgänge auf Debug-LEDs zu legen. Da müsste es doch möglich sein, eine relativ gut dokumentierte Initiaisierungs-Sequenz richtig durchzutakten, oder?
    Geändert von witkatz (17.09.2014 um 12:00 Uhr)

  5. #35
    Erfahrener Benutzer Roboter Genie Avatar von White_Fox
    Registriert seit
    04.10.2011
    Beiträge
    1.473
    Oha...vielen Dank für eure bisherigen Bemühungen, ich werde mir das zu späterer Stunde nochmal zu Gemüte führen, bin grad etwas kurz angeunden.

    Nur ganz kurz:
    Fällt dir hier bei PortC Pin 7 was auf?

    E == Databit7 == doppelt belegt.
    Meine Herren...wo hab ich nur meinen Kopf? E liegt nicht auf PortC, sondern daneben, auf PortA.

  6. #36
    Erfahrener Benutzer Roboter Genie Avatar von White_Fox
    Registriert seit
    04.10.2011
    Beiträge
    1.473
    So...ich habe das erste Hexfile von schorsch eben getestet.
    Nix am LCD zu sehen...allerdings bleibt der schwarze Balken in der ersten Zeile stehen.

    Ich werde mal das Hex von oberallgeier testen.


    Edit:

    YEAH!!! Das Hex von oberallgeier läuft.
    Meine Güte, was freu ich mich gerade...dann werde ich mal ganz genau untersuchen was dein Code im Einzelnen macht.

    Ich danke euch allen sehr für eure Mithilfe...ihr habt was gut bei mir.

    Edit2:
    @witkatz:
    Die .pdf kommt ir bekannt vor...ich glaub die hab ich schonmal kurz überflogen. Aber da steht ja der Controller drin, das DB guck ich mir jetzt auch nochmal genauer an. Danke.
    Geändert von White_Fox (17.09.2014 um 20:38 Uhr)

  7. #37
    Erfahrener Benutzer Robotik Visionär Avatar von oberallgeier
    Registriert seit
    01.09.2007
    Ort
    Oberallgäu
    Beiträge
    8.652
    ... YEAH!!! Das Hex ... läuft. Meine Güte, was freu ich mich gerade ... genau untersuchen was dein Code im Einzelnen macht ...
    Na prima. Das ist eine eher ältere Bibliothek aus meiner LCD-Routinen-Sammlung. Die läuft hier ohne Abfrage des Busybits - aber sie läuft, jedenfalls bei mir, "immer", hat dafür noch ne recht gute Kommentierung und ist daher hier gut geeignet. UND - die delays sind schon lausig lang . . . . Die Version mit Busyabfrage ist leider nicht präsentierbar, da müsste ich seit ner Weile mal aufräumen :-/

    Als Anhaltspunkt für eine Übersetzung nach Assembler brauchst Du also noch die beiden LCD-Quellen.
    Die lcd_162_xt.h. Bitte beachte die Einschränkung hier, dass die Datenleitungen hier nur die ersten vier Pinne eines Port sein können (andernfalls müsste man ein bisschen was ummodeln...
    Code:
    //      Erweiterte Fassung mit Routine für selbst definierte Zeichen
    // Stand = Erweiterung von lcd-routines.h und lcd-routines.c
    // vom 11. Apr. 2012
    // 28 Nov 2012, 16:23   Leichte Korrekturen
    
    // Ansteuerung eines HD44780 kompatiblen LCD im 4-Bit-Interfacemodus
    // http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial
    // http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial/LCD-Ansteuerung
    // + http://www.mikrocontroller.net/articles/HD44780#Benutzerdefinierte_Sonderzeichen
    // + http://www.mikrocontroller.net/articles/Pseudo-Graphische_LCD-Ansteuerung
    //      vgl. auch http://www.mikrocontroller.net/topic/265717#2766442
    //
    //      Ansteuerung ab KoCo_x15 geändert auf RS=PB4, EN=PB5
    
    void lcd_data(unsigned char temp1);
    void lcd_command(unsigned char temp1);
    void lcd_send(unsigned char data);
    void lcd_string(char *data);
    void lcd_enable(void);
    void lcd_init(void);
    void lcd_clear(void);
    void lcd_eep_string(const unsigned char *data);
      void lcd_generatechar( uint8_t code, const uint8_t *data );
    
    //LCD-Befehle
    // - - - - - - - - - - - - - - -
    #define CMD_SetEntryMode         0x04
    #define CMD_SetDisplayAndCursor  0x08
    #define CMD_SetIFOptions         0x20
    #define CMD_SetCGRAMAddress      0x40    // für Custom-Zeichen
    #define CMD_SetDDRAMAddress      0x80    // zum Cursor setzen
      
    // LCD Befehle
    // - - - - - - - - - - - - - - -
    #define CLEAR_DISPLAY 0x01
    
    
    // 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
    
    
    //Makros für LCD
    // - - - - - - - - - - - - - - -
    #define Line1() SetCursor(1,0)    //An den Anfang der 1. Zeile springen
    #define Line2() SetCursor(2,0)    //An den Anfang der 2. Zeile springen
    
    #define SetCursor(y, x) lcd_command((uint8_t)(CMD_SetDDRAMAddress + (0x40*(y-1)) + x))
                                    //An eine bestimmte Position springen
    
    
    #define LCDLoadCustomChar() lcd_command(CMD_SetCGRAMAddress)    //Custom-Zeichen laden
    
    //Eigene Zeichen
    // - - - - - - - - - - - - - - -
    #define LCD_CHAR_OMEGA  244     //Omega-Zeichen
    #define LCD_CHAR_U      228     //µ-Zeichen
    #define LCD_CHAR_DIODE  0       //Dioden-Icon ###>>> wird als Custom-Character erstellt
     
    // Pinbelegung für das LCD, an verwendete Pins anpassen
    #define LCD_PORT      PORTB
    #define LCD_DDR       DDRB
    #define LCD_RS        PB4
    #define LCD_EN1       PB5
    und die lcd_162_xta.c
    Code:
    //      Erweiterte Fassung mit Routine für selbst definierte Zeichen
    // Stand = Erweiterung von lcd-routines.h und lcd-routines.c
    //   vom 11. Apr. 2012
    // 28 Nov 2012 16:24  Leichte Korrekturen
    
    // Ansteuerung eines HD44780 kompatiblen LCD im 4-Bit-Interfacemodus
    // http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial
    //
    // Die Pinbelegung ist über defines in lcd-routines.h einstellbar
     
    #include <avr/io.h>
    //#include "lcd-routines.h"
    #include "lcd_162_xt.h"
    #include <util/delay.h>
    #include <avr/eeprom.h>
     
     
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    // sendet ein Datenbyte an das LCD
    
    void lcd_data(unsigned char temp1)
    {
       LCD_PORT |= (1<<LCD_RS);        // RS auf 1 setzen
       lcd_send(temp1);
    }
    
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    // sendet einen Befehl an das LCD
    
    void lcd_command(unsigned char temp1)
    {
       LCD_PORT &= ~(1<<LCD_RS);        // RS auf 0 setzen
       lcd_send(temp1);
    }
    
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    //Eigentliche LCD-Zugriffs-Funktion; 4-Bit-Modus
    void lcd_send(unsigned char data) {
       // oberes Nibble setzen
      LCD_PORT = (LCD_PORT & 0xF0) | ((data >> 4) & 0x0F);
      _delay_us(5);
      lcd_enable();
       // unteres Nibble setzen
      LCD_PORT = (LCD_PORT & 0xF0) | (data & 0x0F);
      _delay_us(5);
      lcd_enable();
      _delay_us(60);  
      LCD_PORT &= 0xF0;
    }
    
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    // erzeugt den Enable-Puls
    void lcd_enable(void)
    {
        LCD_PORT |= (1<<LCD_EN1);
        _delay_us(10);                   // kurze Pause
       // Bei Problemen ggf. Pause gemäß Datenblatt des LCD Controllers verlängern
       // http://www.mikrocontroller.net/topic/80900
       LCD_PORT &= ~(1<<LCD_EN1);
    }
     
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    // Initialisierung: 
    // Muss ganz am Anfang des Programms aufgerufen werden.
     
    void lcd_init(void)
    {
        LCD_DDR = LCD_DDR | 0x0F | (1<<LCD_RS) | (1<<LCD_EN1);   // Port auf Ausgang schalten
        // muss 3mal hintereinander gesendet werden zur Initialisierung
        _delay_ms(30);
        LCD_PORT = (LCD_PORT & 0xF0 & ~(1<<LCD_RS)) | 0x03;
        lcd_enable();
    
        _delay_ms(5);
        lcd_enable();
    
        _delay_ms(1);
        lcd_enable();
        _delay_ms(1);
        LCD_PORT = (LCD_PORT & 0xF0 & ~(1<<LCD_RS)) | 0x02;
        _delay_ms(1);
        lcd_enable();
        _delay_ms(1);
    
        // 4Bit / 2 Zeilen / 5x7
        lcd_command(CMD_SetIFOptions | 0x08);
    
        // Display ein / Cursor aus / kein Blinken
        lcd_command(CMD_SetDisplayAndCursor | 0x04);
    
        // inkrement / kein Scrollen    
        lcd_command(CMD_SetEntryMode | 0x02);    
        lcd_clear();
    }
     
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    // Sendet den Befehl zur Löschung des Displays
     
    void lcd_clear(void)
    {
       lcd_command(CLEAR_DISPLAY);
       _delay_ms(5);
    }
     
     
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    // Schreibt einen String auf das LCD
     
    void lcd_string(char *data)
    {
        while(*data) {
            lcd_data(*data);
            data++;
        }
    }
    
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    //String aus EEPROM laden und an LCD senden
      void lcd_eep_string(const unsigned char *data)
     {                            //
      unsigned char c;
      while(1)                      //
      {                             //
        c = eeprom_read_byte(data); //
        if(c==0) return;            //
        lcd_data(c);                //
        data++;                     //
      }
     }              // Ende void lcd_eep_string(const
    
    
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    // Schreibt ein Zeichen in den Character Generator RAM
    // Daten liegen direkt im RAM
      void lcd_generatechar(uint8_t code, const uint8_t *data)
     {                             //
      lcd_command(LCD_SET_CGADR|(code<<3)); // Startposition des Zeichens einstellen
      for (uint8_t i=0; i<8; i++)           // Bitmuster übertragen
      {                             //
        lcd_data(data[i]);          //
      }                             //
     }              // Ende void lcd_generatechar(uint8_t code,
    
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Viel Erfolg bei Deiner Assemblerarbeit (ich beneide Dich drum, ich hatte anfangs, bei meinem Einstieg in die Mikrocontrollerwelt, fast nur und s..gern in Assembler programmert, aber mit zunehmender Komplexität der Projekte musste dann C her).
    Ciao sagt der JoeamBerg

  8. #38
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    20.09.2008
    Ort
    Linz A
    Beiträge
    126
    Hallo an alle!

    Na, da hab ich mir ja was vorgenommen! Dieser Tread macht mir nicht gerade Mut!
    Bin gespannt, ob ich mein Vorhaben hin kriege, wenn ich es überhaupt angehe!??!?

    Hab mir dieses LCD besorgt und möchte meine Heizungssteuerung (Mega16) von den vielen LEDs auf Display umbauen.
    Natürlich bin ich davon ausgegangen, dass alle diese LCDs einen HD44780 Prozessor haben.
    Nun lese ich hier, dass dem offenbar nicht so sein MUSS!
    Im Datenblatt finde ich leider keinen Hinweis drauf welcher hier verwendet wird.

    Wenn ich mir den tread so lese wird mir ganz schwummerig, und ich überlege schon den Umbau bleiben zu lassen.
    Zumal ich auch in Assembler programmiere und absolut keine C-Kenntnisse besitze (auch mein Assembler know how ist eher noch begrenzt).

    Gruß Heinz

  9. #39
    Erfahrener Benutzer Robotik Visionär Avatar von oberallgeier
    Registriert seit
    01.09.2007
    Ort
    Oberallgäu
    Beiträge
    8.652
    Hallo Heinz,

    Du bist im Forum fast auf den Tag genau sechs Jahre, da wirst DU doch wohl nicht bei so einer Stolperstelle den Mut verlieren. Sooo schlecht ist doch die Betreuung nicht - soweit ich das kenne.

    ... da hab ich mir ja was vorgenommen ... Tread macht mir nicht gerade Mut ... wird mir ganz schwummerig ... Umbau bleiben zu lassen ...
    Schaumamal was der Thread neben Problembeschreibungen bietet. Zwei Hexe - alledings für einen mega644. Hinweise darauf, dass man keine zwei Funktionen auf einen Pinn legen soll *ggg*. Damit kann man ja schon was anfangen . . . Und weils grad über Anfang geht: welchen Controller benutzt Du ? Woher stammt DEIN Display? Denn wenn Du Heizungsanlage schreibst muss ich sagen: meine Heizung muss schon jetzt laufen (oberes Allgäu = Alpenrand = schnell s..kühl) und auch bei Dir kommt der nächste Winter ganz bestimmt.
    Ciao sagt der JoeamBerg

  10. #40
    Erfahrener Benutzer Roboter-Spezialist Avatar von schorsch_76
    Registriert seit
    25.03.2012
    Ort
    Kurz vor Neuschwanstein
    Alter
    47
    Beiträge
    456
    @HeST: Na das war schon eine schwere Geburt. Muss man schon sagen. Du kannst aber immer davon ausgehen, wenn du dich ans Datenblatt hältst, kommst du ans Ziel.

    Apropos: Ich mach auch gerade meine Heizungssteuerung mit einem Atmega168 (falls der Flash nicht reicht, eben 328 ) und einem Display mit KS0073 über einen PCF8574 und I2C. War jetzt nicht so schwer wie es sich hier in dem Thread darstellt ...

    Klicke auf die Grafik für eine größere Ansicht

Name:	Heizung.jpg
Hits:	12
Größe:	45,4 KB
ID:	29059

    Wie man sieht bin ich noch in der Testphase

Seite 4 von 6 ErsteErste ... 23456 LetzteLetzte

Ähnliche Themen

  1. riesige LCD Probleme
    Von Ineedhelp im Forum AVR Hardwarethemen
    Antworten: 8
    Letzter Beitrag: 23.05.2008, 15:53
  2. Probleme mit LCD
    Von Mr Bean im Forum C - Programmierung (GCC u.a.)
    Antworten: 6
    Letzter Beitrag: 25.10.2007, 09:10
  3. Probleme mit LCD
    Von Jigger im Forum Elektronik
    Antworten: 5
    Letzter Beitrag: 18.02.2007, 13:56
  4. LCD Probleme
    Von dpressedp im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 1
    Letzter Beitrag: 11.01.2007, 13:56
  5. harte LCD-Probleme
    Von Lemonsquash im Forum Elektronik
    Antworten: 3
    Letzter Beitrag: 21.10.2006, 21:55

Berechtigungen

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

Solar Speicher und Akkus Tests