- Akku Tests und Balkonkraftwerk Speicher         
Ergebnis 1 bis 8 von 8

Thema: LCD: Pos = 40*y + x geht nur teilweise

  1. #1
    Erfahrener Benutzer Roboter-Spezialist Avatar von -schumi-
    Registriert seit
    30.12.2009
    Ort
    Wasserburg am Inn / Bayern
    Alter
    30
    Beiträge
    449

    LCD: Pos = 40*y + x geht nur teilweise

    Anzeige

    Powerstation Test
    Hallo zusammen,

    da ich leider ausversehen meine Sourcecodes ins Nirvana geschickt habe und nur noch eine halbfertige Lib fürs LCD hatte, hab ich die jetzt erweitert um wieder eine neue zu haben
    (Jetzt ist alles in der DropBox -> OS ausversehen drüberinstallieren geht nicht mehr^^)

    Allerdings habe ich ein Problem mit der Positionierung des Coursors:
    1. Zeile: Funktioniert
    2. Zeile: kann nur an den Anfang springen

    Ich berechne die Adresse mit Pos = y*40 + x, siehe meine LCD.c:
    Code:
    void LCD_POS (unsigned int line, unsigned int column)
    {
        LCD_COMMAND(0b10000000 + (line*40) + column);
    }
    Warum? Ich checks einfach nicht...

    Schon mal Danke im voraus :-D
    -schumi-

    [EDIT]
    Es ist ein HDD44780 LCD mit 2*16 Zeichen

  2. #2
    Erfahrener Benutzer Roboter-Spezialist Avatar von -schumi-
    Registriert seit
    30.12.2009
    Ort
    Wasserburg am Inn / Bayern
    Alter
    30
    Beiträge
    449
    ARGH! Natürlich findet man die Lösung immer erst wenn man schon gepostet hat

    Lösung:
    1laaaaaa

    • l = Zeilennummer (0 oder 1)
    • a = 6-Bit Spaltennummer
    ( http://www.mikrocontroller.net/artic...im_4-Bit-Modus )

    -> LCD.c
    Code:
    void LCD_POS (unsigned int line, unsigned int column)
    {
        if(line)
            LCD_COMMAND(0b11000000 + column);
        else
            LCD_COMMAND(0b10000000 + column);
    }
    Entschuldigung für diesen wohl sehr überflüssigen Thread^^

    Naja, dafür gibts die hier als Entschädigung die Lib zum nachbasteln (währe dann soweit fertig)

    LCD.c:
    Code:
    #include <avr/io.h>
    #include <util/delay.h>
    #include <stdlib.h>
    #include "LCD.h"
    
    void LCD_SETBYTE (char data)
    {
        LCD_PORT = LCD_PIN & ~(LCD_D0 | LCD_D1 | LCD_D2 | LCD_D3);
        if( data & 1<<0 ) LCD_PORT = LCD_PIN | LCD_D0;
        if( data & 1<<1 ) LCD_PORT = LCD_PIN | LCD_D1;
        if( data & 1<<2 ) LCD_PORT = LCD_PIN | LCD_D2;
        if( data & 1<<3 ) LCD_PORT = LCD_PIN | LCD_D3;
    }
    
    void LCD_ENABLE (void)
    {
        LCD_PORT = (LCD_PIN | LCD_EN);
        _delay_us(1);
        LCD_PORT = (LCD_PIN & ~LCD_EN);
    }
    
    void LCD_DATA (char data)
    {
        char data2 = data;
        data = (data>>4);
        data = (data & 0b00001111);
        LCD_PORT = (LCD_PIN | LCD_RS) & ~(LCD_EN | LCD_D0 | LCD_D1 | LCD_D2 | LCD_D3);
        LCD_SETBYTE (data);
        LCD_ENABLE();
        _delay_us(45);
    
        data2 = (data2 & 0b00001111);
        LCD_PORT = (LCD_PIN | LCD_RS) & ~(LCD_EN | LCD_D0 | LCD_D1 | LCD_D2 | LCD_D3);
        LCD_SETBYTE (data2);
        LCD_ENABLE();
        _delay_ms(2);
    }
    
    
    
    void LCD_COMMAND (char command)
    {
        char command2 = command;
        command = (command>>4);
        command = (command & 0b00001111);
        LCD_PORT = LCD_PIN & ~(LCD_RS | LCD_EN | LCD_D0 | LCD_D1 | LCD_D2 | LCD_D3);
        LCD_SETBYTE (command);
        LCD_ENABLE();
        _delay_us(45);
    
        command2 = (command2 & 0b00001111);
        LCD_PORT = LCD_PIN & ~(LCD_RS | LCD_EN | LCD_D0 | LCD_D1 | LCD_D2 | LCD_D3);
        LCD_SETBYTE (command2);
        LCD_ENABLE();
        _delay_ms(2);
    }
    
    void LCD_STRING(char *string) 
    {    
        while(*string)
        {
            LCD_DATA(*string++);     // zeichen am LC-Display ausgeben                    
        }
    }
    
    void LCD_CLEAR (void)
    {
        LCD_COMMAND(0b00000001);
    }
    
    void LCD_HOME (void)
    {
        LCD_COMMAND(0b00000010);
    }
    
    void LCD_POS (unsigned int line, unsigned int column)
    {
        if(line)
            LCD_COMMAND(0b11000000 + column);
        else
            LCD_COMMAND(0b10000000 + column);
    }
    
    void LCD_INT (int number)
    {
        char string[16];
        itoa(number,string, 10);
        LCD_STRING(string);
    }
    
    void LCD_HEX (int number)
    {
        char string[16];
        itoa(number,string, 16);
        LCD_STRING(string);
    }
    
    void LCD_BIN (int number)
    {
        char string[16];
        itoa(number,string, 2);
        LCD_STRING(string);
    }
    
    void LCD_OCT (int number)
    {
        char string[16];
        itoa(number,string, 8);
        LCD_STRING(string);
    }
    
    void LCD_INIT (void)
    {
        LCD_DDR = LCD_DDR | LCD_RS | LCD_EN | LCD_D0 | LCD_D1 | LCD_D2 | LCD_D3;
        for(int inittimes=0; inittimes<3; inittimes++)
        {
            LCD_PORT = LCD_PIN | LCD_RS | LCD_EN | LCD_D0 | LCD_D1 | LCD_D2 | LCD_D3;
            LCD_PORT = LCD_PORT = LCD_PIN & ~(LCD_EN | LCD_RS);
            _delay_ms(15);
            LCD_SETBYTE (0x30);
            LCD_ENABLE();
            _delay_ms(5);
            LCD_ENABLE();
            _delay_us(100);
            LCD_ENABLE();
            _delay_us(100);
            LCD_SETBYTE (0x20);
            LCD_ENABLE();
            _delay_us(100);
            LCD_COMMAND(0x28);
            LCD_COMMAND(0x08);
            LCD_COMMAND(0x01);
            LCD_COMMAND(0x06);
            LCD_COMMAND(0x0C);
            LCD_COMMAND(0b00000001);
        }
    }
    LCD.h:
    Code:
    #ifndef _LCD_h_
    #define _LCD_h_
    
    void LCD_SETBYTE (char data);
    void LCD_ENABLE (void);
    void LCD_DATA (char data);
    void LCD_COMMAND (char command);
    void LCD_STRING(char *string);
    void LCD_CLEAR (void);
    void LCD_HOME (void);
    void LCD_POS (unsigned int line, unsigned int column);
    void LCD_INT (int number);
    void LCD_HEX (int number);
    void LCD_BIN (int number);
    void LCD_OCT (int number);
    void LCD_INIT (void);
    
    #define    LCD_DDR        DDRA
    #define LCD_PORT    PORTA
    #define LCD_PIN        PINA
    #define    LCD_EN        PIN 6
    #define LCD_RS        PIN 4
    #define LCD_D0        PIN 0
    #define LCD_D1        PIN 1
    #define LCD_D2        PIN 2
    #define LCD_D3        PIN 3
    
    #define PIN        1<<
    
    #endif
    Und ein kleines Anwendungsbeispiel (Laufschrift in der ersten Zeile und Counter in der zweiten):

    Code:
    #include <avr/io.h>
    #include <util/delay.h>
    #include "LCD.h"
    
    int main(void)
    {
        LCD_INIT();
     
        char Zeichenstring[] = "LCD-Lib funzt!  ";
        char temp;
        char schleife;
        unsigned char counter=0;
      
        while(1)
        {
            LCD_CLEAR();
            LCD_POS(0, 0);
            LCD_STRING(Zeichenstring);
            LCD_POS(1, 5);
            LCD_INT(counter++);
    
            temp = Zeichenstring[0];
            for(schleife=0; schleife<14; schleife++)
            {
                Zeichenstring[schleife] = Zeichenstring[schleife+1];
            }
            Zeichenstring[14] = temp;
            _delay_ms(220);
        }
        return 0;
    }
    Gruß
    -schumi-

  3. #3
    Erfahrener Benutzer Roboter Genie Avatar von BMS
    Registriert seit
    21.06.2006
    Ort
    TT,KA
    Alter
    32
    Beiträge
    1.192
    Hi,
    also ich hab in meiner Lib anstatt einer 40 eine 64 stehen, probier's mal
    Grüße, Bernhard

    edit: zu langsam

  4. #4
    Erfahrener Benutzer Roboter-Spezialist Avatar von -schumi-
    Registriert seit
    30.12.2009
    Ort
    Wasserburg am Inn / Bayern
    Alter
    30
    Beiträge
    449
    edit: zu langsam
    Trotzdem danke für die Antwort!

    Hab mal mit 64 ausprobiert -> funzt

    Was auch damit zusammenhängen könnte dass 0b01000000 zufälligerweise 64 ist wie mir gerade einfällt :-D

    Gruß

  5. #5
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    61
    Beiträge
    5.799
    Blog-Einträge
    8
    Was für ein erstaunlicher Zufall ;) Übrigends wäre 0x40 auch 64.

    Und wie immer sehr verblüffend: Kaum macht man es richtig, funktioniert es auch. Danke für die hübsche Library.

    Gruß

    mic
    Bild hier  
    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

  6. #6
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    02.04.2010
    Ort
    Wien
    Beiträge
    119
    Blog-Einträge
    4
    Hey, also wenn ich die lib und da Programm verwenden will, wie mach ich das dann?
    ich hab leider keine ahnung von dem ganzen,
    hab schon herumprobiert und so,
    aber ich schaffs nichtmal das beispielprogramm zu compilieren...

    gibt es irgendwo eine einführung in das thema lcd displays oder so,
    das ich einfach noch nicht gefunden habe?

    danke schonmal

    mfg michi

  7. #7
    Erfahrener Benutzer Roboter-Spezialist Avatar von -schumi-
    Registriert seit
    30.12.2009
    Ort
    Wasserburg am Inn / Bayern
    Alter
    30
    Beiträge
    449
    Hallo miicchii :-D

    leider hab ich irgendwie deinen Beitrag völlig verpennt... Sry


    Machen tust du das so:
    - du hast eine main.c, dort steht dann dein normaler Code drin
    - Du nimmst jeweils noch die LCD.c und die LCD.h und speicherst sie im selben Ordner wie die main.c
    - in der main.c dann >> #include "LCD.h" << einfügen (wie man in dem Beispiel oben sehen kann)
    - dann noch in der LCD.h den Teil hier an deine Hardware anpassen:
    Code:
    #define LCD_DDR       DDRA 
    #define LCD_PORT      PORTA 
    #define LCD_PIN       PINA 
    #define LCD_EN        PIN 6 
    #define LCD_RS        PIN 4 
    #define LCD_D0        PIN 0 
    #define LCD_D1        PIN 1 
    #define LCD_D2        PIN 2 
    #define LCD_D3        PIN 3
    Zum kompilieren musst du noch das Makefile verändern:
    ziemlich weit oben steht das hier:
    Code:
    SRC = $(TARGET).c
    das änderst du in:
    Code:
    SRC = $(TARGET).c LCD.c
    Gruß
    schumi

  8. #8
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    02.04.2010
    Ort
    Wien
    Beiträge
    119
    Blog-Einträge
    4
    Danke für die Antwort, hab eine Lösung auf anderem wege gefunden,
    läuft jetzt im 8-bit Modus, wahrscheinlich probier ichs später mit nur 4,
    wenn ich das mal ganz verstanden hab xD
    Ich verwende übrigens AVR Studio also nichts mit makefiles selber schreiben^^

    danke und lg miicchhii
    Infos zu meinen Projekten gibts auf meiner Homepage: http://langeder.org/

Ähnliche Themen

  1. DS1307 (I2C Echtzeituhr) funktioniert nur teilweise!
    Von papuadive im Forum Microcontroller allgemeine Fragen/Andere Microcontroller
    Antworten: 4
    Letzter Beitrag: 05.04.2011, 10:12
  2. probot 128 nur teilweise funktionsfähig :(
    Von scrider im Forum Allgemeines zum Thema Roboter / Modellbau
    Antworten: 1
    Letzter Beitrag: 03.01.2010, 23:52
  3. Antworten: 2
    Letzter Beitrag: 20.04.2008, 23:30
  4. atmega 8 adc nur teilweise aktivieren?
    Von Mac Gyver im Forum AVR Hardwarethemen
    Antworten: 2
    Letzter Beitrag: 14.10.2006, 14:21
  5. LCD teilweise Löschen
    Von Mr-400-Volt im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 2
    Letzter Beitrag: 17.07.2006, 19:11

Berechtigungen

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

Solar Speicher und Akkus Tests