STM32: GPIOx->IDR zeigt andere Werte als das Oszilloskop

OP #6058367
Lesenswert?

Hallo zusammen,

ich habe gerade eine Merkwürdigkeit: Ich habe eine Schleife, die prüfen 
soll, ob Pins high sind, die niemals abbricht, obwohl das Oszilloskop 
sagt, daß die Pins eindeutig im High-Zustand sind. Die Schleife ist 
einfach:
1
   uint_fast8_t i2c_bitbang_waitbusy(I2C_TypeDef *I2Cx)
2
   {
3
        volatile bool scl, sda;
4
        do
5
        {
6
            scl = GPIOB->IDR & GPIO_Pin_8;
7
            sda = GPIOB->IDR & GPIO_Pin_9;
8
        }
9
        while( (!scl) || (!sda) );
10
        return EXIT_SUCCESS;
11
    }

Beim ersten Aufruf bricht diese Funktion nie ab. Setze ich im Debugger 
die Variablen so, daß die Schleife abbricht, reagiert sie ab dem zweiten 
Durchlauf wie erwartet.

Der Blick in den Debugger ins Register IDR sagt mir, daß die Pins low 
seien, was zum niemals-Abbrechen paßt. Das Oszilloskop sagt mir aber 
eindeutig, daß die Pins auf +5V liegen. Beide sind als Open Drain Output 
eingestellt. Der Peripherie-Takt ist natürlich auch eingeschaltet.

Was kann dazu führen, daß das Register IDR nicht den extern anliegenen 
Zustand widerspiegelt?
Gast #6058388
Lesenswert?

Leider hast du vergessen, das µC Modell zu benennen. Beim STM32F103 sehe 
ich keinen Grund, warum das IDR Register nicht wie erwartet 
funktionieren kann.

Außer: Du hast vergessen, die Taktversorgung für GPIOA einzuschalten 
oder du hast den Pin als analogen Eingang konfiguriert (aber das hast du 
oben ja dementiert).
OP #6058395
Lesenswert?

Stefan F. schrieb:
> Leider hast du vergessen, das µC Modell zu benennen

Bitte entschuldige. Es ist ein STM32F446RE. Ich will den I2C von der 
echten Peripherie auf Bitbanging umschreiben. Daß mir 
Analog-Einstellungen dazwischenfunken, kann ich ausschließen. Eventuell 
funken mir noch Reste der I2C-Peripherie hinein, weil ich noch ganz am 
Anfang stehe. Aber mit der hatte ich noch nie Probleme, was die 
Input-Register angeht.
Beitrag #6059892 wurde von einem Moderator gelöscht.
OP #6059994
Lesenswert?

Nico W. schrieb:
> Das volatile ist überflüssig

Das volatile ist nötig, um einen Breakpoint setzen und um die Schleife 
verlassen zu können. Ansonsten bleibt von der Schleife nicht mehr viel 
übrig.


Nico W. schrieb:
> Kannst du bitte einmal den kompletten Code posten, bei dem du die Pins
> initialisierst?

Die Initialisierung initialisiert eine alternative Funktion, TIM2 als 
Gray-Dekoder auf den beiden Pins (Relikt). Mit war nur neu, daß 
alternative Funktionen das Input Data Register außer Funktion setzen. 
Aus dem Blockdiagramm geht das m.E. nicht hervor.
Gast #6060022
Lesenswert?

Ich rate mal...

            scl = GPIOB->IDR & GPIO_Pin_8;
            sda = GPIOB->IDR & GPIO_Pin_9;

Das Ergebnis dieses Ausdrucks ist kein bool, sondern ein short integer.
Implizierter cast auf bool bei dem dann die Info verloren geht.

Walter T. schrieb:
> Der Blick in den Debugger ins Register IDR sagt mir, daß die Pins low
> seien, was zum niemals-Abbrechen paßt. Das Oszilloskop sagt mir aber
> eindeutig, daß die Pins auf +5V liegen. Beide sind als Open Drain Output
> eingestellt. Der Peripherie-Takt ist natürlich auch eingeschaltet.

Gut, dass passt nicht dazu, aber evtl. läuft hier noch was anderes 
schief.
Gast #6060217
Lesenswert?

Macht es überhaupt Sinn, bool-variablen zu verwenden? Die nehmen doch 
trotzdem ein ganzes byte an Speicher, oder?

Auch: IDR ist ein 32-Bit Register, welches du auf einen kleineren 
Datentyp implizit castest. Aber das haben ja die Vorredner schon erwähnt

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