Forum: Mikrocontroller und Digitale Elektronik STM32 I2C Fehler


von Sean G. (atmega318)


Angehängte Dateien:

Lesenswert?

Folgendes Problem:
Ein NXT soll Daten von einem STM32F103 empfangen. Der NXT ist Master, 
der STM Slave.
Ich bekomme aber kein Adress Match auf dem Debugger, sondern nur BERR.
Dazu schreibt ST:
1
A bus error is detected when a START or a STOP condition is detected and is not located after a multiple of 9 SCL clock pulses. A START or a STOP condition is detected when a SDA edge occurs while SCL is high.
2
The bus error flag is set only in case the I2C is involved in the transfer as master or addressed slave (i.e not during address phase in slave mode).
3
In case of a misplaced START or ReSTART detection in slave mode, the I2C enters address recognition state as for a correct START condition.
4
When a bus error is detected, BERR flag is set in I2C_ISR register, and an interrupt is generated if ERRIE is set in I2C_CR1 register.
5
It is cleared by software by setting BERRCF bit.
Also dachte ich, naja vielleicht ist der Takt falsch. Tatsächlich 
arbeitet der NXT mit komischen 12kHz, aber selbst nach umstellen bleibt 
das Resultat gleich. Wenn ich mit dem STM etwas sende, sehe ich auf dem 
Oszi, dass der Takt gleich ist wie beim NXT. Daran kann es also nicht 
liegen...

Das hier ist mein Testcode:
1
void I2C_SlaveTest(void)
2
{
3
    GPIO_InitTypeDef    GPIO_InitStructure;
4
    I2C_InitTypeDef     I2C_InitStructure;
5
    
6
    uint8_t               Data;
7
 
8
    //enable clocks
9
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
10
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
11
 
12
    // I2C1 SDA and SCL configuration
13
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
14
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
15
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
16
    GPIO_Init(GPIOB, &GPIO_InitStructure);
17
 
18
    I2C_DeInit(I2C1);
19
    I2C_Cmd(I2C1, ENABLE);
20
 
21
    I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
22
    I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
23
    I2C_InitStructure.I2C_OwnAddress1 = 4;
24
    I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
25
    I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
26
    I2C_InitStructure.I2C_ClockSpeed = 10000;
27
    I2C_Init(I2C1, &I2C_InitStructure);
28
 
29
    
30
31
    while (1)
32
    {
33
34
           
35
    switch (I2C_GetLastEvent(I2C1))
36
    {
37
       
38
        // --> I2C Slave as receiver //////////////////////////////////////////
39
        case I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED:   
40
          a = 0;
41
        break;
42
43
        case I2C_EVENT_SLAVE_BYTE_RECEIVED:              
44
          a = 1;
45
        break; 
46
        ///////////////////////////////////////////////////////////////////////    
47
      
48
        // --> I2C Slave as sender ////////////////////////////////////////////
49
        case I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED:
50
            I2C_SendData(I2C1, 0x5D);
51
            a = 3;
52
        break;
53
54
        case I2C_EVENT_SLAVE_BYTE_TRANSMITTED:
55
            I2C_SendData(I2C1, 0x5D);
56
            a = 4;
57
        break;
58
        ///////////////////////////////////////////////////////////////////////
59
          
60
        
61
        case I2C_EVENT_SLAVE_STOP_DETECTED:              
62
            (void)(I2C_GetITStatus(I2C1, I2C_IT_STOPF));
63
            I2C_Cmd(I2C1, ENABLE);
64
            a = 5;
65
        break;
66
67
        default:
68
        break;
69
    }
70
 
71
    }
72
}

Im Anhang: Registerwerte vom Debugger (nachdem der NXT was gesendet hat, 
vorher steht alles auf 0)
und
Vom NXT geschicktes Byte.
Elektrische Fehler sind eigentlich ausgeschlossen (Masse ist verbunden, 
SDA/SCL nicht vertauscht, und beide Seiten können gegen den Pullup 
treiben.)

So langsam gehen mir die Ideen aus, weiss jemand mehr?

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Sean Goff schrieb:
> Byte_vom_NXT.jpg

Das sieht recht merkwürdig aus. Falls das der NXT als Sender ist, fehlt, 
korrekte Adressierung vorausgesetzt, das ACK des STM, das im 9. SCL Takt 
eigentlich low werden müsste. Danach (also wenn ACK nicht kommt) sollte 
der NXT eigentlich gar nicht mehr an SDA rumfummeln, macht er aber doch 
mit der Änderung von SDA, während SCL high bleibt. Diese Bedingung wird 
dann vom STM32 als Fehler ausgeworfen.
Prüfe also als erstes, warum vom STM32 kein ACK kommt.
Edit: Kann es sein, das du aus Versehen Adresse 0x02 statt 0x04 benutzt? 
Beim abzählen der Clocks kommt mir das so vor, ist auf dem schrägen Foto 
aber nicht sooo genau auszumachen.

von Sean G. (atmega318)


Lesenswert?

Matthias Sch. schrieb:
> Sean Goff schrieb:
>> Byte_vom_NXT.jpg
>
> Das sieht recht merkwürdig aus. Falls das der NXT als Sender ist, fehlt,
> korrekte Adressierung vorausgesetzt, das ACK des STM, das im 9. SCL Takt
> eigentlich low werden müsste. Danach (also wenn ACK nicht kommt) sollte
> der NXT eigentlich gar nicht mehr an SDA rumfummeln, macht er aber doch
> mit der Änderung von SDA, während SCL high bleibt. Diese Bedingung wird
> dann vom STM32 als Fehler ausgeworfen.
> Prüfe also als erstes, warum vom STM32 kein ACK kommt.
> Edit: Kann es sein, das du aus Versehen Adresse 0x02 statt 0x04 benutzt?
> Beim abzählen der Clocks kommt mir das so vor, ist auf dem schrägen Foto
> aber nicht sooo genau auszumachen.

Ja, ich benutze 0x02 statt 0x04. Das habe ich aber nur testweise 
gemacht, weil im Debugger im ADDR Register 0x01 statt 0x02 stand.
Aber heisst das, dass der STM eigentlich richtig konfiguriert ist (halt 
mit 2 statt 4)? Er soll einfach auf ein TX Request antworten können. Der 
NXT scheint so oder so alles andere als Normkonform zu sein...

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Sean Goff schrieb:
> Aber heisst das, dass der STM eigentlich richtig konfiguriert ist

Das erfährst du erst dann, wenn die gesendete Adresse des NXT vom STM 
mit ACK quittiert wird, also im 9ten SCL low wird.
Nach einem Buserror gibt es übrigens eine von Philips beschriebene Reset 
Prozedur. Diese besteht aus dem Senden von bis zu 9 SCL Zyklen, um den 
Bus wieder in einen definierten Zustand zu bringen.

von John (Gast)


Angehängte Dateien:

Lesenswert?

Dein Low-Pegel liegt bei 1V. Das ist zu hoch.

von Helper (Gast)


Lesenswert?

John schrieb:
> Dein Low-Pegel liegt bei 1V. Das ist zu hoch.

Hilfst du dir jetzt selbst? Kanns mir nicht anders erklären, woher kommt 
sonst das Bild..?

von John (Gast)


Lesenswert?

Helper schrieb:
> Kanns mir nicht anders erklären, woher kommt
> sonst das Bild..?

Das ist das Bild vom ersten Post des TO. Ich habe es nur etwas entzerrt.

von Sean G. (atmega318)


Lesenswert?

John schrieb:
> Dein Low-Pegel liegt bei 1V. Das ist zu hoch.

Hmm, jetzt wo du das sagst!
Ich habe zwar keine Ahnung, weshalb das so sein soll, denn ich verwende 
100k Pullup (ja der NXT soll sehr treiberschwach sein).
Kann es daran liegen? Weil immer als High erkennen tut der STM es ja 
nicht, sonst könnte der Fehler doch gar nicht entstehen, oder? Oder kann 
es sein, dass das gerade so auf der Schwelle liegt?

Ich weiss das ist etwas mühsam, aber leider kann ich erst nächste Woche 
testen vermutlich. Ist ein Schulprojekt, und ich habe weder den NXT noch 
das Oszi...

LG, Sean

von Sean G. (atmega318)


Lesenswert?

Danke euch allen, war mal wieder ein ganz blöder Fehler:
Ich habe die Pullups in der Schule dran gemacht, und irgendjemand hatte 
die glorreiche Idee 10k Widerstände ins 100k Schächtelchen zu machen :(
Danke an John, ist mir nicht aufgefallen.
Noch ein schönes Wochenende an alle :)

von Dirk K. (dekoepi)


Lesenswert?

Danke für diese Rückmeldung!

Hatte kürzlich schon das Problem mit fehlendem Pullup. Konnte das nicht 
ganz zuordnen, weil es so geklappt hat, wenn ich Rückgabewerte direkt 
via UASRT ausgebe (keine Ahnung, wie das passieren kann). Pullup auf dem 
Pin eingeschaltet, und schon lief es sauber.
Habe genau diesen Fall auch bei einem Kamera-Modul. Am ATmega328 läuft 
das problemlos via Pegelwandler, am STM32 direkt angeschlossen nicht; 
selbst beim Bitbang muss ich pfuschen.
4,7kOhm als Pullup ist ganz offensichtlich zu stark. Muss das mal bei 
mehr "Motivation zu Aktion" gegentesten. Klingt aber logisch! :)

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.