- MultiPlus Wechselrichter Insel und Nulleinspeisung Conrad         
Seite 2 von 3 ErsteErste 123 LetzteLetzte
Ergebnis 11 bis 20 von 28

Thema: I2C Adressen

  1. #11
    Moderator Robotik Einstein Avatar von Kampi
    Registriert seit
    21.11.2009
    Ort
    Monheim, Nordrhein-Westfalen, Germany
    Alter
    35
    Beiträge
    3.501
    Blog-Einträge
    9
    Anzeige

    LiFePo4 Akku selber bauen - Video
    Hey,

    naja so sau dumm ist die Frage nicht
    Die Adresse die im Datenblatt steht (in deinem Fall die 0x68 ) ist die Grundadresse, sprich OHNE Read/Write Bit.
    Das heißt für eine komplette Adresse musst du das Read/Write Bit noch anhängen und das ist ja immer unterschiedlich, je nachdem ob du Lesen oder Schreiben willst.
    Ergo wird das Bitmuster für die 0x68 um eine Stelle nach links geschoben.
    Dadurch wird das Read/Write Bit automatisch mit einer 0 gefüllt und du musst es im Falle eines schreibenden Zugriffs nur noch auf 1 setzen (das machst du, indem du die Adresse mit einer 0x01 verODERst).
    Schaut ruhig mal auf meiner Homepage vorbei :
    http://kampis-elektroecke.de

    Oder folge mir auf Google+:
    Daniel Kampert

    Es gibt 10 Arten von Menschen. Die einen können Binär, die anderen nicht.

    Gruß
    Daniel

  2. #12
    Erfahrener Benutzer Roboter Genie Avatar von oderlachs
    Registriert seit
    17.05.2010
    Ort
    Oderberg
    Alter
    74
    Beiträge
    1.175
    Blog-Einträge
    1
    Also , ich habe kapituliert vorerst und weil es drängte mit der Zeit, erstmal eine Bascom Software geschrieben(holprigerweise). Da klappt es wunderbar mit dem Auslesen der Zeit.
    Ich kann's einfach nicht begreifen.
    Die Adressenzuordnung stimmt schon , aber ich bekomme einfach nicht die Zeit ausgelesen vom DS1307.
    Ich schreibe die I2C Adr + 1 für Lesen,dann die Registeradresse, und überneme dann die Daten vom Datenregister als Datenwert...aber nix sinnvolles kommt dabei raus.
    Natürlich Wird auch noch TWI_INIT, TWI_START,TWI_STOP entsprechend durchgeführt.

    Gerhard, mit hängendem Kopfe..

    Nachtrag: Ich habe mir dieses Beispiel als Vorlage genommen zum Test, ohne das Setzen der UHR (Auskommentiert) wollte nur sec,min,hr auswerten. Das RTC ist mit aktueller Zeit versorgt
    Geändert von oderlachs (16.06.2013 um 09:46 Uhr)
    Arduinos, STK-500(AVR), EasyPIC-40, PICKIT 3 & MPLABX-IDE , Linux Mint

  3. #13
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    01.10.2009
    Beiträge
    437
    Zitat Zitat von oderlachs Beitrag anzeigen
    Ich schreibe die I2C Adr + 1 für Lesen,dann die Registeradresse, und überneme dann die Daten vom Datenregister als Datenwert...aber nix sinnvolles kommt dabei raus.
    Ich hab Dir das schon mal geschrieben und auch wenn Du's nicht gerne hörst: Wenn Du Dir von einer Diskussion mehr erwartest, dann müsstest Du mehr darauf eingehen.
    Hier z.B. Deinen Bascom-Code und Deinen C-Code zeigen, dann kann man sagen, was Du falsch machst.
    Natürlich Wird auch noch TWI_INIT, TWI_START,TWI_STOP entsprechend durchgeführt.
    Ein Beschreibung eines Codes, sei's Prosa oder nicht, taugt nichts. Nur der Code selbst taugt.
    Nachtrag: Ich habe mir dieses Beispiel als Vorlage genommen zum Test, ohne das Setzen der UHR (Auskommentiert) wollte nur sec,min,hr auswerten.
    Wieso nimmst Du ein Beispiel, dass erklärtermaßen seitens des TE dort nicht funktioniert? Er schreibt, dass er den Code erfolgreich compiliert hat, er schreibt auch dass er nicht läuft.

  4. #14
    Erfahrener Benutzer Roboter Genie Avatar von oderlachs
    Registriert seit
    17.05.2010
    Ort
    Oderberg
    Alter
    74
    Beiträge
    1.175
    Blog-Einträge
    1
    Hallo MagicWSmoke !
    Im Posting 12 also genau vor Deiner Antwort ist ein Link zu dem Beispiel, das ich nutze und hier nochmals in wiederholter Form:
    Nachtrag: Ich habe mir dieses Beispiel als Vorlage genommen zum Test, ohne das Setzen der UHR (Auskommentiert) wollte nur sec,min,hr auswerten. Das RTC ist mit aktueller Zeit versorgt
    Nur ist ein Unterschied, das bei mir der PortB.0 bei HR= 8 und MIN = 30 von HIGH zu LOW wechseln ...
    also:
    Code:
    HR_D = BCD2DEC(hr);    // Zeit von BCD Code in Dezimal umwandeln
    MIN_D = BCD2DEC(min); // Zeit von BCD Code in Dezimal umwandeln
     if ((HR_D == 0x08)  &&  (MIN_D  == 0x1E)) PORTB =0xFE
    else PORTB = 0xFF;
    if ((HR_D == 0x08) && (MIN_D  == 0x1F)) PORTB =0xFD;
    else PORTB = 0xFF;
    Mein Code zur Auswertung mal angedeutet, ohne die aber vorhandenen(!!!) Funktionen BCD2DEC dargestellt, also da kann ich nix auswerten. Es sei denn ich initialisiere selber die Zeitvariablen mit dem entsprechenden wert, dann geht es.
    Ich hoffe das reicht nun zur Erklärung...

    Nachtrag: Um allem gerecht zu werden hier nun der komplette Code den ich verwende und der nicht geht, d.h. keine Auswertung an PortB0,PortB1 möglich...
    Code:
    /* ========================================================================== */
    /*                                                                            */
    /*   zeitauswertung DS1307 / ATMEGA16 an PortB Pin B0 + B1                    */
    /*                                                                            */
    /* ========================================================================== */
    
    #define F_CPU 1600000UL
    
    #include<avr/io.h>
    #include<util/delay.h>
    
    
    void rtc_init(void)
    {
    TWSR=0x00;
    TWBR=0x98;
    TWCR=0x04;
    
    }
    
    void rtc_start(void)
    {
    // sende START Bedingungen
        TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
    
        // warte bis fertig...
        while(!(TWCR & (1<<TWINT)));
    }
    
    
    
    unsigned char rtc_read(void)
    {
    TWCR=(1<<TWINT)|(1<<TWEN);
    while(!(TWCR & (1<<TWINT)));
    return(TWDR);
    }
    
    void rtc_write(unsigned char data)
    {
    TWDR=data;// sending address
    TWCR=(1<<TWINT)|(1<<TWEN);
    // warte bis fertig...
        while(!(TWCR & (1<<TWINT)));}
    
    void rtc_stop()
    {
    TWCR=(1<<TWINT)|(TWSTO)|(1<<TWEN);
    // warte bis fertig...
        while(!(TWCR & (1<<TWINT)));
    }
    /* ========================================================================== */
    /*                                                                            */
    /*                          DEZIMAL ZU BCD // Uhr Stellen                     */
    /*                                                                            */
    /* ========================================================================== */
    char dez_to_bcd(char num)
    {
    return ((num/10 * 16) + (num % 10));
    }
    /* ========================================================================== */
    /*                                                                            */
    /*                          BCD zu DEZIMAL // UHR LESEN                       */
    /*                                                                            */
    /* ========================================================================== */
    char bcd_to_dez(char num)
    {
    return ((num/16 * 10) + (num % 16));
    }
    /* ========================================================================== */
    /*                                                                            */
    /*                                                                            */
    /*                                                                            */
    /* ========================================================================== */
    int main(void)
    {
    unsigned char sec,min,hr,HR_D,MIN_D;
    
    DDRB=0xFF;
    
    
    rtc_init();
    _delay_ms(1000);
    
    rtc_start();
    /// Zeit zum Test auf 0,5 min vor Schaltvorgang setzen
    rtc_write(0b11010000);   // 1101000=adress of ds1307 and bit 0= write   
    rtc_write(0x00);  // pointing address location 00 i.e seconds
    rtc_write(0x1E);// set sec=30
    rtc_write(0x1D);// set min=29
    rtc_write(0x08);// set hr=8
    
    rtc_stop();
    
    
    while(1)
    {
    
    rtc_start();
    rtc_write(0b11010001);   // 1101000=adress of ds1307 and bit 1= read   
    rtc_write(0x00);  // pointing address location 00 i.e seconds
    sec=rtc_read();
    rtc_stop();
    _delay_ms(50);           // etwas warten
    
    rtc_start();
    rtc_write(0b11010001);   // 1101000=adress of ds1307 and bit 1= read   
    rtc_write(0x01);         // pointing address location 01 i.e minute
    min=rtc_read();
    rtc_stop();
    _delay_ms(50);           // etwas warten
    
    rtc_start();
    rtc_write(0b11010001);   // 1101000=adress of ds1307 and bit 1= read   
    rtc_write(0x02);         // pointing address location 02 i.e hours
    hr=rtc_read();
    rtc_stop();
    _delay_ms(50); // etwas warten
    
    // Zeit decodieren und auswerten
    HR_D  = bcd_to_dez(hr);    // Zeit von BCD Code in Dezimal umwandeln
    MIN_D = bcd_to_dez(min); // Zeit von BCD Code in Dezimal umwandeln
     if ((HR_D == 0x08)  &&  (MIN_D  == 0x1E)) PORTB =0xFE;
    else PORTB = 0xFF;
    if ((HR_D == 0x08) && (MIN_D  == 0x1F)) PORTB =0xFD;
    else PORTB = 0xFF;
    }
    }
    Woher das Grundgerüst ist , findet man unter den oben erwähnten Link.
    Gerhard
    Geändert von oderlachs (16.06.2013 um 17:14 Uhr)
    Arduinos, STK-500(AVR), EasyPIC-40, PICKIT 3 & MPLABX-IDE , Linux Mint

  5. #15
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    01.10.2009
    Beiträge
    437
    Zitat Zitat von oderlachs Beitrag anzeigen
    Im Posting 12 also genau vor Deiner Antwort ist ein Link zu dem Beispiel
    Ich habe diesen Link nicht übersehen und bezog mich gerade darauf:
    Wieso nimmst Du ein Beispiel, dass erklärtermaßen seitens des TE dort nicht funktioniert?
    Zitat des verlinkten Threads:
    When I am running this code on PROTEUS simulator I am not getting any output, but polling in the code working properly for applying delay.

    1 Answer
    I don't think you are generating the start condition correctly, among other things.
    Was mich zu meiner Frage brachte, warum Du (als ein Lernender in I2C) einen Code nimmst, bei dem der TE selbst erklärt, dass der nicht geht, und bei dem zwar ein Teilnehmer Hilfestellung gab, dieser Thread jedoch weder geklärt, noch abgeschlossen wurde. Das war mir unverständlich, aber übersehen hab' ich nichts.

    Genauso wie meine Aufforderung an Dich, den Bascom-Code zu zeigen, nicht aus dem Grund heraus entstand, dass ich nicht wüsste, wie's unter Bascom zu programmieren wäre, sondern deswegen, weil ich am funktionierenden Code genau die Einstellungen ablesen und dann Deinen C-Code beurteilen, bzw. verbessern kann.

    - - - Aktualisiert - - -

    Nur mal ein paar Sachen, die krumm sind, hier z.B. hast Du genau einen Fehler des TE's übernommen:
    Code:
    void rtc_stop()
    {
        TWCR=(1<<TWINT)|(TWSTO)|(1<<TWEN);
        // warte bis fertig...
        while(!(TWCR & (1<<TWINT)));
    }
    Das muss so lauten:
    Code:
    TWCR=(1<<TWINT)|(1<<TWSTO)|(1<<TWEN);
    Dieser Fehler hat zur Folge, dass die Funktion rtc_stop() nicht als Stop, sondern als Start ausgeführt wird.
    Da wär' ich als DS1307 auch verwirrt

    Weiter, der Lesezyklus für die DS1307 geht so:
    Code:
    Start
       Sende Schreibadresse (RW=0)
       Sende Register der DS1307, welches adressiert werden soll
       (Repeated) Start
       Sende Leseadresse (RW=1)
       Lese Sekunde mit ACK
       ...
       Lese Jahr mit NACK
    Stop
    Jetzt schau' Dir mal den Zeugs an, den Du von dem verlinkten Thread des TE übernommen hast und vergleiche das:
    Code:
            rtc_start();
            rtc_write(0b11010001);   // 1101000=adress of ds1307 and bit 1= read
            rtc_write(0x00);  // pointing address location 00 i.e seconds
            sec=rtc_read();
            rtc_stop();
            _delay_ms(50);           // etwas warten
    
            rtc_start();
            rtc_write(0b11010001);   // 1101000=adress of ds1307 and bit 1= read
            rtc_write(0x01);         // pointing address location 01 i.e minute
            min=rtc_read();
            rtc_stop();
            _delay_ms(50);           // etwas warten
    
            rtc_start();
            rtc_write(0b11010001);   // 1101000=adress of ds1307 and bit 1= read
            rtc_write(0x02);         // pointing address location 02 i.e hours
            hr=rtc_read();
            rtc_stop();
            _delay_ms(50); // etwas warten
    Es wundert mich nicht, dass das nicht klappt, genauso wie ich verstehe, dass es frustriert, wenn man auf solchem Code aufbaut.

    - - - Aktualisiert - - -

    Versuch' das hier, ACK, NACK wird nicht berücksichtigt, da Du sowieso keine Behandlung der Status-Codes hast.
    Code:
    #define F_CPU 16000000UL
    
    #include<avr/io.h>
    #include<util/delay.h>
    
    #define rtc_adr_w 0xD0
    #define rtc_adr_r rtc_adr_w | 0x01
    
    void rtc_init(void)
    {
        TWSR=0x00;
        TWBR=0x98;  // I2C Clock 50kHz@16MHz
    }
    
    void rtc_start(void)
    {
        TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
            while(!(TWCR & (1<<TWINT)));
    }
    
    unsigned char rtc_read(void)
    {
        TWCR=(1<<TWINT)|(1<<TWEN);
            while(!(TWCR & (1<<TWINT)));
        return(TWDR);
    }
    
    void rtc_write(unsigned char data)
    {
        TWDR=data;// sending address
        TWCR=(1<<TWINT) | (1<<TWEN);
          while(!(TWCR & (1<<TWINT)));}
    
    void rtc_stop()
    {
        TWCR=(1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
            while(!(TWCR & (1<<TWINT)));
    }
    int main(void)
    {
        unsigned char sec;
        unsigned char last_sec = 0;
        DDRB=0xFF;
        PORTB=0xFF;
        
        rtc_init();
        while(1)
        {
            rtc_start();
            rtc_write(rtc_adr_w);   // Sende Schreibadresse
            rtc_write(0x00);        // Sekunden Register Adresse
            rtc_start();            // Repeated Start
            rtc_write(rtc_adr_r);   // Sende Leseadresse
            sec = rtc_read();        // Wert Register 0 lesen = RTC Sekunde
            rtc_stop();
            
            if (sec != last_sec)
              {
                last_sec = sec;
                PORTB ^= 0x01;   // Toggle Bit 0
              }
                _delay_ms(100);
        }
    }
    Mit was läuft eigentlich Dein ATM16? Tatsächlich mit 1,6MHz? Kann ich mir nicht vorstellen. Dann stimmt Dein delay_ms nicht.

  6. #16
    Erfahrener Benutzer Roboter Genie Avatar von oderlachs
    Registriert seit
    17.05.2010
    Ort
    Oderberg
    Alter
    74
    Beiträge
    1.175
    Blog-Einträge
    1
    Hallo Magic !

    Danke für Deine Ausführungen und vorallem Deine Geduld !!! 1,6Mz ich denke doch das sind 16MHz oder habe ich eine Null zu wenig ? Dann dürfte ja gar nix gehen.Sorry das ist mir beim kopieren passiert da habe ich die orginal 1MHz falsch überschrieben, in der AVRStudio Datei sind aber 16.000.000 UL (ohne Pkte).
    Ja ich habe selber schon gemerkt das da Fehkler sind, weil der Compiler auch streikt, bzw Fehler ausgibt.
    Ich versuche ja selber mit Datenblatt und ATMega-Fachbuch(?) diese auszumerzen. Das ich in den Webseiten mal was falsch verstehe das es nicht geht anstatt zu funktionieren, liegt an meinem schlechten English. Habe aber ne Menge gelernt dabei , aus Fehlern lernt man eben.
    Leider habe ich bislang noch kein als richtig funktionierendes ausgezeichnetes Beispiel in GCC gefunden . In Bascom und Arduino gibt es sie wie Sand am Meer.
    Morgen werde ich das beisspiel von Dir mal testen, heute glüht einwenig der Kopf schon.

    Danke nochmals

    Gerhard

    Nachtrag : das Progbeispiel von Dir bleibt in der While Schleife stecken bis ich rtc_stop() auskommentiere.
    Geändert von oderlachs (16.06.2013 um 21:45 Uhr)
    Arduinos, STK-500(AVR), EasyPIC-40, PICKIT 3 & MPLABX-IDE , Linux Mint

  7. #17
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    01.10.2009
    Beiträge
    437
    Zitat Zitat von oderlachs Beitrag anzeigen
    1,6Mz ich denke doch das sind 16MHz oder habe ich eine Null zu wenig ?
    Code:
    #define F_CPU 1600000UL
    Ich zähl' 5 Nullen.
    Dann dürfte ja gar nix gehen.
    Das hat nur Einfluss auf die delay_ms, die läuft dann 10x zu schnell, das hat aber keinen wesentlichen Einfluss auf den Rest.
    in der AVRStudio Datei sind aber 16.000.000 UL (ohne Pkte).
    Auch da gibt's 'nen Fallstrick, es kann sein, dass das AVR-Studio beim Compilieren nur den in den Projekteinstellungen angegebenen Wert verwendet.
    Ja ich habe selber schon gemerkt das da Fehkler sind, weil der Compiler auch streikt, bzw Fehler ausgibt.
    Die Fehler, welche der verlinkte TE eingebaut hat, sind inhaltlicher Natur und keine Syntaxfehler.
    Du könntest aus dem Bascom-Code lernen, denn im Beispiel der DS1307 wird die Abfolge der I2C-Befehle richtig gemacht.
    Leider habe ich bislang noch kein als richtig funktionierendes ausgezeichnetes Beispiel in GCC gefunden . In Bascom und Arduino gibt es sie wie Sand am Meer.
    Diese Lib hier von Peter Fleury ist eigenartigerweise wenig, bzw. schlecht zu finden:
    http://www.kvetakov.net/clanky/File/AVR/twi_lib.c
    http://www.kvetakov.net/clanky/File/AVR/twi_lib.h

    Damit kannst Du den Ablauf des Bascom-Codes nachbilden, dann dürftest Du ziemlich sicher Erfolg haben.
    K.A. warum die obige Lib selten ist, vielleicht weil die I2C-Funktionen nach Datenblatt recht einfach zu bauen sind, bzw. der AVR GCC rudimentäre Unterstützung über \avr\include\util\twi.h anbietet.
    Siehe auch http://www.nongnu.org/avr-libc/user-...twi__demo.html

    Könnte sei, dass Fleury dann seine komfortableren Funktionen zurückgezogen hat.
    Die Soft-I2C-Funktionen von Peter Fleury sind dagegen gut zu finden, wohl weil nicht GCC-unterstützt und da per Assemblercode ausgeführt, sie nicht von jedem gebaut werden können.
    Geändert von MagicWSmoke (16.06.2013 um 22:12 Uhr)

  8. #18
    Erfahrener Benutzer Roboter Genie Avatar von oderlachs
    Registriert seit
    17.05.2010
    Ort
    Oderberg
    Alter
    74
    Beiträge
    1.175
    Blog-Einträge
    1
    Also ich habe ebend nochmals den Programmcode mittels Datenblatt verglichen , d.h. den Ablauf beim TWI, das ist genau wie im Programm beschrieben da gelistet.
    Ich muss nochmals schauen ob vieleicht was an den Fuses nicht stimmt, aber beim Usart Beispiel klappt aölles wunderbar, sonst würde da auch gewirre zu sehen sein.
    Aber für heute erst mal genug..
    Ich danke Dir nochmals herzlichst!!

    Gerhard
    Arduinos, STK-500(AVR), EasyPIC-40, PICKIT 3 & MPLABX-IDE , Linux Mint

  9. #19
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    01.10.2009
    Beiträge
    437
    Zitat Zitat von oderlachs Beitrag anzeigen
    Also ich habe ebend nochmals den Programmcode mittels Datenblatt verglichen , d.h. den Ablauf beim TWI, das ist genau wie im Programm beschrieben da gelistet.
    Auf welches Programm beziehst Du Dich?
    Die DS1307 nimmt's eigentlich nur übel, wenn der I2C-Takt zu hoch ist, das sollte hier nicht der Fall sein, denn I2C-Clock = CPU clock / (16 + (2 x TWBR x (4^TWPS))) = 16000000 / (16 + 2 x 0x98 x 1) = 50000Hz
    Aber setz' doch mal das TWBR auf 0x48, dann hast Du 100kHz I2C-Clock.

    Solltest Du bei meinem Code mehrere Register nacheinander lesen wollen, so benötigst Du eine weitere Funktion mit ACK, d.h. bei allen in Reihe zu lesenden, bis auf das letzte Register, muss TWEA in TWCR gesetzt sein. Nur eben beim letzten Register aber nicht, darum reicht eben für ein einziges Register: TWCR=(1<<TWINT)|(1<<TWEN);

    Und immer aufpassen, dass Du auch das richtige Hexfile flasht
    Geändert von MagicWSmoke (16.06.2013 um 22:46 Uhr)

  10. #20
    Erfahrener Benutzer Roboter Genie Avatar von oderlachs
    Registriert seit
    17.05.2010
    Ort
    Oderberg
    Alter
    74
    Beiträge
    1.175
    Blog-Einträge
    1
    Ich beziehe mich auf den Beispielcode von Dir, auch eine Erhöhung des I2C Clocks auf 100k ergab nix positives. Na ja nun fordert erst mal die Kirschenernte meine Anwesenheit, mal sehen wann ich wuieder Zeit dafür finde.

    Gruss

    Gerhard
    Arduinos, STK-500(AVR), EasyPIC-40, PICKIT 3 & MPLABX-IDE , Linux Mint

Seite 2 von 3 ErsteErste 123 LetzteLetzte

Ähnliche Themen

  1. [ERLEDIGT] PCA 8574 M-Unit findet zwei I2C-Adressen am China LCD ????
    Von meistervolker im Forum Controller- und Roboterboards von Conrad.de
    Antworten: 3
    Letzter Beitrag: 29.07.2011, 19:21
  2. Cortex M3 Programcounter Adressen
    Von Siro im Forum ARM - 32-bit-Mikrocontroller-Architektur
    Antworten: 2
    Letzter Beitrag: 11.06.2010, 16:39
  3. #define und adressen setzten in asm30 - dspic
    Von Pitt1986 im Forum PIC Controller
    Antworten: 2
    Letzter Beitrag: 10.06.2008, 21:13
  4. Bootloader Adressen
    Von geronet im Forum AVR Hardwarethemen
    Antworten: 1
    Letzter Beitrag: 10.02.2007, 22:27
  5. Adressen im hex file
    Von MAXXX im Forum PIC Controller
    Antworten: 3
    Letzter Beitrag: 21.08.2005, 21:01

Berechtigungen

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

LiFePO4 Speicher Test