mikrocontroller.net

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


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Walter T. (nicolas)


Bewertung
0 lesenswert
nicht 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:
   uint_fast8_t i2c_bitbang_waitbusy(I2C_TypeDef *I2Cx)
   {
        volatile bool scl, sda;
        do
        {
            scl = GPIOB->IDR & GPIO_Pin_8;
            sda = GPIOB->IDR & GPIO_Pin_9;
        }
        while( (!scl) || (!sda) );
        return EXIT_SUCCESS;
    }

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


Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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).

: Bearbeitet durch User
von Walter T. (nicolas)


Bewertung
0 lesenswert
nicht 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. (stefanus)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht lesenswert
Walter T. schrieb:
> Beide sind als Open Drain Output eingestellt.

???

von Nico W. (nico_w)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
-1 lesenswert
nicht 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)


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

von uiopü (Gast)


Bewertung
0 lesenswert
nicht 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. (stefanus)


Bewertung
0 lesenswert
nicht 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)


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

von Floxles (Gast)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht lesenswert
Floxles schrieb:
> IDR ist ein 32-Bit Register, welches du auf einen kleineren
> Datentyp implizit castest.
#include <string.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>

/* Funktion zum Testen von Sachen. */
exit_t runToShow(void)
{
    bool a;
    printf("a = %i\n", a = 10);

    return EXIT_SUCCESS;
}
 Ergebnis: 1

von Bauform B. (bauformb)


Bewertung
0 lesenswert
nicht lesenswert
Da fehlt noch etwas wie
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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.