Bits sind hoch auf deaktivierten Pins (STM32)

Aus irgendeinem Grund habe ich viele Bits mit dem Wert 1, auch wenn sie ausgeschaltet sein sollen. Ich habe versucht, es mit einigen LEDs und dem Keil uVision-Debugger zu debuggen. uC ist STM32F103 Die Situation ist:
Ich habe 2 Pins als Ausgang und 1 als Eingang konfiguriert.

GPIOA->CRL = 0x00000228;

Wenn ich versuche, das IDR-Register zu lesen (das Eingabewerte enthält, auf die mit GPIOA->IDR zugegriffen wird), erwarte ich, etwas wie 0x00000001 oder alle Nullen zu erhalten, wenn die Eingabe niedrig ist. Aber aus irgendeinem Grund bekomme ich 0x0000BF01, was bedeutet, dass ich dieses Zeug am Eingang habe - 1011111100000001, was ich offensichtlich nicht habe, da ich diese Pins nicht einmal benutze.

Was ich versucht habe:
Aus dem Datenblatt habe ich herausgefunden, dass der Reset-Status für Pins 4 = 0100 ist. Also versuchte ich es

GPIOA->CRL = 0x44444228;

Dies gab mir Werte auf IDR 0x0000BFF8, immer noch werid.
Dann habe ich versucht, das CRH-Register auch manuell zurückzusetzen

GPIOA->CRH = 0x44444444;

Auch das hat nichts geändert.

Manchmal gibt es 0x0000B000 aus ... Ich weiß nicht, vielleicht ist es ein wenig zufällig (Rauschaufnahme?).

Was kann das Problem sein? Ordne ich etwas falsch zu?

Im Grunde ist dies im Wesentlichen mein gesamter Code, während ich nur auf GPIO->IDR zugreife:

RCC->APB2ENR|=RCC_APB2ENR_IOPAEN; // Enable IOPA
GPIOA->CRL = 0x44444228;
GPIOA->CRH = 0x44444444;

Und ja, ich weiß, dass ich die std_periph-Bibliothek verwenden kann. Meine Frage ist, zu erfahren, warum die Dinge so passieren, und nicht, eine Problemumgehung zu finden.

LÖSUNG
Der folgende Text gilt für stm32f103, bei anderen stm32s bin ich mir nicht sicher.
Es stellte sich heraus, dass die Pins 12,13,14,15 an Port A für JTAG- und CAN-Signale vorgesehen sind, also sind sie "reserviert" und nicht verwendbar, es sei denn, Sie ordnen JTAG woanders neu zu. Verwenden Sie Pin 12 bis 15 grundsätzlich nicht an Port A, Sie können es ignorieren, indem Sie das benötigte Register maskieren oder falls Sie bestimmte Bits lesen möchten PIN-Nummern zusammen.
Ich habe herausgefunden, dass es immer dieselben Bits waren, ich habe einfach den gesamten Chip mit dem STM32 ST-LINK Utility gelöscht und überprüft, ob diese Bits wieder hoch sind - und sie waren tatsächlich hoch.
AUCH! Die Pins 3 und 4 an Port B sind auch für SWO und NJTRST reserviert und gehen auch auf einem frisch gelöschten Chip hoch, also nehme ich an, dass es besser ist, PB3 und PB4 NICHT zu verwenden.

Es könnte uns helfen, wenn Sie das gesamte Programm und einen Link zur verwendeten Hardware posten. Mit dem, was Sie dargestellt haben, ist es schwer zu helfen. Offensichtliche Vorschläge sind: Die Ports werden nicht korrekt aktiviert, und dies sind zufällige Werte, der Port wird überschrieben, oder ein Teil der Software setzt die Pull-Up-Widerstände der Ports auf „Ein“. Auch die Hardware kann Pins haben, die mit Signalen verbunden sind, und ein Teil der Software wird dafür initialisiert.
Sehr gute Detektivarbeit. Ich stimme Ihnen bezüglich der JTAG-Pins zu (sorry, dass ich diese nicht überprüft hatte), aber ich stimme Ihnen bezüglich der CAN/USB-Pins nicht zu. AFAIK, wenn CAN/USB und die anderen Peripheriegeräte (TIM1 USART1) nicht verwendet werden, kann PA12 für GPIO verwendet werden.

Antworten (1)

Wir brauchen wahrscheinlich mehr Informationen, um Ihnen umfassend helfen zu können. Jedoch, ...

Der „Reset-Wert“ von 0x44444444 ist der Wert, auf den die Register gesetzt werden , wenn die Hardware zurückgesetzt wird. Es ist nicht unbedingt der Port-Konfigurationswert, den Sie benötigen.

Siehe RM008-Referenzhandbuch ... STM32F103xx ... fortschrittliche ARM-basierte 32-Bit-MCUs Abschnitt 9.2

Der Code setzt alle Port-Pins auf:
„CNFy: 01: Floating input (reset state)“
„MODEy: 00: Input mode (reset state)“

Also sind alle Pins außer den unteren drei für die Eingabe eingestellt, ohne spezifisches Pull-up oder Pull-down. Daher kann ein Pin, der mit einem Signal verbunden ist oder eine zufällige Ladung hält, entweder 0 oder 1 sein.

Es ist normal, die Daten von unbenutzten Pins eines Ports zu maskieren, sodass nur die benötigten Werte verwendet werden. Dies hilft, wenn beispielsweise Ihre Hardware geändert wird und neue Pins für einen anderen Zweck aktiv werden.

Ich maskiere das IDR, sodass nur der Wert für Pins verwendet wird, die aktive Eingänge sind, bevor ich den Wert des Port-Eingangsdatenregisters verwende.

Sie können den Pulldown-Widerstand an allen anderen Pins einstellen, um besser sehen zu können, was mit den aktiven Eingängen passiert. Das birgt jedoch ein gewisses Risiko; zum Beispiel, wenn diese Eingangspins mit einem High-Signal oder Vcc verbunden werden.

Wenn Sie sich den Quellcode für die Standardperipheriebibliothek ansehen, zeigt er eine Folge von Registerzugriffen, die ihn korrekt initialisieren.

Das könnte Ihnen genug Einblick geben, um Ihr Lernen fortzusetzen.

Möglicherweise einfacher zu lesen ist die libmaple-Quelle von Leaflabs für das Maple STM32F103-Entwicklungsboard.

Oder stöbern Sie durch stm32duino.com, die an ihrem Update für libmample arbeiten.
Oder schauen Sie sich eine Portierung von libmaple von einem ehemaligen LeafLabs-Mitarbeiter auf rambutan.cc an

BEARBEITEN: Als Sie die CRL-Bits auf '8 = 1000 (Eingangs-Pulldown)' gesetzt haben, haben Sie auch das ODR-Register auf 0 gesetzt? Gemäß Tabelle 20 in Abschnitt 9.1 bestimmt der ODR, ob der Widerstand ein Pull-down oder ein Pull-up ist.

EDIT2: Gut gemacht! Ein gutes Stück Detektivarbeit.
Die JTAG-Pins (PA13, PA14, PA15, PB3, PB4) können für die normale GPIO-Nutzung freigegeben werden, indem ein Wert in AFIO_MAPR festgelegt wird, aber ich würde diese Pins eher als JTAG/SWJ-DP belassen.
AFAIK PA11 und PA12 sind normale Pins, wenn also CAN, USB, TIM1 und USART1 nicht verwendet werden, stehen sie für normales GPIO zur Verfügung.

Ich habe versucht, alle nicht verwendeten Pins auf 8 = 1000 (Eingangs-Pulldown) zu setzen, hat nicht geholfen ... Danke für die Links, ich werde den Quellcode durchgehen und erfahren, was los ist. Ich werde Ihre Antwort markieren, aber ich würde die Lösung später posten, indem ich den ursprünglichen Beitrag bearbeite.
Wenn jemand diesen Kommentar liest - lesen Sie die Lösung im ursprünglichen Beitrag, sie enthält einige nützliche Informationen.