Forum: Mikrocontroller und Digitale Elektronik STM32F4 I2C (N)ACK


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Peter L. (pelikan)


Lesenswert?

moin,

folgendes muss ich mit I2C auf einen STM32F4 reasisieren:

Master      Slave

Adddr

      ACK

Steuerung

      ACK

FüllByte

      (N)ACK


Auf NACK kommt ein STOP.
Bei ACK geht es weiter.

Mit dem lesen des Datenregisters wird ja die nächste Datenübertragung 
ausgelöst und die Einstellung von ACK gespeichert.

Ob ACK oder NACK kann aber erst nach auslesen des DR festgestellt 
werden.

Kennt jemand einen Trick, wie ich das DR lesen kann OHNE die nächste 
Datenübertragung auszulösen?

Danke.

VG Peter

von Wastl (hartundweichware)


Lesenswert?

Peter L. schrieb:
> folgendes muss ich mit I2C auf einen STM32F4 reasisieren:

Gib deinen Slave an, am besten gleich mit Datenblatt. Mit
deiner ASCII Flowchart kommen wir nicht weiter.

Peter L. schrieb:
> Kennt jemand einen Trick

Schreib lieber mal in Klartext was du eigentlich erreichen
willst.

von Alexander (alecxs)


Lesenswert?

vielleicht ein HAL_I2C_Stop() hinterher?

von Monk (Gast)


Lesenswert?

Wastl schrieb:
> Schreib lieber mal in Klartext was du eigentlich erreichen
> willst.

Das hat er getan.

Sein Slave soll nach dem Lesen eines empfangenen Bytes entscheiden, ob 
er das mit ACK oder NACK beantworten will. Wer STM32 kennt, der weiß 
dass das dort nicht so einfach geht, weil man das ACK/NACK Flag schon 
vor dem Empfang des betroffenen Bytes festlegen muss.

> Kennt jemand einen Trick, wie ich das DR lesen kann OHNE
> die nächste Datenübertragung auszulösen?

Ich habe das zum Glück so noch nicht gebraucht. In meinem konkreten Fall 
konnte ich einfach ein weiteres (dummy) Byte empfangen und dieses dann 
mit NACK beantworten.

Ich bin gespannt, ob es dafür eine "saubere" Lösung gibt.

von Peter L. (pelikan)


Lesenswert?

moin,

wenns so nicht geht, baut man sich ein eigenes DR.

Dazu auf den SCL einen EXTI Interrupt mit steigender Flanke setzen.

Nach I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED , die Pause zwischen 1.( 
ADDR ) und 2.( 1.Daten-) Byte, wird ein Counter auf 8 gesetzt.

Mit einem DummyRead des DR wird das 2. Byte gestartet.

Nun löst jeder SCL einen INT aus. Dieser rotiert SDA in eine 
Variable...mein DR.

@ Steve
sauber genug?

VG Peter

von Monk (Gast)


Lesenswert?

Ich kann dir nicht folgen. Willst du die I2C Hardware in Software 
nachbilden?

von Peter L. (pelikan)


Lesenswert?

Hi Steve,

im Prinzip ist es die Nachbildung des Lesens in der I2C Unit.

So wie die HW den Datenstrom von SDA per SCL in ein Register 
reinschiebt.

Ich klemme mich auf SDA/SCL und greife die Daten ab. Meine ISR schieb 
SDA in eine Varible mit dem selben Wert wie DR. Somit kann ich vor lesen 
des I2C-DR
schon feststellen was kommt und kann (N)ACK wie gefordert setzen.

Mein Problem ist damit gelöst.

VG Peter

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.