Forum: Mikrocontroller und Digitale Elektronik STM32Fxxx Warum keine zwei Alternative Function Register?


von Christian J. (Gast)


Lesenswert?

Nabend!

Mag vielleicht dem ein oder anderen trivial vorkommen aber gerade klappt 
etwas nicht und da blieb ich am AF_IO Register hängen.

Ich arbeite noch mit den StdPeriph Library, daher Nachsicht, HAL ist up 
to date aber umsteigen möchte ich nicht. Das meiste was ich mit der HAL 
finde ist auch ganz fix umgeschrieben.

Hier die beiden Header der SPL, der APB2 hat ein AFIO, der APB1 aber 
nicht.
Alternate Function, wie ich es verstehe ich, dass man der Hardware, zb 
UART, SPI die Kontrolle über Pins überlässt, also eine Art Weiche die 
gestellt werden muss, damit aus General IO Pins eben die der Hardware 
werden und sie von den normalen Port Register abgekoppelt werden.

Naja, meine UART2 Geschichte für den F103 läuft aber eben auch ohne. 
Hatte erst Code aus dem Netz angeschaut, der war aber auch wieder 
fehlerhaft, der warf die Busse durcheinander, APB2 Geschichte in einen 
APB1 RCC Befehl usw. Man prüfe also, was man kopiert.

Also wann genau muss man den Clock für diese AF genau aktivieren mit
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO) ??

Und das eben auch nur für den APB2 Bus.. weil der APB1 ja kein solches 
Register hat.

Bei meiner UART2 Routine wird der Pin ja mit GPIO_Mode_AF_PP defniert, 
das scheint zu reichen.

Interessant... ohne GPIO_Speed_2MHz spielt es auch nicht, dachte da wäre 
ein Default drin, irgendwas muss ja drin stehen. Aber nein, ohne das 
geht es nicht. Auch bei bei den GPIO Ports.
1
/*****************************************************
2
 * Initialize USART2: TX Only, Pin GPIOA2 ist TX
3
 *****************************************************/
4
void USART2_Init(void)
5
{
6
    USART_InitTypeDef usart2_init_struct;
7
    GPIO_InitTypeDef gpioa_init_struct;
8
9
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
10
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
11
12
    /* GPIOA PINA2 alternative function TX */
13
    gpioa_init_struct.GPIO_Pin = GPIO_Pin_2;
14
    gpioa_init_struct.GPIO_Speed = GPIO_Speed_2MHz;
15
    gpioa_init_struct.GPIO_Mode = GPIO_Mode_AF_PP;
16
    GPIO_Init(GPIOA, &gpioa_init_struct);
17
18
    /* Baud rate 9600, 8-bit data, One stop bit
19
     * No parity, Tx, No HW flow control */
20
21
    usart2_init_struct.USART_BaudRate   = 9600;
22
    usart2_init_struct.USART_WordLength = USART_WordLength_8b;
23
    usart2_init_struct.USART_StopBits   = USART_StopBits_1;
24
    usart2_init_struct.USART_Parity     = USART_Parity_No ;
25
    usart2_init_struct.USART_Mode       = USART_Mode_Tx;
26
    usart2_init_struct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
27
    USART_Init(USART2, &usart2_init_struct);
28
29
    USART_Cmd(USART2, ENABLE);
30
}


1
/** @defgroup APB2_peripheral
2
  * @{
3
  */
4
5
#define RCC_APB2Periph_AFIO              ((uint32_t)0x00000001)
6
#define RCC_APB2Periph_GPIOA             ((uint32_t)0x00000004)
7
#define RCC_APB2Periph_GPIOB             ((uint32_t)0x00000008)
8
#define RCC_APB2Periph_GPIOC             ((uint32_t)0x00000010)
9
#define RCC_APB2Periph_GPIOD             ((uint32_t)0x00000020)
10
#define RCC_APB2Periph_GPIOE             ((uint32_t)0x00000040)
11
#define RCC_APB2Periph_GPIOF             ((uint32_t)0x00000080)
12
#define RCC_APB2Periph_GPIOG             ((uint32_t)0x00000100)
13
#define RCC_APB2Periph_ADC1              ((uint32_t)0x00000200)
14
#define RCC_APB2Periph_ADC2              ((uint32_t)0x00000400)
15
#define RCC_APB2Periph_TIM1              ((uint32_t)0x00000800)
16
#define RCC_APB2Periph_SPI1              ((uint32_t)0x00001000)
17
#define RCC_APB2Periph_TIM8              ((uint32_t)0x00002000)
18
#define RCC_APB2Periph_USART1            ((uint32_t)0x00004000)
19
#define RCC_APB2Periph_ADC3              ((uint32_t)0x00008000)
20
#define RCC_APB2Periph_TIM15             ((uint32_t)0x00010000)
21
#define RCC_APB2Periph_TIM16             ((uint32_t)0x00020000)
22
#define RCC_APB2Periph_TIM17             ((uint32_t)0x00040000)
23
#define RCC_APB2Periph_TIM9              ((uint32_t)0x00080000)
24
#define RCC_APB2Periph_TIM10             ((uint32_t)0x00100000)
25
#define RCC_APB2Periph_TIM11             ((uint32_t)0x00200000)
26
27
#define IS_RCC_APB2_PERIPH(PERIPH) ((((PERIPH) & 0xFFC00002) == 0x00) && ((PERIPH) != 0x00))
28
/**
29
  * @}
30
  */
31
32
/** @defgroup APB1_peripheral
33
  * @{
34
  */
35
36
#define RCC_APB1Periph_TIM2              ((uint32_t)0x00000001)
37
#define RCC_APB1Periph_TIM3              ((uint32_t)0x00000002)
38
#define RCC_APB1Periph_TIM4              ((uint32_t)0x00000004)
39
#define RCC_APB1Periph_TIM5              ((uint32_t)0x00000008)
40
#define RCC_APB1Periph_TIM6              ((uint32_t)0x00000010)
41
#define RCC_APB1Periph_TIM7              ((uint32_t)0x00000020)
42
#define RCC_APB1Periph_TIM12             ((uint32_t)0x00000040)
43
#define RCC_APB1Periph_TIM13             ((uint32_t)0x00000080)
44
#define RCC_APB1Periph_TIM14             ((uint32_t)0x00000100)
45
#define RCC_APB1Periph_WWDG              ((uint32_t)0x00000800)
46
#define RCC_APB1Periph_SPI2              ((uint32_t)0x00004000)
47
#define RCC_APB1Periph_SPI3              ((uint32_t)0x00008000)
48
#define RCC_APB1Periph_USART2            ((uint32_t)0x00020000)
49
#define RCC_APB1Periph_USART3            ((uint32_t)0x00040000)
50
#define RCC_APB1Periph_UART4             ((uint32_t)0x00080000)
51
#define RCC_APB1Periph_UART5             ((uint32_t)0x00100000)
52
#define RCC_APB1Periph_I2C1              ((uint32_t)0x00200000)
53
#define RCC_APB1Periph_I2C2              ((uint32_t)0x00400000)
54
#define RCC_APB1Periph_USB               ((uint32_t)0x00800000)
55
#define RCC_APB1Periph_CAN1              ((uint32_t)0x02000000)
56
#define RCC_APB1Periph_CAN2              ((uint32_t)0x04000000)
57
#define RCC_APB1Periph_BKP               ((uint32_t)0x08000000)
58
#define RCC_APB1Periph_PWR               ((uint32_t)0x10000000)
59
#define RCC_APB1Periph_DAC               ((uint32_t)0x20000000)
60
#define RCC_APB1Periph_CEC

von John Doe (Gast)


Lesenswert?

Christian J. schrieb:
> Hier die beiden Header der SPL, der APB2 hat ein AFIO, der APB1 aber
> nicht.

Das ist so nicht richtig. Die Alternate Function Einheit wirkt auf alle 
Pins. Allerdings muss man ja an die Register kommen und ST hat die halt 
auf den APB2 gelegt. Hätte aber genauso gut der APB1 sein können.

> Alternate Function, wie ich es verstehe ich, dass man der Hardware, zb
> UART, SPI die Kontrolle über Pins überlässt, also eine Art Weiche die
> gestellt werden muss, damit aus General IO Pins eben die der Hardware
> werden und sie von den normalen Port Register abgekoppelt werden.

Grundsätzlich richtig.

> Also wann genau muss man den Clock für diese AF genau aktivieren mit
> RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO) ??

Laut Manual muss der AFIO aktiviert sein beim Zugriff auf dessen 
Register, z.B.: "To read/write the AFIO_EVCR,AFIO_MAPR and AFIO_EXTICRX 
registers, the AFIO clock should first be enabled. Refer to Section 
6.3.7: APB2 peripheral clock enable register (RCC_APB2ENR)."

> Und das eben auch nur für den APB2 Bus.. weil der APB1 ja kein solches
> Register hat.

siehe oben, AFIO wirkt auf alles, am Bus hängt es nur für den 
Registerzugriff.

> Bei meiner UART2 Routine wird der Pin ja mit GPIO_Mode_AF_PP defniert,
> das scheint zu reichen.

Ja.

> Interessant... ohne GPIO_Speed_2MHz spielt es auch nicht, dachte da wäre
> ein Default drin, irgendwas muss ja drin stehen. Aber nein, ohne das
> geht es nicht. Auch bei bei den GPIO Ports.

Was die Library daraus macht, weiss ich nicht, aber Reset Default ist 
jeweils Input für die Pins und 0 beim Mode und das ist Reserved, wenn 
der Pin auf Output gestellt ist. Daher muss ein Mode-Bit gesetzt werden.

von Christian J. (Gast)


Lesenswert?

John Doe schrieb:
> Das ist so nicht richtig. Die Alternate Function Einheit wirkt auf alle
> Pins. Allerdings muss man ja an die Register kommen und ST hat die halt
> auf den APB2 gelegt. Hätte aber genauso gut der APB1 sein können.

Ich danke dir ganz herzlich für diese ausführliche Antwort! Damit ist 
wohl auch alles schon beantwortet! Bei der Suche im Netz vorher fand 
sich jedenfalls eine Menge Falsches und so richtig verstanden wurde es 
teils auch nicht. Einschalten des AF Clocks kann jedenfalls nicht 
verkehrt sein, die paar uA machen den Kohl auch nicht fett.

Zitat:
Was die Library daraus macht, weiss ich nicht, aber Reset Default ist
jeweils Input für die Pins und 0 beim Mode und das ist Reserved, wenn
der Pin auf Output gestellt ist. Daher muss ein Mode-Bit gesetzt werden.
--

Nun ja, jedenfalls muss man die Pins vorher auf 0 setzen, bevor man die 
Clocks einschaltet und den Struct Init für OUT(LOW) durchführt, sonst 
gibt es ganz feine High-Glitches-Nadeln am Datalogger.

von Bauform B. (bauformb)


Lesenswert?

Der Betreff ist stark übertrieben, dieses Problem gibt es nur bei den 
uralten STM32F10x, also 100, 101, 102, 103, 105 und 107. Da stecken die 
Chips 410, 412, 414, 418, 420, 428 und 430 drin.

Diese Art des Alternate Function Multiplexers ist so vermurkst, die 
Chips gehören als Folterwerkzeug geächtet. Mal wieder ein Fall von der 
schlechteste gewinnt :(

von Stefan F. (Gast)


Lesenswert?

Bauform B. schrieb:
> Dieses Problem gibt es nur bei den uralten STM32F10x

Stimmt, bei den neueren Modellen ist das wesentlich eleganter und auch 
besser verständlich umgesetzt worden.

Bauform B. schrieb:
> Mal wieder ein Fall von der schlechteste gewinnt

Allerdings sorgen die Chinesen (mal wieder) durch ihre schlechten 
Fälschungen für ein jähes Ende des STM32F103. Aktueller Nachfolger ist 
der STM32F303.

von Christian J. (Gast)


Lesenswert?

Stefan ⛄ F. schrieb:
> Allerdings sorgen die Chinesen (mal wieder) durch ihre schlechten
> Fälschungen für ein jähes Ende des STM32F103. Aktueller Nachfolger ist
> der STM32F303.

Da nahezu jedes Blue Pill Board heute ein Fake ist und meine ganz sicher 
auch wird es da wohl keine Möglichkeit geben das zu prüfen. Ich schreibe 
meine aktuelle Software auch Zeile für Zeile und teste sofort danach. 
Für den 303 habe ich keine CMSIS und keine SPL. Leider.

von Dr. MCU (Gast)


Lesenswert?

Bauform B. schrieb:
> Der Betreff ist stark übertrieben, dieses Problem gibt es nur bei
> den
> uralten STM32F10x, also 100, 101, 102, 103, 105 und 107. Da stecken die
> Chips 410, 412, 414, 418, 420, 428 und 430 drin.
>
> Diese Art des Alternate Function Multiplexers ist so vermurkst, die
> Chips gehören als Folterwerkzeug geächtet. Mal wieder ein Fall von der
> schlechteste gewinnt :(

Der STM32F100 war STs Cortex-Erstlingswerk. Und das war nach den 
Luminary-Vorreitern (welche nur Standard-ARM-IP für die Peripherie 
einsetzten) schon recht ordentlich.
Insbesondere nach den vielen Jahren mit dem ARM7TDMI-Murks war das weit 
mehr als nur ein Schritt nach vorn.

von Christian J. (Gast)


Lesenswert?

Dr. MCU schrieb:
> Insbesondere nach den vielen Jahren mit dem ARM7TDMI-Murks war das weit
> mehr als nur ein Schritt nach vorn.

Die habe ich 2000 "bearbeitet"... allein schon die Clocks einstellen war 
Hexenwerk :-( Dabei wurde das Teil gefeiert wie sonstwas...

von Dr. MCU (Gast)


Lesenswert?

Viel schlimmer noch war der ganze Interruptkram mangels 
Interruptcontroller im Kern. Ich sag nur "spurious interrupt"...

von Christian J. (Gast)


Lesenswert?

Dr. MCU schrieb:
> Viel schlimmer noch war der ganze Interruptkram mangels
> Interruptcontroller im Kern. Ich sag nur "spurious interrupt"...

Die mmc SD Schnittstelle hat keiner verstanden im Team... zehnmal 
Datenbuch durchgelesen... nur Fragezeichen im Gesicht :-( War ja noch 
alles neu, gab keine Beispiele und Internet war noch leer....

von Stefan F. (Gast)


Lesenswert?

Christian J. schrieb:
> Für den 303 habe ich keine CMSIS und keine SPL. Leider.

Die CMSIS kannst du leicht diesem Paket extrahieren: 
https://www.st.com/en/embedded-software/stm32cubef3.html

von Dr. MCU (Gast)


Lesenswert?

Stefan ⛄ F. schrieb:
> Christian J. schrieb:
>> Für den 303 habe ich keine CMSIS und keine SPL. Leider.
>
> Die CMSIS kannst du leicht diesem Paket extrahieren:
> https://www.st.com/en/embedded-software/stm32cubef3.html

Besser direkt aus github:
https://github.com/STMicroelectronics/STM32CubeF3

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.