Forum: Mikrocontroller und Digitale Elektronik STM32F103 an ADXL345 - keine Reaktion auf I2C


von Christian J. (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

ist hier wohl meine letzte Hoffnung, ich finde es jedenfalls nicht raus 
:-(

An einem Blue Pill Board hängt ein ADXL345 Gyro Sensot mir I2C. CS an 
VCC.
Spielt an einem Arduino auch einwandfrei aber STM32 ist nunmal etwas 
mehr Aufwand.

Zunächst: Genau 2 Mal hatte ich auf dem Datalogger (China Teil) die 
richtige I2C Sequenz und dann nie wieder! 10 Versuche, nichts. Plötzlich 
klappte es und dann nicht merh. Testweise 0x50 in OFFX eingeschrieben 
und wieder ausgelesen.... und es kam wirklich hin! 2 Mal und dann war 
Schluss.
Inzwischen habe ich Blue Pill und ADXL ausgetauscht, immer das Gleiche. 
Lötungen natürlich auch kontrolliert, Spannungen usw.  usw.

Was ich noch sehe ist die Write Adressierung nach dem Start und dann 
läuft er in den Timeout rein bei

if (!i2c_address_direction(DEV_ID_WRITE,I2C_Direction_Transmitter))
        return ERROR;

I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED kommt nicht, da wartet er 
sich tot.

Reagiert also gar nicht. Da es 2 Mal geklappt hat muss also etwas 
richtig sein.

#define DEV_ID_WRITE     0x3A
#define DEV_ID_READ      0x3B

Habe ich da vielleicht irgendwas übersehen? Die Pull Ups sind auf diesen 
blauen Boards mit drauf, die man in der Bucht kriegt. Am Arduino spielen 
die auch sofort... naja, andere Welt eben.

Aufgefallen ist mir nur das ACK und das NAK als Unterschied von Logger 
zu Datenblatt aber das kann ich ja nicht beeinflussen beim Write 
Vorgang, nur beim Read.

I2cstart() spuckt nie ERROR aus, egal ob die Kabel dran sind oder ab am 
Slave. Kann man also als void deklarieren.
1
/* Beschreibe ein ADXL345 Register mit einem 8 Bit Wert */
2
ErrorStatus adxl_writeRegister(uint8_t address, uint8_t value)
3
{
4
    /* Start Condition senden */
5
6
    if (!i2c_start())
7
        return ERROR;
8
    /* Den Chip adressieren */
9
    if (!i2c_address_direction(DEV_ID_WRITE,I2C_Direction_Transmitter))
10
        return ERROR;
11
    /* Zieladresse anwählen */
12
    if (!i2c_write(address))
13
        return ERROR;
14
    /* Datum einschreiben */
15
    if (!i2c_write(value))
16
        return ERROR;
17
    i2c_stop();
18
19
    return SUCCESS;
20
}
1
/* ----- Erzeuge Start Bedingung ------ */
2
static ErrorStatus i2c_start()
3
{
4
   int timeout = I2C_TIMEOUT;
5
6
   I2C_GenerateSTART(I2Cx, ENABLE);
7
   /* Warte auf I2C EV5. Bus frei, Start akzeptiert */
8
   while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT))
9
   {
10
       if (!(--timeout)) {
11
            return ERROR;
12
       }
13
   }
14
   return SUCCESS;
15
}
16
17
/* --------- Erzeuge Stop Bedingung ------- */
18
static void i2c_stop()
19
{
20
    I2C_GenerateSTOP(I2Cx, ENABLE);
21
}
22
23
/* ---------- Adressiere den Slave --------
24
   Write: I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED
25
   Read:  I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED
26
*/
27
static ErrorStatus i2c_address_direction(uint8_t address, uint8_t direction)
28
{
29
    unsigned int timeout = I2C_TIMEOUT;
30
31
    /* Adressiere den Slave mit Datenrichtung */
32
    I2C_Send7bitAddress(I2Cx, address, direction);
33
    /* Warte auf I2C EV6, Slave hat seine Adressierung akzeptiert */
34
    if (direction == I2C_Direction_Transmitter)  {
35
        while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) {
36
            if (!(--timeout)) {
37
               return ERROR;
38
            }
39
        }
40
    }
41
    if (direction == I2C_Direction_Receiver)  {
42
        while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)) {
43
            if (!(--timeout)) {
44
               return ERROR;
45
            }
46
        }
47
    }
48
49
    return SUCCESS;
50
}
51
52
/* ------- Uebertrage 1 Byte an Slave ----- */
53
static ErrorStatus i2c_write(uint8_t byte)
54
{
55
    unsigned int timeout = I2C_TIMEOUT;
56
57
    I2C_SendData(I2Cx, byte);
58
    /* Warte auf Ev8_2, Datum wurde heraus geschoben */
59
    while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED))   {
60
        if (!(--timeout)) {
61
            return ERROR;
62
       }
63
    }
64
    return SUCCESS;
65
}
66
67
// ---------------------------------------------------------------
68
// Initialisiere den I2C Bus
69
// ---------------------------------------------------------------
70
void I2C1_Init()
71
{
72
    GPIO_InitTypeDef GPIO_InitStruct;       // Port Init Struct
73
    I2C_InitTypeDef I2C_InitStruct;         // I2C Init Struct
74
75
    I2C_Disable();
76
77
    // Peripherie Takt einschalten I2C3: PB6 (I2C1 SCL) und PB7 (I2C1_SDA)
78
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
79
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
80
81
    // Port mit SCL/SCA einrichten
82
    GPIO_InitStruct.GPIO_Pin   = I2C_SCL_PIN | I2C_SDA_PIN;
83
    GPIO_InitStruct.GPIO_Mode  = GPIO_Mode_AF_OD;            // Pins als Alternate Function einstellen
84
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_10MHz;           // IO Speed, nicht Baudrate, 2 Mhz reicht
85
86
    GPIO_Init(I2C_SCL_PORT, &GPIO_InitStruct);
87
88
    // Struktur Parameter fuer I2C setzen
89
    I2C_StructInit(&I2C_InitStruct);                                        // Rücksetzen auf Default
90
    I2C_InitStruct.I2C_ClockSpeed           = I2C_SPEED;                    // 100 khz Busfrequenz
91
    I2C_InitStruct.I2C_Mode                 = I2C_Mode_I2C;                 // Normaler I2C Mode
92
    I2C_InitStruct.I2C_DutyCycle            = I2C_DutyCycle_2;              // 50:50 Duty Cycle
93
    I2C_InitStruct.I2C_OwnAddress1          = 0x00;                         // Dummy Adresse
94
    I2C_InitStruct.I2C_Ack                  = I2C_Ack_Enable;               // ACK senden
95
    I2C_InitStruct.I2C_AcknowledgedAddress  = I2C_AcknowledgedAddress_7bit; // 7 Bit Adressierung
96
97
    // I2C3 mit den obigen Parametern konfigurieren
98
    I2C_Init(I2Cx, &I2C_InitStruct);
99
100
    // I2C einschalten
101
    I2C_Cmd(I2Cx, ENABLE);
102
}

von au weia (Gast)


Lesenswert?

Christian J. schrieb:
> Habe ich da vielleicht irgendwas übersehen?

Zunächst mal den Hinweis dass längere Sourcen als Anhang
gepostet werden sollen und nicht im Beitrags-Text.

Immer wieder die gleichen Typen, voll drauf und ohne Rücksicht!
Nach dem Motto: ich bin ich und mir kannst du nicht.

Beitrag #6628926 wurde von einem Moderator gelöscht.
von Xerxes (Gast)


Lesenswert?

Christian J. schrieb:
> CS an VCC.

Sicher ? #CS ist low-aktiv.

von Christian J. (Gast)


Lesenswert?

Xerxes schrieb:
> Sicher ? #CS ist low-aktiv.

CS an Vdd aktiviert I2C, an Low SPI:

von Andreas Rath (Gast)


Lesenswert?

hmm eventuell: Arduino 5V, STM 3V3

von Christian J. (Gast)


Lesenswert?

Andreas Rath schrieb:
> hmm eventuell: Arduino 5V, STM 3V3

Alle meine Arduinos: 3.3V, ADXL345 Board 3.0 - 6.0V
Wobei dieser Spannungsregler, der dazwischen hängt vielleicht trotzdem 
die Ursache sein könnte.....

von Stefan F. (Gast)


Lesenswert?

Ich weiß nicht ob dein Framework vertrauenswürdig ist. Die I²C 
Schnittstelle dieses Mikrocontrollers hat ein paar eklige Eigenarten, 
die es unmöglich machen, einzelne Bytes zu empfangen.

Dein Hauptproblem scheint aber zunächst das ausbleibende ACK nach der 
Adressierung des Chips zu sein. Deswegen würde ich mal die Qualität 
(Pegel, Flanken) der Signale mit einem Oszilloskop prüfen.

Oder zeige wenigstens mal den Schaltplan, vielleicht liegt ein 
Designfehler vor.

Dein Logic Analyzer zeigt etwas schönes an, aber ob dein IC das auch so 
sieht, ist damit noch nicht sicher.

Christian J. schrieb:
> Wobei dieser Spannungsregler, der dazwischen hängt vielleicht trotzdem
> die Ursache sein könnte.....

Eben, deswegen die Frage nach Schaltplan und Oszilloskop-Bild.

von Wolfgang (Gast)


Lesenswert?

Christian J. schrieb im Beitrag #6628926:
> Brauchst du ja nicht zu lesen und deine permanenten
> Belästigungen/Pöbeleien als Troll ohne irgendwelchen fachlichen Inhalt
> hier reichen mir auch!

Ganz schön große Klappe ...

Warum schreibst du auf die Adresse 0x3A, obwohl im Datenblatt 0x1D 
angegeben ist?

Probier's mal mit einem I2C-Scanner

von Christian J. (Gast)


Lesenswert?

Stefan ⛄ F. schrieb:
> Eben, deswegen die Frage nach Schaltplan und Oszilloskop-Bild.

Habe leider keines. Und es ist nur der F103 mit dem ADXL345 dran, direkt 
nur die Drähte, VCC, GND, SCL, SDA. Ich teste alles einzeln, bevor ich 
dasa Ganze baue. Erzeuge 3.3V aber aus einen DC/DC Wanlder. Der STM32 
verträgt die.

Wenn etwas aber 1-2 klappt und dann nicht mehr und das Draufhalten des 
Fingers auf die Kontakte auch nichts bewirkt, dann ist was Faul.

Heute aber nicht mehr, genug vom Tag vergeudet seit heute morgen.Erstmal 
raus und frische Luft tanken

von Stefan F. (Gast)


Lesenswert?

Christian J. schrieb:
> Habe leider keines.

Dann besorge dir eins. Wenn es billig sein muss, dann ein DSO-150.

Und Zeichne den Schaltplan während du auf die Lieferung wartest.

Christian J. schrieb:
> Wenn etwas aber 1-2 klappt und dann nicht mehr und das Draufhalten des
> Fingers auf die Kontakte auch nichts bewirkt, dann ist was Faul.

Eben. Das ist der Moment, wo Messen (statt Raten) angesagt ist.

von Christian J. (Gast)


Lesenswert?

Wolfgang schrieb:
> Ganz schön große Klappe ...

Ich wüsste keine Grund die ständigen Pöbeleien dieser Person noch zu 
tolerieren. Das grosse Manko dieses Forums seit Jahren, dass anonyme 
trolle Threads zerstören können. Da man nicht blockieren kann muss man 
sie leider ertragen.

Und der Rest ergibt sich aus dem Datenblatt und der I2C Specs, Stichwort 
Adressierung R/W Bit. Aus 1D wird 3A bei Shift Left mit LSB = 0 und 3B 
mit LSB=1. Das macht der uC nicht für einen, das muss man selbst tun.

von Christian J. (Gast)


Angehängte Dateien:

Lesenswert?

Stefan ⛄ F. schrieb:
> Eben. Das ist der Moment, wo Messen (statt Raten) angesagt ist.

Hallo Stefan,

wie man sieht spielt er.... Messungen am Arduino ergaben erstmal eine 
Alternativadresse. Korrigiert. Lief immer noch nicht. Finger mal auf die 
Pins draufhalten beim Messen und... oh Wunder.... 0x50 rein und 0x50 
kommen raus. (Der Jubelschrei war bis zur Straße zu hören) Glaube der 
Rest ist wie Du sagstest: Wie sieht das Signal aus? Kann ja nicht immer 
die Finger drauf halten :-) Gefühlt sind die Teile bei 3.3V wohl nicht 
so gut drauf. Werde mal den Regler totmachen und überbrücken.

edit: Jetzt geht es auch ohne Finger drauf.... wie ich diese Sorte 
Fehler hasse!

von Christian J. (Gast)



Lesenswert?

Abschliessendes Ergebnis (für die Nachwelt :-)

Diese blauen ADXL345 as der Bucht für nen schmalen Preis von 1 Euro 
scheinen nicht "echt" zu sein, heisst aber nicht, dass sie es nicht tun. 
​Das Sparkfun ADXL345 Modul kostet immer hin 17 Euro, was ich aber auch 
zu teuer finde.

Erstens ist die Slave Adresse auf A6/A7 gesetzt worden und ist nicht 
3A/3B

Zweitens spielen die Module mit 3.3V an Vcc wohl auch nur haarscharf, je 
nachdem wie kalt oder warm es gerade ist. Finger drauf = sie tun es... 
Finger weg... 1-2 min warten, sie tun es nicht mehr. Ziemlich gaga.

Nach dem Brücken des Spannungsreglers (der ganz kleine Käfer) über Vcc 
läuft es jetzt immer. Den kann man nur ablöten und da ne Brücke unter 
der Lupe zwischen frickeln.

Fazit: die blauen Module wie im Bild laufen nicht mit 3.3V. Zumindest 
nicht stabil.

Und noch besser... wo Bluepill drauf steht ist noch lange nicht Bluepill 
drin. Ich habe rund 10 Boards, einige 5 Jahre alt, manche ganz neu und 
alle in einer Kiste. Die meisten unbenutzt. Bei so 2-3 Stück regt sich 
mit I2C gar nichts, oder nur "irgendwas komisches". Ein paar Takte 
kommen, dann war es das. Die liegen jetzt in der Tonne.

Laufen tut es derzeit mit einem der alten Boards, die noch etwas anders 
bestückt sind als die neuen.

Spannende Sache.... Fake ADXL345 Chips und wohl auch Fake-STM32 ... mich 
wundert da gar nichts mehr inzwischen :-( Ok,die schön gelb bedruckten 
Z80 Prozessoren die man so für 1 Euro kriegt sind auch Nachbauten, die 
gab es so nie. Lohnt sich scheinbar. Steckt man sie ein ist bei 1.5 Mhz 
Schluss, dann entgleist der Programmfluss.

Jedenfalls sind 10 Stunden dabei drauf gegangen heute seit 8 Uhr 
morgens.

von Stefan F. (Gast)


Lesenswert?

Christian J. schrieb:
> Und noch besser... wo Bluepill drauf steht ist noch lange nicht Bluepill
> drin.

Was du nicht sagst! Von entsprechenden Berichten ist dieses Forum seit 
Anfang 2020 voll. Und seit 2021 hat keiner mehr berichtet, ein Bluepill 
mit einem echten oder wenigstens voll kompatiblen STM32F103 bekommen zu 
haben.

von Christian J. (Gast)


Lesenswert?

Stefan ⛄ F. schrieb:

> Was du nicht sagst! Von entsprechenden Berichten ist dieses Forum seit
> Anfang 2020 voll. Und seit 2021 hat keiner mehr berichtet, ein Bluepill
> mit einem echten oder wenigstens voll kompatiblen STM32F103 bekommen zu
> haben.

Habe mir trotzdem die billigsten bestellt, die ich kriegen konnte beim 
Chinesen und werde die an der Rework Station ablöten und durch Originale 
von Digikey bestücken, die mit 128kb. Da suche ich die Fehler wenigstens 
bei mir und nicht im Chip.

von Stefan F. (Gast)


Lesenswert?

Christian J. schrieb:
> Habe mir trotzdem die billigsten bestellt

Mehr Geld auszugeben würde ohnehin nicht helfen. Das hatte jemand 
anderes schon ausprobiert.

von Stefan F. (Gast)


Lesenswert?

Christian J. schrieb:
> werde die an der Rework Station ablöten und durch Originale
> von Digikey bestücken

Kennst du den RobotDyn Shop? Der hat noch originale auf schwarzen 
Boards, mit gleicher Pinbelegung.
https://robotdyn.com/stm32-arm-arduino-mini-system-dev-board-with-arduino-bootloader-stm32f103c8t6-64kb-soldered.html

Aber Achtung: Robotdyn hatte zeitweise parallel zu den originalen auch 
CKS103C8T6 verkauft. Das stand da allerdings klar im Titel.

von Johannes S. (Gast)


Lesenswert?

Es gibt auch noch Olimex, die haben ein Board mit dem F103RB, also auch 
offizielen 128 kB Flash. Etwas teurer als die Bluepill, aber die dürften 
einen originolen ST drauf haben.
https://www.olimex.com/Products/ARM/ST/STM32-H103/
https://www.olimex.com/Products/ARM/ST/STM32-H107/
und die haben weitere interessante Boards, mal so als Alternative zu den 
Chinesen.

von Christian J. (Gast)


Lesenswert?

Stefan ⛄ F. schrieb:
> Kennst du den RobotDyn Shop? Der hat noch originale auf schwarzen
> Boards, mit gleicher Pinbelegung.

Sind ausverkauft.... hast du zuufällig diese Blinky App von GreaseWeazel 
zum Testen? Ich habe leider keinen Zugriff auf das Github, will einfach 
nicht laden.

von Stefan F. (Gast)


Angehängte Dateien:

Lesenswert?

Christian J. schrieb:
> hast du zuufällig diese Blinky App von GreaseWeazel
> zum Testen? Ich habe leider keinen Zugriff auf das Github, will einfach
> nicht laden.

Siehe Anhang

von pegel (Gast)


Lesenswert?

Christian J. schrieb:
> direkt nur die Drähte, VCC, GND, SCL, SDA.

Gibt es auch PullUps passender Größe?

von Christian J. (Gast)


Lesenswert?

Stefan ⛄ F. schrieb:
> Siehe Anhan

Danke! (.hex File leider nicht drin und kompilieren kann ich das auf die 
Schnelle nicht mit meiner IDE)

Ergänzung: Habe den I2C auf einem Lochraster mal mit Vollgas durchlaufen 
lassen, sobald es stolpert, also ein Flag nicht kommt geht ein rote LED 
an.
Verbindung ca. 4cm lang zwischen uC und Board. Es lief bisher 24h durch 
aber man kann es ganz leicht stören wenn man ein Feuerzeug mit Piezo 
daneben zündet. Das reicht aus und die Kommunikation kommt dann auch 
nicht mehr in Ordnung ohne Eingriff.

Bist du auch fit, was die Anbindung von I2C an DMA angeht? Einen ADC 
habe ich problemlos auf einen Array abgebildet aber der arbeitet ja auch 
vollautomatisch allein und da muss nur eine Adresse ausgelesen werden 
aber bei I2C sieht das doch etwas anders aus.

Akltuell klickert Timer 3 alle 1s einen INT, wo ich dann im Handler die 
Werte auslese, was eh nur 1.1ms dauert und mache dort auch die 
Auswertung auf Bewegung. Manuell, weil ich mit den internen Features des 
ADXL345 nicht vertraut bin. Da sind zu viele Fragen offen da mein Gerät 
in jeder Lage arbeiten muss und meine Lösung gut funktioniert.

Übrlege ob ich da einen Thread für aufmache, denn die StdPeriph sind ja 
out of date, die klicken heute alles mit HAL zusammen, was ich noch zu 
Fuss mache.

von Stefan F. (Gast)


Lesenswert?

Christian J. schrieb:
> Bist du auch fit, was die Anbindung von I2C an DMA angeht?

Nein.

Christian J. schrieb:
> Habe ich da vielleicht irgendwas übersehen? Die Pull Ups sind auf diesen
> blauen Boards mit drauf, die man in der Bucht kriegt.

Die sind meistens recht hochohmig, z.B.10 kΩ. Das ist für viele 
Anwendungen zu viel, vor allem wenn es mit Radiowellen oder Funken zu 
tun hat.

Nach wie vor brauchst du ein Oszilloskop um die Signalqualität zu 
bewerten. Wenn die Signale schon im Regelfall grenzwertig sind, ist 
deine Schaltung störempfindlch.

von Christian J. (Gast)


Lesenswert?

Stefan ⛄ F. schrieb:
> Nach wie vor brauchst du ein Oszilloskop um die Signalqualität zu
> bewerten. Wenn die Signale schon im Regelfall grenzwertig sind, ist
> deine Schaltung störempfindlch.

Ja, ich denke dran nachdem die Sache mit dem DPF am Auto repariert 
worden ist :-) Kostet wohl einige Oszis.

Ist hier ganz gut beschrieben aber ob der Aufriss für 6 Bytes lohnt, die 
mit 400khz I2C Frequenz in 0,25ms da sind ist die Frage. Bei den NMEA 
Daten, die fortlaufend eintrudeln werde ich das wohl machen.

Gundsätzlich geht das nicht vollautomatisch, die CPU muss die ganze 
Adressierung machen, der DMA springt da ein, wo in einer Tour gelesen 
oder geschrieben werden muss. Auch dieses Beispiel ist wohl eher 
Hobby-Neugier als echter Nutzen, der liest auch nur 6 Bytes aus und muss 
dafür 4 reinschieben.

https://letanphuc.net/2014/06/stm32-mpu6050-dma-i2c/

von Stefan F. (Gast)


Lesenswert?

Christian J. schrieb:
> Ist hier ganz gut beschrieben aber ob der Aufriss für 6 Bytes lohnt

Ein DSO-150 kostet nur 30 Euro. Um damit ordentlich was zu sehen, musst 
du aber mit der Übertragungsrate runter gehen, z.B. auf 100kHz

von Wolfgang (Gast)


Lesenswert?

Christian J. schrieb:
> Erstens ist die Slave Adresse auf A6/A7 gesetzt worden und ist nicht
> 3A/3B

Das sind genau die Werte für das Adressbytes, die laut Datenblatt 
erforderlich sind, um den Sensor bei auf low gezogenem Pin 12 (SDO/Alt 
Address) anzusprechen - passend zu I2C-Adresse 0x53.
Nicht wundern - RTFM

von Christian J. (Gast)


Angehängte Dateien:

Lesenswert?

Lagen heute in der Post, scheinen wirklich echte STM32F103 zu sein aber 
leider ist das Pinout komplett anders und Lochraster müsste man alles 
auseinander rupfen.

von Christopher J. (christopher_j23)


Lesenswert?

Christian J. schrieb:
> Lagen heute in der Post, scheinen wirklich echte STM32F103 zu sein

Was macht dich da so sicher?


> leider ist das Pinout komplett anders und Lochraster müsste man alles
> auseinander rupfen.

Das ist halt ein BlackPill und nicht einfach nur ein Bluepill auf 
schwarzem Board.

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.