LM75A reagiert nicht, I2C funktioniert

OP #5921772
Lesenswert?

Hallo,

ich bin mal wieder ratlos.

Den I²C nutze ich inzwischen ohne nennenswerte Probleme. Nur der LM75 
will iregndwie nicht.

Es handelt sich um diesen:
https://docs-emea.rs-online.com/webdocs/14e5/0900766b814e5831.pdf

Momentan wird nichts weiter gemacht, als 0x00 über die Adresse 0x90 
(alle Adresspins auf GND) zu senden und dann sollen 2 Bytes über 0x91 
empfangen werden. Aber schon beim Senden reagiert der LM75 nicht. Mir 
ist bewusst, dass ich die 0x00 nicht senden müsste um die Temperatur zu 
lesen.

Ich habe probiert:
- Zwei weitere LM75
- Pinbelegung schon 10x kontrolliert
- Lange und kurze Kabel
- Am gleichen Bus laufen noch andere Geräte ohne Probleme (2 Displays 
und ein Portexpander)
- GY-511 (Gyro) ebenfalls an den gleichen Bus, nur Adressen und Register 
gewechselt, ansonsten identischer Code wie für den LM75 und er 
antwortet.
- Pullup Widerstände (1K und 10K)
- Kondensator laut Datenblatt an die Versorgungspins
- Pegelwandler um von den knappen 2,82 auf 4,2 V zu kommen. Ebenfalls 
mit Pullup und Kondensator
- SDA und SCL getauscht
- Was ich nicht testen kann ist die Geschwindigkeit des I²C Busses 
ändern, weil er sich aufhängt, wenn sich zu viel Arbeit anstaut, die er 
über I²C nicht weg bekommt. Laut Datenblatt 2,5 µs für einen Takt, was 
400 MHz (Fast Mode) entspricht. Diese sind bei mir eingestellt.

Bus ist in Ordnung und Hardware wüsste ich nicht was ich sonst noch 
versuchen soll.

Der Code ist unspektakulär und wie gesagt, funktioniert mit dem Gyro.
1
if(i2c1.useSendewunschFlag(temp1.readDeviceID(),true) == 1 && tempAuswertung == 0) //darf ich?
2
{
3

4
  i2c1.setTxRxSperre(temp1.readDeviceID()); //Sperrt Zugriff auf i2c1, damit dma nicht unterbrochen wird.
5

6
  //funktioniert: Portexpander
7
  //buffer[0] = 0x12;
8
  //HAL_I2C_Master_Transmit_DMA(&hi2c1,0x40,buffer,1);
9

10
  //funktioniert: Gyro
11
  //buffer[0] = 0x28;
12
  //HAL_I2C_Master_Transmit_DMA(&hi2c1,0x32,buffer,1);
13

14
  //funktioniert nicht: LM75
15
  buffer[0] = 0x00;
16
  HAL_I2C_Master_Transmit_DMA(&hi2c1,0x90,buffer,1);
17

18
  tempAuswertung = 20;
19
}
20

21
if (tempAuswertung == 20 && i2c1.readBusyTxFlag() == false) //gesendet?
22
{
23
  //funktioniert: Portexpander
24
  //HAL_I2C_Master_Receive_DMA(&hi2c1,0x41,RxBuffer,2); 
25

26
  //funktioniert: Gyro
27
  //HAL_I2C_Master_Receive_DMA(&hi2c1,0x33,RxBuffer,2); 
28

29
  //funktioniert nicht: LM75
30
  HAL_I2C_Master_Receive_DMA(&hi2c1,0x91,RxBuffer,2);
31

32
  tempAuswertung = 30;
33
}
34

35
if (tempAuswertung == 30 && i2c1.readBusyRxFlag() == false) //empfangen?
36
{
37
  i2c1.resetTxRxSperre(); //Gibt Zugriff wieder frei
38
  temperatur[0] = RxBuffer[0];
39
  temperatur[1] = RxBuffer[1];
40
  tempAuswertung = 0;
41
}
Gast #5921788
Lesenswert?

Welchen Wert liefert HAL_I2C_Master_Transmit_DMA(&hi2c1,0x90,buffer,1) 
zurück?

Oder: Antwortet der Sensor nach der Adresse mit einem ACK? Antwrotet er 
nach dem einen Byte mit einem ACK? Das kannst du mit einem Logic 
Analyzer oder Oszilloskop prüfen.
OP #5921886
Lesenswert?

@Stefanus:

Hätte ich vielleicht noch schreiben sollen. Nach erfolgreicher 
Kommunikation springt er in eine dieser beiden Funktionen. Macht er aber 
nicht. Als wenn unter der Adresse niemand anzutreffen ist.
1
void HAL_I2C_MasterTxCpltCallback(I2C_HandleTypeDef *hi2c1)
2
{
3
  i2c1.resetBusyTxFlag();
4
}
5

6
void HAL_I2C_MasterRxCpltCallback(I2C_HandleTypeDef *hi2c1)
7
{
8
  i2c1.resetBusyRxFlag();
9
}

Logic Analyzer und Oszi sind nicht zur Hand.

Wie kann ich das machen mit Wert zurückgeben lassen? Über die Error 
Handler?

@Crazy: Siehe Beschreibung.
Gast #5921908
Lesenswert?

Heinz M. schrieb:
> Wie kann ich das machen mit Wert zurückgeben lassen?

Die Funktionliefer einen Rpckgabewert zurpck, den musst du nur in eine 
Variable speichern und kontrollieren. Die Funktion ist so deklariert:

HAL_StatusTypeDef HAL_I2C_Master_Transmit_DMA(I2C_HandleTypeDef *hi2c, 
uint16_t DevAddress, uint8_t *pData, uint16_t Size);

Wenn die Funktion nicht HAL_OK zurück liefert, kannst du 
HAL_I2C_GetError(I2C_HandleTypeDef *hi2c) aufrufen, um Details zum 
Fehler zu erhalten.

> Logic Analyzer und Oszi sind nicht zur Hand.

Dann kaufe Dir mal ganz schnell wenigstens so einen billigen "8ch Logic 
Analyzer" für 8€, denn Analysieren ist besser als Raten.
#5921942
Lesenswert?

Heinz M. schrieb:
>
>
> void HAL_I2C_MasterRxCpltCallback(I2C_HandleTypeDef *hi2c1)
> {
>   i2c1.resetBusyRxFlag();
> }

ic2c1.resetBusy... ist vollkommen überflüssig, aber dafür fehlt die 
Abfrage, ob der Callback auch wirklich zu deinem i2c-Port gehört.

Ausserdem sollte der i2c-Handle in der Funktion nicht den selben Namen 
haben wie das tatsächlich genutzte (globale) i2c-Handle.

So sollte das aussehen:
1
void HAL_I2C_MasterTxCpltCallback(I2C_HandleTypeDef *hi2c)
2
 {
3
   if(hi2c == &hi2c1)
4
   {
5
       // do something
6
   }
7
 }
OP #5922080
Lesenswert?

@Stefanus:
1
buffer[0] = 0x00;
2
test=HAL_I2C_Master_Transmit_DMA(&hi2c1,0x90,buffer,1);
3
HAL_Delay(30);
4
if (test == 0)
5
  HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13);
Er liefert 0 zurück. Egal ob bei funktionierendem Gyro oder nicht 
funktionierendem LM75. Nur mit dem Unterschied, dass er bei dem Gyro in 
den Callback reinspringt und beim LM75 nicht. Bei Adressen wo definitiv 
nichts dran hängt liefert er auch 0. Sollte er da nicht eine 3 liefern?


@Harry: Danke, da wäre ich wohl später drüber gestolpert. An dem 
resetBusy hängt noch mehr dran, was aber nichts mit dem aktuellen 
Problem mit dem LM75 zu tun hat. Wollte euch nicht zumuten den ganzen 
Code durchzuakkern, da er ja mit den anderen I²C Geräten funktioniert. 
Und bevor ihr noch mehr Fehler findet :-X
OP #5923041
Lesenswert?

"HAL_OK       = 0x00U,
HAL_ERROR    = 0x01U,
HAL_BUSY     = 0x02U,
HAL_TIMEOUT  = 0x03U"

Quelle: 
https://community.st.com/s/question/0D50X00009XkXjvSAF/halstatustypedef

Daher wenn eine Adresse angeschrieben wird, wo kein Gerät antworten 
könnte, müsste eigentlich 3 kommen. Es kommt aber 0. Im Gegensatz dazu 
reagiert er aber richtig, dass er nicht in den Callback springt. 
Vielleicht hab ich auch was bei der Fehlerabfrage falsch, weil er immer 
0 ausspuckt.
OP #5927525
Lesenswert?

Hab die Funktion so eingebaut:
1
test=HAL_I2C_IsDeviceReady(&hi2c1,0x32,1,10);

Dann bleibt er komplett stecken. Mainloop wird nicht weiter ausgeführt. 
Habe es mit dem Portexpander gegengeprüft, der definitiv funktioniert.

Auch wenn ich die Adresspins alle auf High mache und OS offen lassen das 
gleiche.
Gast #5927531
Lesenswert?

Heinz M. schrieb:
> Dann bleibt er komplett stecken

Messe mal die Pegel an den Leitungen SCL und SDA in diesem hängenden 
Zustand. Wenn eine der beiden Leitungen auf Low hängt, trenne den Sensor 
im laufenden Betrieb ab. Bleibt sie dann immer noch auf Low?

Auf diese Weise findest du heraus, ob der Sensor oder der 
Mikrocontroller hängt.

Pull-Up Widerstände sind noch vorhanden, hoffe ich ?!?
OP #5927567
Lesenswert?

Aktuell sieht es so aus.

µC
|
- 1 kOhm Pull-Up
|
- Portexpander (funktioniert)
- Display1 (funktioniert)
- Display2 (funktioniert)
|
Levelshifter TXB0104
|
- 1 kOhm Pull-Up
|
- LM75

Auf LM75 Seite:
4,26 V VCC
1,75 V bzw. 1,74 V wenn er hängt
0,67 V wenn ich die Datenleitung abziehe
µC hört auf zu senden (mit LEDs an Leitung getestet)

Wenn ich mein normales Programm nehme, dann arbeitet der µC ganz normal 
weiter. (ohne den Levelshifter -> Pegel high)

Mit dem IsDeviceReady bleibt er jedoch stehen. (Ohne den Levelshifter -> 
Pegel low)
Gast #5927578
Lesenswert?

Heinz M. schrieb:
> 1,75 V bzw. 1,74 V wenn er hängt
> 0,67 V wenn ich die Datenleitung abziehe

Das sind beide unerwartete Werte.

Im Ruhezustand sollen beide Leitungen High Pegel haben. Ich denke, du 
solltest da weiter forschen, am Besten mit einem Oszilloskop. ielleicht 
passen die recht niederohmigen Pull-Up Widerstände nicht oder der 
Pegelwandler funktioniert nicht.

Warum betreibst du den LM75 nicht einfach mit 3,3V und ohne 
Pegelwandler? Ich würde das wenigstens mal ausprobieren, um Probleme 
durch den Pegelwandler auszuschließen.
OP #5927642
Lesenswert?

Diese LM 75 sind mit 2,8 bis 5,5 V spezifiziert. Das Discovery Board, 
welches ich als Programmer nehme liefert ~2,91 V.

Über 10 cm 0,75 mm² kommen auf dem Breadboard nur noch 2,78 V an.

Daher der Versuch mit dem Pegelwandler.

Ohne Pegelwandler sind es 2,53 V bzw. 2,62 V wenn er bei dem 
IsDeviceReady hängen bleibt.

Wechsle ich auf HAL_I2C_Master_Transmit_DMA sind es 0,37 V (SCL) und 
2,85 V. VCC ist in dem Fall auf 2,82 V angestiegen.

Edit: Displays und Portexpander funktionieren auch "ohne" Pull-Up. Ich 
vermute auf den Display Baords sind schon welche drauf. Beim LM75 habe 
ich mit denen von den Displays, als auch die separaten 1k versucht.
Gast #5927705
Lesenswert?

Heinz M. schrieb:
> Wechsle ich auf HAL_I2C_Master_Transmit_DMA sind es 0,37 V (SCL) und
> 2,85 V. VCC ist in dem Fall auf 2,82 V angestiegen.

Messungen am I²C Bus mit dem Multimeter müssten im Ruhezustand fast VCC 
(höchstens 0,1V darunter) und im Fehlerfall wenn ein Gerät hängt fast 0V 
(maximal 0,1V) ergeben. Deine Messwerte deuten für mich auf eine 
Hardwareproblem hin, dass du wie gesagt mit einem Oszilloskop weiter 
untersuche kannst.

Alternativ kannst du ein Testprogramm schreiben, dass die beiden Pins im 
10 Sekunden Takt (im Open-Drain Modus!) auf High/Low umschaltet und dann 
man die Pegel Messen.

Und den LM75 kannst du durch Taster (nach GND hin) ersetzen und dann man 
die Spannungen vor und hinter dem Pegelwandler messen (bei High und 
Low).

Möglicherweise fließen da zu hohe Ströme: Kann man auch messen.
#5927819
Lesenswert?

Heinz M. schrieb:
> Hab die Funktion so
> eingebaut:test=HAL_I2C_IsDeviceReady(&hi2c1,0x32,1,10);
>
> Dann bleibt er komplett stecken. Mainloop wird nicht weiter ausgeführt.

Den aktuellen Status bekommst du mit:
1
Result = HAL_I2C_GetState(&hi2c);

Wenn alles gut gegangen ist, enthält Result:

HAL_I2C_STATE_READY

Andere mögliche Stati findest du in der Doku.
Gast #5927827
Lesenswert?

Heinz M. schrieb:
> Momentan wird nichts weiter gemacht, als 0x00 über die Adresse 0x90
> (alle Adresspins auf GND) zu senden und dann sollen 2 Bytes über 0x91
> empfangen werden. Aber schon beim Senden reagiert der LM75 nicht.

Bist du sicher, dass deine I2C-Receive und -Transmit Funktionen nicht 
die I2C-Adresse entsprechend Tab. 4 im Datenblatt erwarten?

Evtl. hast du mit der dort für A0..2=0 angegeben Adresse 0x48 mehr 
Glück. Sonst lasse einfach mal einen I2C-Scanner den gesamten 7-Bit 
Adressraum absuchen.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren