- 12V Akku mit 280 Ah bauen         
Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 11

Thema: Amtel atmega 32 als I2C- SLAVE Bus mit 250kBaud im Interrupt Modus

  1. #1
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    07.11.2004
    Beiträge
    332

    Amtel atmega 32 als I2C- SLAVE Bus mit 250kBaud im Interrupt Modus

    Anzeige

    LiFePo4 Akku selber bauen - Video
    Hallo Zusammen,

    hat jemand erfahren mit einem I2C Bus im Fast Modus ?
    Leider sind meine Routinen des Master jetzt mit 250KBaud, statt vorher 100kb.
    Den Kernel mit 100kBaud neu compilieren und wieder einbringen ist nicht ohne.

    Ich habe schon versucht, meine Routine zu optimieren, bekomme aber bei einem längeren Schreibzugriff
    immer wieder sporadische Fehler. Ich verwende bereits Clock-Stretching.

    Da die Interrupt-Routine in C geschrieben ist und der Assembler-Code eigentlich schon recht aussieht,
    wollte ich Euch mal fragen, ob ich hier überhaupt eine Chance habe, das ans rennen zu bekommen.

    Ich verwende einen atmega32 mit 16Mhz

    Würde ein atmega644 mit 20Mhz gehen ?

    Gruss R.
    Kaum macht man es richtig, schon funktioniert's ...

  2. #2
    Benutzer Stammmitglied
    Registriert seit
    26.08.2006
    Beiträge
    84
    Mahlzeit!

    Was für Pullups nimmst du?

    Hm, 250kBaudsind bei 16MHz 64 Takte pro Bit, also rund 512 Takte pro übertragenem Byte.
    In der Zeit sollte sich eigentlich alles wünschenswerte machen lassen

    Gibts auf dem Slave evtl. noch andere Interrupts die dazwischen funken können?

    MfG
    Niels

  3. #3
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    07.11.2004
    Beiträge
    332
    Hi,

    derzeit habe ich 1kOhm Widerstände drin.

    Nun ja, folgende Interrupts kommen noch dazu:

    - Timer für Systemtakt und Zeit (Timer var hochzählen und Flag setzen)
    - Impulstakt je Motor (2) hochzählen
    - Messwert fertig, auswerten (schon was aufwendiger)

    Der Hauptrechner hat aber auch noch andere Teilnehmer zu scannen (4 Stück), also ist es für
    die Motorsteuerung kein Dauerfeuer.

    Gruss R.
    Kaum macht man es richtig, schon funktioniert's ...

  4. #4
    Benutzer Stammmitglied
    Registriert seit
    26.08.2006
    Beiträge
    84
    Zitat Zitat von Ritchie Beitrag anzeigen
    - Messwert fertig, auswerten (schon was aufwendiger)
    Wenn das zu lange dauert kanns das schon sein.
    Für sowas setz ich gerne nur eine Variable in der Int-Routine, prüfe die dann in der Hauptschleife und mach dann die Auswertung von da aus.
    Da bleibt dann genug Zeit, falls doch mal 2 Interrupts zeitlich zusammenfallen.
    Ein sei() am Anfang einer Interrupt-Routine ließe aber auch einen Int für I2C mittendrin zu (nested interrupt)

    Was für Fehler gibts denn überhaupt? Bitfehler? Fehlen ganze Bytes?

    MfG Niels

  5. #5
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    07.11.2004
    Beiträge
    332
    Hi,
    schwer zu sagen, welchen Fehler ich habe, da Linux mir derzeit nur einen result-code -1 zurück gibt.

    Leider streikt auch mein I2C Bus Monitor bei dieser Speed (250k). Der zeigt nur Teile der Übertragung an.
    Der ist mit 100kBaud schon an seiner Grenze und kann auch hier längere Protokolle nicht mehr mitschreiben.

    Ich versuche gerade den Fehler weiter einzugrenzen (c++-linux). Ein einziger Schreibbefehl auf eine Variable scheint kein Problem zu sein. Sende ich mehrere Bytes in einem Rutsch herunter, hat der Kontroller wohl ein Problem.

    Ich habe die Routine auch schon dahin geändert, das ich das AC/NACK wirklich am Ende der Routine sende, damit der Master nicht schon wieder mit der nächsten Datenübertragung beginnt, bevor der Kontroller die Interrupt-Routine verläßt. Viel schneller geht es wirklich nicht.

    Bei Lesen erscheint das Problem nicht derart. Ich vermute evtl. also auch noch einen Bug in meiner Schreib-Routine. Kann Ihn aber derzeit nicht mehr sehen (Amtel Code).

    Derzeit habe ich einen 200Mhz CPU für Linux im Einsatz, die 400Mhz CPU liegt aber schon auf dem Schreibtisch und wartet auf dem Einbau. Ich habe da schon die Vermutung, das das ganze noch schlimmer wird, da hier dann das Abtaster Raster kürzer wird.

    Gruss R.
    Geändert von Ritchie (21.07.2012 um 16:32 Uhr)
    Kaum macht man es richtig, schon funktioniert's ...

  6. #6
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    07.03.2011
    Beiträge
    1.899
    Zitat Zitat von Ritchie Beitrag anzeigen
    Ich verwende bereits Clock-Stretching.
    Das kommt mir merkwürdig vor. Solange der Slave SCL auf low festhält, steht der Bus. Zur Not auch ewig, es gibt keinen Timeout (außer beim SMBus, aber auch der ist lang).

    Ich habe die Routine auch schon dahin geändert, das ich das AC/NACK wirklich am Ende der Routine sende
    Das ACK wird nicht gesendet, der Master gibt auch beim ACK/NACK die Clock vor. Es ist einfach das neunte Bit einer Übertragung.

    Bei den Kontrolern die ich kenne, geht das so: der Kontroler hält beim letzten Takt SCL low und damit den Bus an und löst einen Interrupt aus. Die CPU hat jetzt alle Zeit der Welt, zu reagieren. Ganz zum Schluß wird SCL freigegeben und die Übertragung geht weiter.

    Derzeit habe ich einen 200Mhz CPU für Linux im Einsatz, die 400Mhz CPU liegt aber schon auf dem Schreibtisch und wartet auf dem Einbau. Ich habe da schon die Vermutung, das das ganze noch schlimmer wird, da hier dann das Abtaster Raster kürzer wird.
    Da die Clock beim I2C ein Handshake macht: Master setzt SCL low, Slave erkennt das und setzt auch low, Master läßt los, Slave auch (wenn er soweit ist) darf das kein Problem sein.

    Dein Problem wird auch bei 100kHz da sein, nur seltener auftreten. Du solltest die Abläufe in deinem Code vor allem im Zusammenwirken mit den Steuerbits des Kontrolers noch mal überprüfen.

    MfG Klebwax
    Strom fließt auch durch krumme Drähte !

  7. #7
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    07.11.2004
    Beiträge
    332
    Hallo,

    irgendwie gebe ich Dir ja recht, nur gibt es den irgendwo eine entsprechende Beschreibung, wann welches Signal innerhalb der Interrupt-Routine ausgelöst wird. Die Beschreibung aus der Headerdatei <twi.h> ist nicht wirklich hilfreich oder ?

    Ich weiss zum Beispiel nicht sicher, welchen Anteil der Steuersignal die Hardware des atmega32 durchführt und welche nicht.

    Folgende Signale verarbeitet meine und auch die RN-Wissens Routine eins Slave im Interrupt Mode.
    Code:
    {
        switch (TW_STATUS)                                            //Check the TWI-Status register
            {
            case    TW_REP_START:                                    // Repeated Start bestätigen
                       break
            case    TW_SR_SLA_ACK:                                    // 0x30 Slave Receiver, Slave was addressed
                    break;
            case    TW_SR_DATA_ACK:                                    // 0x80 Slave Receiver, a data byte received
                break;
        case TW_ST_SLA_ACK:                                            //0xA8 Slave addressed in read mode
        case TW_ST_DATA_ACK:                                        //0xB8 Slave Transmitter, Request of data
            break;
    //    case TW_ST_DATA_NACK:                                        // 0xC0 No more data requested
    //    case TW_SR_DATA_NACK:                                        // 0x88
    //    case TW_ST_LAST_DATA:                                        // 0xC8  Last data byte in TWDR has ben transmitted (TWEA = “0”);
    //case TW_SR_STOP:                                                         // 0xA0 STOP empfangen has been received
        default:     
            AcknowlegeFlag=2;
        break;
             break;    
        }
        
    if (AcknowlegeFlag == TRUE )        TWCR_ACK;
    if (AcknowlegeFlag == FALSE )        TWCR_NACK;
    if (AcknowlegeFlag == 2 )            TWCR_RESET;
    }

    Nur werden hier Start / Stop / Repeated Start komplett aussen vorgelassen, diese werden laut diesem Code über den Default geleitet (also Reset ?!).

    Wird diese Routine auch dann ausgeführt, wenn ich mit einem anderen Partner rede ? Die Daten der Adresse werden natürlich mit einem Takt von 250kBaud übertragen. Der atmega kann den Fast Modus, das sollte also nicht das Problem sein.

    Edit1:
    Die Bilder 1 und 2 zeigen jeweils das eigentlich Protokoll, was ich verwende
    Picture 1: Zeigt den Schreibzugriff. Das erste Byte ist hierbei die Adresse, wo die Daten abgelegt werden
    Picture 2: Zeigt den Lesezugriff. Das erste Byte ist hierbei die Adresse, wo die Daten gelesen werden soll. Danach der Repeated Start und der Lesezugriff.
    Hier wäre das Problem, der Repeated Start und die neue Slave-Adresse, dieser ist aber bei Lesen, was ja geht

    Edit2:
    Ich habe den "Repeated Start" noch eingefügt. Hier wird dann mit einem ACK geantwortet.
    Nur habe ich ja nur mit dem Schreiben Probleme, hier wird ja eh nur jedes Byte vom Master mit "ACK" beantwortet.
    Es erfolgt keine Änderung der Datenrichtung (Repeated Start). Dies ist ja doch eigentlich die einfache Richtung.

    Edit3: Hier die Bedingungen, wann das Modul TWI einen Interrupt auswirft.
    Seite 176 vom Atmega32 gab mir die Infos:

    The TWINT Flag is set in the following situations:

    After the TWI has transmitted a START/REPEATED START condition

    After the TWI has transmitted SLA+R/W

    After the TWI has transmitted an address byte

    After the TWI has lost arbitration

    After the TWI has been addressed by own slave address or general call

    After the TWI has received a data byte

    After a STOP or REPEATED START has been received while still addressed as a slave

    When a bus error has occurred due to an illegal START or STOP condition

    Gruss R.
    Miniaturansichten angehängter Grafiken Miniaturansichten angehängter Grafiken Picture2.JPG   Picture1.JPG  
    Geändert von Ritchie (22.07.2012 um 15:27 Uhr) Grund: Zusatzinfos
    Kaum macht man es richtig, schon funktioniert's ...

  8. #8
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    07.03.2011
    Beiträge
    1.899
    Zitat Zitat von Ritchie Beitrag anzeigen
    Nur werden hier Start / Stop / Repeated Start komplett aussen vorgelassen, diese werden laut diesem Code über den Default geleitet (also Reset ?!).

    Wird diese Routine auch dann ausgeführt, wenn ich mit einem anderen Partner rede ?
    Das ist dein Code, das mußt du doch wissen.

    Die Beschreibung aus der Headerdatei <twi.h> ist nicht wirklich hilfreich oder ?
    Der Headerfile hilft dir da wenig, das ist ja nur eine Schreibhilfe. Was du wissen mußt, steht im Datenblatt und in den Application Notes.

    Deine Bilder helfen auch nicht, sie zeigen einen Layer zu hoch. Da kommt das Timing garnicht mehr vor. Selbst wenn auf dieser Ebene alle Bits gleich breit dargestellt sind, heißt das nicht, daß sie gleich lang sind.

    The TWINT Flag is set in the following situations:

    After the TWI has transmitted a START/REPEATED START condition

    After the TWI has transmitted SLA+R/W

    After the TWI has transmitted an address byte

    After the TWI has lost arbitration

    After the TWI has been addressed by own slave address or general call

    After the TWI has received a data byte

    After a STOP or REPEATED START has been received while still addressed as a slave

    When a bus error has occurred due to an illegal START or STOP condition
    Als Slave sind für dich nur die letzten 4 von Bedeutung. Wichtiger sind aber die Bits, mit der der Kontroler gesteuert wird und ihre genaue Wirkung.

    Bau dir eine Testumgebung auf und teste mit Hilfe von Debugger und LA oder Speicherscope deinen Code, bis du genau weißt, was wann und warum passiert.

    MfG Klebwax
    Strom fließt auch durch krumme Drähte !

  9. #9
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    07.11.2004
    Beiträge
    332
    Hallo Zusammen,

    ich habe nochmals ein kleines Dokument erstellt, welches die Datenübertragung entsprechend verdeutlichen soll.

    siehe Anhang "I2CProtokoll.doc". Es soll die Ereignisse anzeigen und deren Aktionen.

    Nur wenn die Routine ein "TW_START" oder "TW_REP_START" empfangen wird, soll weder ein ACK/NAK gesendet werden.
    Aber wenn ich das Flag

    TWCR = (1<<TWEN)|(1<<TWIE)|(1<<TWINT)|(1<<TWEA)|(0<<TWSTA )|(1<<TWSTO)|(0<<TWWC);

    Setze ich gleichzeiti ein ACK/NACK oder sehe ich das falsch.

    Da ich derzeit kein Speicherscope zur Verfügung habe, habe ich hier ein Problem.

    Edit 1:
    Versuche mir ein Speicherscope zu besorgen.

    Gruss R.
    Angehängte Dateien Angehängte Dateien
    Kaum macht man es richtig, schon funktioniert's ...

  10. #10
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    07.03.2011
    Beiträge
    1.899
    Erst mal zu deinem Text:

    Wenn du ein Adressbyte bekommen hat, muß mit ACK geantwortet werden. Ob der Kontroler das bei der eingestellten Adresse selbsttätig macht, sagt dir das Datenblatt.

    Alles was ab jetzt passiert, liegt in deiner eigenen Verantwortung. Es gibt da bei I2C keine Vorgaben, das Protokoll auf dieser Ebene bestimmst du selbst. Gerne wird es so gemacht, wie bei den ersten EEPRoms. Da ist das erste Byte eines Writes die Datenadresse, die nachfolgenden werden dann ab dieser Adresse geschrieben, wobei gleichzeitig die Adresse erhöht wird. Wieviele Bytes geschrieben werden, ist unbestimmt. Wenn der Slave nicht mehr will, antwortet er mit NACK, wenn der Master nichts mehr zu sagen hat, löst er ein STOP aus.

    Das ganze hat aber mit dem Timing nichts zu tun. Da gehts im wesentlichen um die SCL Leitung, die bestimmt das Timing.

    MfG Klebwax
    Strom fließt auch durch krumme Drähte !

Seite 1 von 2 12 LetzteLetzte

Ähnliche Themen

  1. Atmega in MPCP Modus
    Von demmy im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 4
    Letzter Beitrag: 07.05.2012, 08:23
  2. Antworten: 3
    Letzter Beitrag: 06.11.2010, 18:54
  3. Interrupt beim I2C Slave
    Von guenter1604 im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 3
    Letzter Beitrag: 07.12.2009, 18:59
  4. Interrupt bei TWI Slave (Atmega8)?
    Von ingo pirker im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 2
    Letzter Beitrag: 20.11.2009, 22:36
  5. I2C Slave Interrupt
    Von simple im Forum C - Programmierung (GCC u.a.)
    Antworten: 1
    Letzter Beitrag: 29.11.2006, 17:53

Berechtigungen

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

12V Akku bauen