Forum: Mikrocontroller und Digitale Elektronik STM32: GPIOx->IDR zeigt andere Werte als das Oszilloskop


von Walter T. (nicolas)


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?

: Bearbeitet durch User
von Stefan F. (Gast)



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).

von Walter T. (nicolas)


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.

von Stefan F. (Gast)


Lesenswert?

Dann suche mal die entsprechenden Seiten im Referenzhandbuch des STM32F4 
heraus. Vielleicht gibt es da noch mehr, als beim STM32F1.

von John Doe (Gast)


Lesenswert?

Walter T. schrieb:
> Beide sind als Open Drain Output eingestellt.

???

von Nico W. (nico_w)


Lesenswert?

Das volatile ist überflüssig.
Kannst du bitte einmal den kompletten Code posten, bei dem du die Pins 
initialisierst? In dem Teil sehe ich zumindest kein Problem.

: Bearbeitet durch User
Beitrag #6059892 wurde vom Autor gelöscht.
von Walter T. (nicolas)


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.

: Bearbeitet durch User
von leo (Gast)


Lesenswert?

Walter T. schrieb:
> Das volatile ist nötig, um einen Breakpoint setzen zu können. Ansonsten
> bleibt von der Schleife nicht mehr viel übrig.

Du solltest zum Debuggen die Optimierungen ausschalten, sonst siehst du 
eh nicht viel bzw. verkehrt. D.h. volatile brauchst du da nicht.

leo

von Ingo Less (Gast)


Lesenswert?

Ich kann mich irren, du weist deinen Bools aber Werte > 1 zu! Führt das 
nicht zu einem Fehler?

von uiopü (Gast)


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.

von Stefan F. (Gast)


Lesenswert?

Walter T. schrieb:
> Mit war nur neu, dass
> alternative Funktionen das Input Data Register außer Funktion setzen.

Echt, ist das so? Das würde mich überraschen.

von Kaj (Gast)


Lesenswert?

Einem bool einen nicht-bool-Wert zu zuweisen ist undefined behavior. Da 
spielt dann unteranderem das ABI eine Rolle.

von Floxles (Gast)


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

von Walter T. (nicolas)


Lesenswert?

Floxles schrieb:
> IDR ist ein 32-Bit Register, welches du auf einen kleineren
> Datentyp implizit castest.
1
#include <string.h>
2
#include <stdbool.h>
3
#include <stdio.h>
4
#include <stdlib.h>
5
6
/* Funktion zum Testen von Sachen. */
7
exit_t runToShow(void)
8
{
9
    bool a;
10
    printf("a = %i\n", a = 10);
11
12
    return EXIT_SUCCESS;
13
}
 Ergebnis: 1

von Bauform B. (bauformb)


Lesenswert?

Da fehlt noch etwas wie
1
printf ("%d\n", sizeof(bool))
, weil, vernünftig wär's, wenn bool ein int wäre, also 32 Bit. Und dann 
muss der Test natürlich mit dem gleichen Compiler laufem.

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.