Forum: Mikrocontroller und Digitale Elektronik STM32F103: Port-Pin wird nicht angesprungen


von Walter T. (nicolas)


Lesenswert?

Hallo zusammen,

ich mache gerade meine ersten Gehversuche mit Em-Bitz und einem 
Nuceo-F103RB. Dankenswerterweise haben die Entwickler des Nucleo-Boards 
die "Arduino"-Pins 3 und 4 ohne Lötjumper auf die Pins gelegt, die vom 
SWD/JTAG benötigt werden. Jetzt versuche ich gerade, diese zu benutzen. 
Ob sich das Nucleo-Board dann überhaupt noch sinnvoll unter Em-Bitz 
einsetzen läßt, kläre ich danach.

Mein Quelltext ist noch überschaubar:
1
#include "stm32f10x_gpio.h"
2
#include "../common/src_avrcom/io.h"
3
#include "../common/src_avrcom/delay.h"
4
#include "stm32f10x_conf.h"
5
#include "../board_nucleo_f103rb.h"
6
#include "../ioMapping.h"
7
8
9
/* Einzelnes oder mehrere Bits eines Ports umschalten (push-pull)
10
 * Diese Funktion ist im Gegensatz zu setBit/clearBit keine atomare Operation!
11
 *
12
 * GPIOx
13
 * Pin: Bitmaske */
14
static_always_inline void io_toggleBit(GPIO_t * const GPIOx, const IOPint_t Pin)
15
{
16
    GPIOx->ODR ^= (uint32_t) Pin;
17
}
18
19
20
int main(void)
21
{
22
    SystemInit();
23
    SysTick_Config(SystemCoreClock/1000); // 1ms
24
25
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
26
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
27
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
28
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);
29
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE);
30
31
32
    AFIO->MAPR &= ~AFIO_MAPR_SWJ_CFG; // RM0008 S. 176
33
    AFIO->MAPR |=  AFIO_MAPR_SWJ_CFG_2;
34
35
    io_setOutput(LED2_GPIO, LED2_Pin);
36
    io_setOutput(GPIOB, GPIO_Pin_3);
37
    io_setOutput(GPIOB, GPIO_Pin_4);
38
    io_setOutput(GPIOB, GPIO_Pin_5);
39
40
    uint16_t val = 1;
41
    while(1)
42
    {
43
        //io_toggleBit(SPARE0_GPIO, SPARE0_Pin);
44
        //io_toggleBit(LED2_GPIO, LED2_Pin);
45
        //glcd_ili9341_putsth(val, 1);
46
        val <<= 1;
47
        if( val == 1<<8 ) val = 1;
48
49
        uint32_t merker = (uint32_t) GPIOB;
50
        delay_ms(200);
51
        io_toggleBit(GPIOB, GPIO_Pin_3);  // Wirkung sichtbar
52
        io_toggleBit(GPIOB, GPIO_Pin_4);  // Wird im Debugger gar nicht angesprungen
53
        io_toggleBit(GPIOB, GPIO_Pin_5);  // Wird im Debugger gar nicht angesprungen
54
    }
55
56
}

Was ich merkwürdig finde: Die beiden letzten "Funktionen" werden im 
Debugger erst gar nicht angesprungen. Der Speicherbereich an dieser 
Adresse ändert sich auch nur beim Aufruf der drittletzten Zeile in der 
Hauptschleife.

Ich hätte jetzt erwartet, daß ich
 a) entweder überhaupt nicht mehr hätte Debuggen können oder
 b) die Funktion aufgerufen wird, aber wirkungslos bleibt.

Leider weiß ich auch noch nicht, wie man (und ob) man in Em-Bitz ein 
Assembler-Listing mit Zuordnung zu den C-Funktionen erzeugen kann.

Wer kann das Mysterium aufklären?

Viele Grüße
W.T.


P.S.: Ich habe das Mysterium selbst gelöst: Die drei Funktionsaufrufe 
werden zu einem einzigen Zugriff auf GPIOB->ODR optimiert, der dann den 
tatsächlichen Zustand vom GPIOB an den entsprechenden Pins exklusiv 
verodert. Wirkung hat das aber dann nur auf Pin PB5, die anderen hat der 
Debugger im Griff, vermutlich durch eine externe Debug-Startsequenz. Was 
für mich bedeutet, daß ich den Nucleo erst seit wenigen Stunden kenne, 
aber die Pinbelegung schon jetzt hasse.

von Dr. Sommer (Gast)


Lesenswert?

Walter T. schrieb:
> Die drei Funktionsaufrufe
> werden zu einem einzigen Zugriff auf GPIOB->ODR optimiert

Das sollte aber nicht so sein, oder ist bei dir das ODR etwa nicht als 
__IO bzw. volatile deklariert?!
Bit Togglen geht übrigens auch atomar:
1
static_always_inline void io_toggleBit(GPIO_t * const GPIOx, const IOPint_t Pin)
2
{
3
  uint32_t S = GPIOx->ODR;
4
  uint32_t P = (uint32_t) Pin;
5
  GPIOx->BSRR = ((S & P) << 16) | ((~S) & P);
6
}

von Dr. Sommer (Gast)


Lesenswert?

Walter T. schrieb:
> AFIO->MAPR &= ~AFIO_MAPR_SWJ_CFG; // RM0008 S. 176
>     AFIO->MAPR |=  AFIO_MAPR_SWJ_CFG_2;

1. Du musst erst den Takt für AFIO einschalten, über RCC_APB2ENR_AFIOEN. 
So hat diese Zeile keine Wirkung.

2. Das sollte ja den Debug-Port komplett abschalten sodass du nicht 
mehr debuggen kannst. Wäre es nicht sinnvoller, nur auf SWD 
umzuschalten, weil du dann noch debuggen kannst, aber PB3,4 dann frei 
werden?

Im Manual steht auch:
To use the serial wire DP to release some GPIOs, the user software must 
set
SWJ_CFG=010 just after reset. This releases PA15, PB3 and PB4 which 
now become available as GPIOs.

Vielleicht mal die Konfiguration früher setzen?

von Leo C. (rapid)


Lesenswert?

Walter T. schrieb:
> AFIO->MAPR &= ~AFIO_MAPR_SWJ_CFG; // RM0008 S. 176
> AFIO->MAPR |=  AFIO_MAPR_SWJ_CFG_2;

Das funktioniert so nicht, weil die SWJ_CFG-Bits Write Only sind.
Siehe RM0008 9.4.2 (bei mir auf Seite 183).

von Stefan F. (Gast)


Lesenswert?

> Das funktioniert so nicht

ich denke schon daß es funktioniert, denn ganz egal welcehn dummy Wert 
er liest, wird doch die &= Operation dennoch dazu führen, daß die 
gewünschten Bits gelöscht werden, wärhend |= die gewünschten Bits setzt.

Der entscheidende Punkt ist, daß nur die SWJ_CFG-Bits Write-Only sind. 
Die anderen kann man zu Glück doch lesen.

von Hannes J. (pnuebergang)


Lesenswert?

Walter T. schrieb:
> Hallo zusammen,
>
> ich mache gerade meine ersten Gehversuche mit Em-Bitz und einem
> Nuceo-F103RB. Dankenswerterweise haben die Entwickler des Nucleo-Boards
> die "Arduino"-Pins 3 und 4 ohne Lötjumper auf die Pins gelegt,

Was sollen dies

> "Arduino"-Pins 3 und 4

sein? Kann es sein, dass du die Pin-Bezeichnungen verwechselst?

> Ob sich das Nucleo-Board dann überhaupt noch sinnvoll unter Em-Bitz
> einsetzen läßt,

EmBlitz ist eine IDE. Die interessiert weder das Board noch 
Pin-Bezeichnungen.

>     io_setOutput(GPIOB, GPIO_Pin_3);
>     io_setOutput(GPIOB, GPIO_Pin_4);
>     io_setOutput(GPIOB, GPIO_Pin_5);

Also geht es um PB3, PB4 und PB5. Irgendwas davon nennst du 
"Arduino"-Pins 3 und 4. Jetzt machen wir mal was ganz wildes, wir 
schauen in die Dokumentation ...

Wir erhalten:
1
Connector   | Connector | Arduino | F103 |  F103
2
            |    Pin    |   Pin   | Pin  | Funktion
3
------------+-----------+---------+------+---------------------
4
CN9 digital |    4      |   D3    | PB3  | TIM2_CH2
5
CN9 digital |    6      |   D5    | PB4  | TIM3_CH1
6
CN9 digital |    5      |   D4    | PB5  |     -

Also geht es um 4/D3/PB3 und 5/D4/PB5?

Aber erst mal kontrollieren wir das im Schaltplan. Wir lernen, der von 
dir vermutlich beanstandete 4/D3/PB3 hat einer Verbindung zu SWO. 
6/D5/PB4 und 5/D4/PB5 gehen nur zu Connector-Pins.

Wir lernen auch, SWO läßt sich über SB15 abtrennen. Das Handbuch verrät 
nicht, was die Voreinstellung ist.

> Ob sich das Nucleo-Board dann überhaupt noch sinnvoll unter Em-Bitz
> einsetzen läßt, kläre ich danach.

Bist du sicher, dass du die notwendige Kompetenz für diese Abklärung 
hast? Denn EmBlitz hat damit überhaupt nichts zu tun.

> verodert. Wirkung hat das aber dann nur auf Pin PB5, die anderen hat der
> Debugger im Griff,

Jetzt geht es doch um PB3 und PB4 (Arduino D3 und D5)? Dann, wie andere 
schon geschrieben haben: SWJ_CFG

> für mich bedeutet, daß ich den Nucleo erst seit wenigen Stunden kenne,
> aber die Pinbelegung schon jetzt hasse.

Dann nimm halt ein Board ohne Arduino-Anschlüsse oder ein Original 
Arduino-Board mit Kindergarten-IDE.

von Walter T. (nicolas)


Lesenswert?

Hannes J. schrieb:
> Also geht es um PB3, PB4 und PB5. Irgendwas davon nennst du
> "Arduino"-Pins 3 und 4. Jetzt machen wir mal was ganz wildes, wir
> schauen in die Dokumentation ...

Ich übersetze mal Deinen Post vom Herablassenden ins Hochdeutsche: "Ich 
habe nie weder mit EmBitz noch mit den Nucleo-Board etwas gemacht." Das 
ist keine Schande. Aber die Auslassungen über den Teil, der von Anfang 
an klar war, sind damit auch unnötig. Die Tabelle übrigens auch. Daß PB3 
und PB4 auch mit dem Timer gesegnet sind, hat nichts mit der 
Problemstellung zu tun.

PB3 und PB4 sind Teil des Debug-Interfaces. Aufgrund der Position an der 
Stiftleiste entsprechen sie aber auch Pins, die von etlichen 
Arduino-Shields genutzt werden.

Wie hängt das mit EmBitz zusammen? Die Oberfläche ist darauf getrimmt, 
daß man quasi immer sofort eine Debug-Session startet. Ich habe die 
Schaltfläche für "normales" Flashen noch nicht einmal gefunden. Das ist 
aber gar nicht so schlecht, weil sie sehr schnell vom Programmier- in 
den Debugmodus und zurück wechselt.


Dr. Sommer schrieb:
> Wäre es nicht sinnvoller, nur auf SWD
> umzuschalten, weil du dann noch debuggen kannst, aber PB3,4 dann frei
> werden?

Ja, ist es. Die Komplett-Abschaltung habe ich nur probiert, um zu sehen, 
ob sich überhaupt eine Wirkung ergibt.

Dr. Sommer schrieb:
> Du musst erst den Takt für AFIO einschalten, über RCC_APB2ENR_AFIOEN.
> So hat diese Zeile keine Wirkung.

Das war's! Der Takt für die AFIO fehlte. Jetzt habe ich mich erst einmal 
erfolgreich ausgesperrt und die Pins wackeln.

Jetzt wird erst einmal Mittagessen gekocht, und dann der JTAG 
herausgeholt.

von Dr. Sommer (Gast)


Lesenswert?

Walter T. schrieb:
> Jetzt habe ich mich erst einmal
> erfolgreich ausgesperrt und die Pins wackeln.

Du warst gewarnt:

Dr. Sommer schrieb:
> 2. Das sollte ja den Debug-Port komplett abschalten sodass du nicht
> mehr debuggen kannst.

Walter T. schrieb:
> Jetzt wird erst einmal Mittagessen gekocht, und dann der JTAG
> herausgeholt.
Was genau bringt das, wenn der JTAG-Port deaktiviert ist? Du kannst 
entweder per Bootloader ein anderes Programm aufspielen, oder versuchen 
durch schnelles Reset-Drücken und dann sofortiges Verbinden per SWD/JTAG 
eine Verbindung herzustellen. Die J-Link z.B. können letzteres 
automatisch. Beim ST-Link könnte die Option "Connect under Reset" 
helfen.

von Stefan F. (Gast)


Lesenswert?

SWO ist am ST-Link Adapter ein Eingang, under dessen Benitzung ist für 
den Programmier- und Debug Vorgang nicht notwendig. Du kannst den Pin 
also einfach anderweitig nutzen. Die Verbindung zum ST-Link stört dabei 
nicht.

von Walter T. (nicolas)


Lesenswert?

Es funktioniert auf über den den SWIM am Nucleo. Einfach die Leitung 
NRST auf Low ziehen und "Connect under Reset" im ST-Link-Utility 
auswählen. Jetzt habe ich alles, was ich brauche.

Auch wenn die Pinbelegung des Nucleo wirklich nicht im nüchtenen Zustand 
zu verstehen ist. Es gibt nirgendwo 8 Portpins hintereinander, auf der 
wichtigsten Stiftleiste konkurrieren Signale für den Debugger.

von W.S. (Gast)


Lesenswert?

Walter T. schrieb:
> #include "../common/src_avrcom/io.h"

Walter T. schrieb:
> Ich übersetze mal Deinen Post vom Herablassenden ins Hochdeutsche:

Also Walter, es wäre wirklich das Beste für dich, wenn du zuerst mal 
all die Arduino-AVR-Gefilde beiseite legen würdest und dich anschließend 
eben NICHT mit irgend einer verdammten IDE befassen würdest, sondern das 
Manual zu deinem STM32F103 lesen würdest.

Nein, ich meine NICHT, daß du irgendwelche Soßenprogramme wie Cube oder 
St-Lib usw. dir anschauen sollst, die wie eine dicke Soße über die 
Hardware gekippt dem Programmierer die Sicht auf die HW verkleistern. 
Sondern ich meine damit, daß du es lernen solltest, deine Register 
selbst zu benutzen.

Beiträge gerade zu dem Zeugs von ST gibt es hier ja weitaus mehr als 
genug - und es gibt hier auch eine Menge Leute, die von der Sache ein 
Stück mehr verstehen als du es momentan verstehst. Glaube deshalb lieber 
nicht, daß das von dir zitierte "herablassend" sei. Das Gegenteil ist 
der Fall, hier will dir jemand tatsächlich HELFEN - und zwar helfen, die 
Dinge zu verstehen und nicht bloß Vorgekautes zu benutzen. Also nicht 
dem Manne nen Fisch geben, sondern ihn das Angeln zu lehren. Klaro?

W.S.

von Dr. Sommer (Gast)


Lesenswert?

W.S. schrieb:
> das Beste für dich

> anschauen sollst

> lernen solltest

> Glaube deshalb

> Klaro?

Prediger am Werk!

von --- (Gast)


Lesenswert?

> #include "../common/src_avrcom/io.h"
> #include "../common/src_avrcom/delay.h"

Ja mit solchen Altlasten wird die Lernkurve flacher.
Und mit "Arduino-Pins" gebe ich mich im bei ARMs nicht ab.
Bei den Nucleos sind sie als zur Stiftleiste parallele Testpunkte
für Oszi und LA nutzbar.
Wegen des windschiefen Designs von Mario & Luigi sind sie für mich
fuer Laboraufbauten eher unbrauchbar.

Das "richtige" Pin-Out haben übrigens die 100 Pinner.
Bei kleineren Gehäusen muss man mit ein wenig Um/nordnung leben.
Immerhin ist bei den Nucleos verschiedener Serien L0/M0/M3
das Pin-Out gleich.

> sondern das Manual zu deinem STM32F103 lesen
Sogar der Plural ist hier angezeigt. Denn es ist ja nicht nur eins.

> Prediger am Werk!
Solang er das Gute™ predigt.

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.