- MultiPlus Wechselrichter Insel und Nulleinspeisung Conrad         
Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 13

Thema: 1. I2C Versuch - 24C02 sendet kein ACK

  1. #1
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    27.08.2007
    Alter
    34
    Beiträge
    324

    1. I2C Versuch - 24C02 sendet kein ACK

    Anzeige

    Praxistest und DIY Projekte
    Nach längerem hin und her habe ich mich entschieden, das es an der Zeit ist mich mal mit I2C zu befassen und weil ich das Protokoll / den Bus auch verstehen möchte, will ich dies zunächst ohne zusätzliche Bibliotheken ausprobieren. Ich habe im m8 Datenblatt die TWI Kapitel (die Grundlagen) gelesen und daraus folgenden Programmcode erstellt, der eine Verbindung mit einem 24C02 herstellen soll - bis zum ersten ACK des Speichers - dieses kommt jedoch nicht und ich weiss nicht warum.
    Mein 24C02 ist wie folgt mit meinem Mega8 verbunden

    <pre>GND-|°-- |-VCC
    GND-| |-nix
    GND-| |-SCK
    GND-|----|-SDA</pre>

    Folglich müsste die 7bit Adresse des Speichers doch 1010000 sein und das erste zu sendende Byte 10100000 bzw 0xA0 sein. Ein gelungener Schritt wird durch ein Blinken an PB0 signalisiert.
    Code:
    #include <avr/io.h>
    #include <util/delay.h>
    #define START 0x08
    #define SLAVE_OK 0x18
    #define F_CPU 8000000UL
    
    void blink(){
        _delay_ms(300);
        PORTB |= (1<<PB0);
        _delay_ms(300);
        PORTB = 0;
    }
    
    int main(void)
    {
    
        DDRB = 0xFF;
        PORTB = 0;
    
        TWBR = 0x20;
        TWCR = (1<<TWINT);
        TWCR |= (1<<TWSTA);
        TWCR |= (1<<TWEN);
    
        while (bit_is_clear(TWCR, TWINT)){
        };
    
        blink();
    
        if ((TWSR & 0xF8) == START){
            blink();
        }
    
        TWDR = 0xA0;
        TWCR = (1<<TWINT) | (1<<TWEN);
    
        while (bit_is_clear(TWCR, TWINT)){
        };
        blink();
    
        if ((TWSR & 0xF8) != SLAVE_OK){
            blink();
        }
        else {
            blink();
            blink();
        }
    
    //hier ginge es dann mit den Daten weiter
    
    }
    4xBlinken müsste bedeuten, dass alles richtig ist, 5 mal, das kein Ack vom Slave eingegangen ist. Dies ist bei mir immer der Fall und ich kann es mir nicht erklären. Die Adressierung müsste mit 10100000 doch richtig sein für die genannte Beschaltung.

    Vielen dank für eure Hilfe[/code]

  2. #2
    Erfahrener Benutzer Robotik Einstein Avatar von Jaecko
    Registriert seit
    16.10.2006
    Ort
    Lkr. Rottal/Inn
    Alter
    41
    Beiträge
    2.009
    Wie sieht denn die restliche Beschaltung aus? Ist an SCL/SDA jeweils ein Pullup nach 5V? Wird gern mal vergessen (passiert auch mir immer wieder)
    Von der Adresse her schaut 0xA0 aber richtig aus.
    #ifndef MfG
    #define MfG

  3. #3
    Erfahrener Benutzer Robotik Einstein Avatar von Jaecko
    Registriert seit
    16.10.2006
    Ort
    Lkr. Rottal/Inn
    Alter
    41
    Beiträge
    2.009
    [Doppelpost durch Browserfehler]
    #ifndef MfG
    #define MfG

  4. #4
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    27.08.2007
    Alter
    34
    Beiträge
    324
    Das ging ja flott! Pullup10k sind (leider) da. Wär zu schön gewesen

    andere Ideen?

  5. #5
    Erfahrener Benutzer Robotik Einstein Avatar von Jaecko
    Registriert seit
    16.10.2006
    Ort
    Lkr. Rottal/Inn
    Alter
    41
    Beiträge
    2.009
    Hm... mist... wär der Klassiker gewesen.

    Was mir grad im Programm selber auffällt: Während einer I2C-Übertragung sollten keine verzögernden Dinge drin sein wie LCD-Ausgaben, UART-Übertragungen oder eben dieses LED-Blinken. Hier vergeht möglicherweise zu viel Zeit, so dass die TWI-Hardware nen Timeout produziert und den Bus wieder freigibt.
    Speicher den Status einfach in ner Variable und werte die aus, wenn STOP gesendet wurde und der Bus wieder frei ist.
    #ifndef MfG
    #define MfG

  6. #6
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    27.08.2007
    Alter
    34
    Beiträge
    324
    Code:
    int main(void)
    {
    
        DDRB = 0xFF;
        PORTB = 0;
    
        TWBR = 0x20;
        TWCR = (1<<TWINT);
        TWCR |= (1<<TWSTA);
        TWCR |= (1<<TWEN);
    
        char temp = 0;
    
        while (bit_is_clear(TWCR, TWINT)){
        };
    
        temp++;
    
        if ((TWSR & 0xF8) == START){
            temp++;
        }
    
        TWDR = 0xA0;
        TWCR = (1<<TWINT) | (1<<TWEN);
    
        while (bit_is_clear(TWCR, TWINT)){
        };
        temp++;
    
        if ((TWSR & 0xF8) != SLAVE_OK){
            temp++;
        }
        else {
            temp+=2;
        }
    
        for (char i = 0; i < temp; i++){
            blink();
        }
        return 0;
    }
    Es blinkt trotzdem 5 mal - also war es wohl kein timeout. Danke trotzdem - wir kriegens schon noch ^^

    edit: muss jetzt leider schlafen gehen

  7. #7
    Erfahrener Benutzer Robotik Einstein Avatar von Jaecko
    Registriert seit
    16.10.2006
    Ort
    Lkr. Rottal/Inn
    Alter
    41
    Beiträge
    2.009
    Also von der Befehlsfolge her siehts eigentlich ziemlich so aus wie bei mir.
    Wo was anders ist, ist die Bus-Initialisierung.

    Hier mal die Funktionen, die ich verwend. Evtl. hilft dir das weiter.
    Code:
    void I2C_Init(ui32_t scl_clock)
    {
      // Initializes the I2C/TWI Hardware as Master
      TWSR = 0;                         // no prescaler
      TWBR = ((F_CPU/scl_clock)-16)/2;  // must be > 10 for stable operation
    }
    
    
    e_errors I2C_Start(ui8_t address)
    {
      ui8_t twst = 0;
      ui8_t retval = ERR_OK;
      
      TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN); 	// send START condition
      while(!(TWCR & (1<<TWINT)));                  // wait until transmission completed
    	twst = TW_STATUS & 0xF8;                      // check value of TWI Status Register. Mask prescaler bits.
    	if ( (twst != TW_START) && (twst != TW_REP_START)) 
      {
        retval = ERR_TWI_NO_START;
      }
    
    	if (retval == ERR_OK)
      {
        // send device address
    	  TWDR = address;
    	  TWCR = (1<<TWINT) | (1<<TWEN);
    
      	// wail until transmission completed and ACK/NACK has been received
      	while(!(TWCR & (1<<TWINT)));
      
      	// check value of TWI Status Register. Mask prescaler bits.
      	twst = TW_STATUS & 0xF8;
      	if ((twst != TW_MT_SLA_ACK) && (twst != TW_MR_SLA_ACK)) 
        {
          retval = ERR_TWI_NO_ACK;
        }
      }
    	return retval;
    }
    
    void I2C_Stop(void)
    {
    	TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO); // send stop condition
    	while(TWCR & (1<<TWSTO));                   // wait until stop condition is executed and bus released 
    }
    Damit sollte zumindest mal ein "Bin da!" des EEPROMs kommen.
    #ifndef MfG
    #define MfG

  8. #8
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    27.08.2007
    Alter
    34
    Beiträge
    324
    damit ich den Code ausprobieren kann bräuchte ich glaube ich deine Header Dateien, oder?

    danke

    ->muss jetzt zur Arbeit

  9. #9
    Erfahrener Benutzer Robotik Einstein Avatar von Jaecko
    Registriert seit
    16.10.2006
    Ort
    Lkr. Rottal/Inn
    Alter
    41
    Beiträge
    2.009
    Nicht unbedingt, aber wär fast sinnvoller.
    Hier mal alle Dateien.
    Angehängte Dateien Angehängte Dateien
    #ifndef MfG
    #define MfG

  10. #10
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    27.08.2007
    Alter
    34
    Beiträge
    324
    Danke!

    Ich hab grad etwas anderes ausprobiert und bin auf einen interessanten Hinweis gestoßen. Offenbar liegt ein Problem mit der Adressierung vor. Wenn ich die Adresse an Chip und im Programm auf 10100100 also 0xA4 ändere bekomme ich das erwünschte ACK. Ich habe im Wiki, sowohl als auch bei Google nach "i2c" AND "10100000" gesucht, aber die Adresse wird nirgendwo als reserviert bezeichnet.

    Jedenfalls kann es jetzt erstmal weiter gehen. Melde mich dann wieder

    edit: warum lösche ich die TWINT Flag indem ich eine 1 reinschreibe? Das bedeutet doch das durch dass die Hardware den Status dann sofort auf null setzten muss... ist doch paradox...

Seite 1 von 2 12 LetzteLetzte

Berechtigungen

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

fchao-Sinus-Wechselrichter AliExpress