- Labornetzteil AliExpress         
Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 16

Thema: Suche Programmbeispiel für TWI/I2C Bus in Assembler

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    16.01.2010
    Beiträge
    17

    Suche Programmbeispiel für TWI/I2C Bus in Assembler

    Anzeige

    LiFePo4 Akku selber bauen - Video
    Moin, ich bin noch relativ neu in der Mikrocontroller-Welt und benötige mal etwas Hilfe.

    Hab ein mega32 uc und wollte mit diesem über ein I2C Bus mit einem PCF8574 kommunizieren lassen. Hab die ganze Prozedur mit dem Busverkehr verstanden doch irgendwie bekomme ich das ganze nicht zum laufen.

    1.Wollte fragen ob nicht jemand mal ein Fertiges I2C Programm in Assembler hat bei dem ich mal reinschauen kann was ich anders mache?

    2.Der PCF hat die Hex Adresse 72. Das ganze sind ja nu 7 Bit. Und das letzte Bit soll ja so weit ich es verstanden habe das Read/Write Bit sein. Wenn ich jetzt schreiben möchte muss ich doch noch ne Null an die Adresse ranhängen so das das komplette Byte zum verschicken im TWDR dann 0xE4 (bzw 11100100) sein müsste. Oder etwa nicht?

    Wäre super wenn Ihr mir da weiter helfen könntet.

  2. #2
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    10.02.2005
    Ort
    eastside, L.E.
    Alter
    53
    Beiträge
    104
    Hi,

    wenn Du die Adresse als 0x72 angibst ist bit 0 schon das R/W-bit.

    0x72 gehört laut Datenblatt zum PCF8574A, paßt das?

    Rajko

  3. #3
    Neuer Benutzer Öfters hier
    Registriert seit
    16.01.2010
    Beiträge
    17
    Es ist ein PCF8574AP. Habe A0 auf 5V und A1 und A2 auf GND.

    Die SDA und SCL liegen ja auf Port C (PC0, PCC1). Müssen diese Ports noch auf In- oder Output gestellt werden?

    Ich initialisiere die Startsequenz (TWINT, TWSTA und TWEN bekommen ein "1" signal) danach kommt die erste "wait" Schleife in der gewartet wird bis TWINT ausgelöst wird. Da hängt das Programm dann in einer Endlosschleife, weil TWINT nicht von der Hardware auf 1 gesetzt wird. Woran kann es liegen das das Interrupt-Flag nicht ausgelöst wird?


    Wie sollte ich die Bus-Frequenz wählen für meinen PCF? 100kHz gewählt. Das ganze habe ich vor der Startsequenz in TWBR geschrieben (0x4.

  4. #4
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    10.02.2005
    Ort
    eastside, L.E.
    Alter
    53
    Beiträge
    104
    Wenn noch nicht mal der Start-Zustand erreicht wird kann das fast nur schaltungstechnische Gründe haben. Hast Du die notwendigen Pullup-Widerstände auf den zwei Leitungen? Führen beide Leitungen H-Pegel bevor Du den TWI startest?

    Die Ports selber mußt Du normal nicht anfassen, die werden durch TWEN auf TWI umgeschaltet. Es gibt den Hinweis, daß man die Ports auf Eingang mit aktiviertem internen Pullup stellen kann, um sich unter Umständen die externen Pullups sparen zu können. Bei 100kHz sind die internen Pullups aber gefühlsmäßig zu hochohmig, je nach Länge und Kapazität des Busses.

    Rajko

  5. #5
    Neuer Benutzer Öfters hier
    Registriert seit
    16.01.2010
    Beiträge
    17
    Tausend dank. Funktioniert super.

    Hatte das Kapitel mit den Pull-ups ehrlich gesagt völlig übersprungen, weil ich mich auf die Pull-up Widerstände im uC verlassen wollte. Das waren ja glaub ich so 10k. Hab das ganze jetzt mal mit 4,7k probiert und es läuft. Bin echt super erleichtert. Das mit der Bus-Kapazität habe ich auch schon mal irgendwo gelesen doch wenn es jetzt funktioniert wahrscheinlich übertrieben Hirnschmalz in die Berechnung der Kapazität zu legen.

    Von meiner Seite nochmal vielen Dank. Damit kann nun ich wieder ruhig schlafen.

    Zwei Fragen wären da aber noch von meiner Seite.

    1. Ich wollte für mein Projekt mehrere PCFs benutzen und ein Mega32 aus Master. Wenn ich nun die Kommunikation mit einem PCF eingeleitet habe und ich möchte mitten in meinem Programm einen anderen PCF ansprechen muss ich doch nicht jedesmal den BUS Stoppen und neu initialisieren oder? Reicht es nicht wenn ich ab dem Step mit dem Senden der Slaveadresse weitermache.

    2. Hab beim PCF die Funktion des Interrupt Aus- oder Eingangs nicht so ganz verstanden? Wann und wozu ich diesen überhaupt benötige? Dient der als eine art Erweiterung der uC Eingänge meines Mega`s?

  6. #6
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    10.02.2005
    Ort
    eastside, L.E.
    Alter
    53
    Beiträge
    104
    1. jein... Um einen neuen Slave anzusprechen ist es am saubersten, wenn Du einen Stop-Befehl absetzt und dann mit einem Start weitermachst. Du kannst aber auch ohne vorheriges Stop einen sogenannten "repeated Start" machen, das mußt Du aber dann in der Auswertung des Statusbytes berücksichtigen, es wird dann als 0x10 statt 0x08 gemeldet.

    Die komplette Initialisierung mußt Du nicht jedes Mal wiederholen.

    2. Den /INT-Ausgang des PCF kannst Du auf einen (INT-)Eingang des mega32 verdrahten um Dir signalisieren zu lassen, daß sich ein Eingang am PCF verändert hat. Dann kannst Du das auslesen ereignisgesteuert machen, sonst mußt Du halt bei Bedarf oder zyklisch pollen.

    Rajko

  7. #7
    Neuer Benutzer Öfters hier
    Registriert seit
    16.01.2010
    Beiträge
    17
    Ich habe bisher ja immer den Master Transmitter Mode benutzt und den PCF als Ausgang verwendet.
    Jetzt wollte ich die ganze Sache umdrehen und den Master Receiver Mode benutzten wobei mit der PCF als Eingang dient. Leider bekomme ich das noch nicht so wirklich hin.

    Habe die Startsequenz eingeleitet und die Adresse des PCF angesprochen. Bis dahin funktioniert alles. Bei der Statusabfrage nach dem senden der Adresse soll ich ja jetzt nicht mehr $18 sondern $40 benutzten. Und da hakt dann auch die ganze Sache.

    1. Wie bekomme ich die Statusbits auf $40?
    2. Wie kann ich dann die Daten vom Slave zum Master übertragen (ins TWDR)? Werden die dann automatisch ins TWDR geschrieben?

    Danke schonmal für die Antwort

  8. #8
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    10.02.2005
    Ort
    eastside, L.E.
    Alter
    53
    Beiträge
    104
    Bit 0 der Adresse hast Du auf 1 gesetzt zum lesen?

    Kannst Du Dir den anliegenden Statuscode anzeigen lassen, zur Not provisorisch binär per paar Led's an freien Ports?

    Oder poste mal Deinen Code.

    Wenn alles richtig läuft landen die Daten des Slaves automatisch im TWDR, ja.

    Rajko

  9. #9
    Neuer Benutzer Öfters hier
    Registriert seit
    16.01.2010
    Beiträge
    17
    Initialisierung läuft jetzt. $40 steht jetzt im Statusregister und ich wollte jetzt anfangen Daten vom TWDR zu lesen. Hab die Textpassage in der Doku zum Mega 32 nur nicht so richtig verstanden.

    "Received data can be read from the TWDR Register when the TWINT Flag
    is set high by hardware. This scheme is repeated until the last byte has been received. After the last byte has been received, the MR should inform the ST by sending a NACK after the last received data byte."

    Soll ich nach dem der Status ($40) erkannt wurde nochmal auf das TWINT Flag warten und dann einfach mit "in r16, TWDR" die Daten aus dem Datenregitster holen?

    So würde ich mir das ganze jetzt nach dem lesen des Manuals vorstellen.
    (beginnt da dem Punkt wo die Adresse erfolgreich gesendet wurde)

    in r16, TWSR
    andi r16, 0xF8
    cpi r16, 0x40
    brne error

    rcall wait ;warten auf TWINT Flag

    in r20, TWDR ;einlesen der Daten in r20
    ldi r16, (1<<TWINT)
    out TWCR, r16 ;senden eines NACK`s an den ST

    rcall wait ;warten auf TWINT Flag

    in r16, TWSR
    andi r16, 0xF8
    cpi r16, 0x50 ;NACK wurde vom ST empfangen
    brne error


    ldi r16, (1<<TWINT)|(1<<TWEN)|(1<<TWSTO)
    out TWCR, r16

    r20 würde dann zur Weiterverarbeitung zur Verfügung stehen.

  10. #10
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    10.02.2005
    Ort
    eastside, L.E.
    Alter
    53
    Beiträge
    104
    Na das sieht doch schon gut aus.

    Nachdem du Status 0x40 erhalten hast mußt Du nur auch wieder das TWINT auf 1 setzen, damit es weiter geht.

    Wenn Du die einzelne Kommunikation nur auf das einmalige lesen eines Bytes von diesem PCF beschränken willst, mußt Du dabei gleichzeitig das TWEA auf 0 setzen. Das zeigt dem PCF an, daß dies die letzte Abfrage (in dem Fall die erste und die letzte gleichermaßen) ist.

    Sollen die Daten eines PCF laufend eingelesen werden, um z.B. auf einen Pinwechsel zu warten, setzt Du das TWEA auf 1, dann läßt sich der PCF immer wieder auslesen. Willst Du dann z.B. auf einen anderen PCF wechseln muß das TWEA vor(!) dem letzten empfangenem Byte wieder auf 0 gesetzt werden.

    Nach der 0x40 kehrt sich also die 'Richtung' vom ACK/NACK um, es wird nun vom ATmega erzeugt und zeigt dem PCM an, ob weiterhin ausgelesen wird.

    In dem Zusammenhang sind dann auch die folgenden Statuswerte zu sehen, wenn Du vorher festgelegt hast, daß ein ACK gesendet wird, bekommst Du die 0x50, und mußt anschließend weiter auslesen. Nach Du ein NACK erzeugt hast bekommst Du nach dem nächsten empfangenen Byte die 0x58, erst jetzt darfst Du mit TWSTO die Verbindung beenden.

Seite 1 von 2 12 LetzteLetzte

Berechtigungen

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

Solar Speicher und Akkus Tests