STM32 und usart1/2 Initialisierung

OP #2974463
Lesenswert?

Hallo,
es geht um den Prozessor STM32F107VC auf einem Olimex Board 
32P107.Programmierung mit CoIDE
Ich habe jetzt seit 2h versucht herauszufinden warum USART1 einwandfrei 
funktioniert aber USART2 keinen Mux tut.
Vielleicht habe ich bei der Initialisierung ja was übersehen und jemand 
kann mir einen Tipp geben. Oder vielleicht messe ich an den falschen 
Pins. Sind nicht beide UARTS gleichberechtigt ?
Schönen Gruß
Wolfram
Angehängte Dateien:
Gast #2974576
Lesenswert?

USART1_SendString("Uart1\n");
  while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);

  USART1_SendString("Uart2\n");
-------------^
  while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
---------------------------------------^


Weil du 2 mal auf USART1 sendest?
OP #2974662
Lesenswert?

Sorry, das war ein copy and paste Fehler... (weil ich die 
Stringvariablen getauscht hatte)
im orginal ist es wie hier:

int main(void)
{
// Controller initialisieren

SystemInit();

InitUart1();
InitUart2();

while(1)
{
  delay_nus(10000);
  USART1_SendString("Uart1\n");
  while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
  USART2_SendString("Uart2\n");
  while(USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET);
}
}

Tut aber eben dennoch nicht...
Angehängte Dateien:
OP #2974742
Lesenswert?

A. K. schrieb:
> RCC_APB2PeriphClockCmd(RCC_APB1Periph_USART2
>       -^-                    -^-
Ja da hatte ich auch vermutet und rumgedoktert, aber laut Doko solls so 
sein:

fuer UART1
/**
  * @brief  Enables or disables the High Speed APB (APB2) peripheral 
clock.
  * @param  RCC_APB2Periph: specifies the APB2 peripheral to gates its 
clock.
  *   This parameter can be any combination of the following values:
  *     @arg RCC_APB2Periph_AFIO, RCC_APB2Periph_GPIOA, 
RCC_APB2Periph_GPIOB,
  *          RCC_APB2Periph_GPIOC, RCC_APB2Periph_GPIOD, 
RCC_APB2Periph_GPIOE,
  *          RCC_APB2Periph_GPIOF, RCC_APB2Periph_GPIOG, 
RCC_APB2Periph_ADC1,
  *          RCC_APB2Periph_ADC2, RCC_APB2Periph_TIM1, 
RCC_APB2Periph_SPI1,
  *          RCC_APB2Periph_TIM8, RCC_APB2Periph_USART1(!!!!), 
RCC_APB2Periph_ADC3,
  *          RCC_APB2Periph_TIM15, RCC_APB2Periph_TIM16, 
RCC_APB2Periph_TIM17,
  *          RCC_APB2Periph_TIM9, RCC_APB2Periph_TIM10, 
RCC_APB2Periph_TIM11
  * @param  NewState: new state of the specified peripheral clock.
für UART2:
/**
  * @brief  Enables or disables the Low Speed APB (APB1) peripheral 
clock.
  * @param  RCC_APB1Periph: specifies the APB1 peripheral to gates its 
clock.
  *   This parameter can be any combination of the following values:
  *     @arg RCC_APB1Periph_TIM2, RCC_APB1Periph_TIM3, 
RCC_APB1Periph_TIM4,
  *          RCC_APB1Periph_TIM5, RCC_APB1Periph_TIM6, 
RCC_APB1Periph_TIM7,
  *          RCC_APB1Periph_WWDG, RCC_APB1Periph_SPI2, 
RCC_APB1Periph_SPI3,
  *          RCC_APB1Periph_USART2, RCC_APB1Periph_USART3, 
RCC_APB1Periph_USART4,
  *          RCC_APB1Periph_USART5, RCC_APB1Periph_I2C1, 
RCC_APB1Periph_I2C2,
  *          RCC_APB1Periph_USB, RCC_APB1Periph_CAN1, 
RCC_APB1Periph_BKP,
  *          RCC_APB1Periph_PWR, RCC_APB1Periph_DAC, RCC_APB1Periph_CEC,
  *          RCC_APB1Periph_TIM12, RCC_APB1Periph_TIM13, 
RCC_APB1Periph_TIM14
  * @param  NewState: new state of the specified peripheral clock.

Warum die beiden unterschiedliche Clock sources verwenden(sollen) ist 
mir unklar.
OP #2975333
Lesenswert?

A. K. schrieb:
> primären Pins von UART2

Aber ich dachte ich benutze die primären(!) Pins ? Woran erkennt man das 
?

>müssen die Pins geremapt werden

Das habe ich auch mal versucht, leider auch ohne Erfolg, kann es sein, 
dass die Reihenfolge der Config falsch ist ?
Hier der letzte Versuch:

void InitUart2(void)
{
  // Initialize Structs
  GPIO_InitTypeDef GPIO_InitStructure;
  USART_InitTypeDef USART_InitStructure;
  USART_ClockInitTypeDef USART_ClockInitStructure;
  // Enable clocks
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2 | RCC_APB2Periph_GPIOD, 
ENABLE);
  //RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
  // USART1 RX-Pin initialize PD6
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
  GPIO_Init(GPIOD, &GPIO_InitStructure);
  // USART1 TX-Pin initialize PD5
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
  GPIO_Init(GPIOD, &GPIO_InitStructure);

  /* Remap USART, as USART2 is used as alternate pins on PD5/6*/
  GPIO_PinRemapConfig(GPIO_Remap_USART2, ENABLE);

  // USART initialize
  USART_ClockStructInit(&USART_ClockInitStructure);
  USART_ClockInit(USART2, &USART_ClockInitStructure);

  USART_InitStructure.USART_BaudRate = 9600;
  USART_InitStructure.USART_WordLength = USART_WordLength_8b;
  USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
  USART_InitStructure.USART_Parity = USART_Parity_No;
  USART_InitStructure.USART_StopBits = USART_StopBits_1;
  USART_InitStructure.USART_HardwareFlowControl = 
USART_HardwareFlowControl_None;

  USART_Init(USART2, &USART_InitStructure);
  USART_Cmd(USART2, ENABLE);
}
OP #2975424
Lesenswert?

Markus, danke für den Hinweis, da hast Du wohl recht.

Markus Müller schrieb:
> Die Zeile ist falsch:
> RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2 | RCC_APB2Periph_GPIOD,
> ENABLE);

Also stattdessen müsste es wohl so sein:

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);

Dann sind doch beide richtig Enabled... ? hab ich so jetzt verstanden, 
ABEr GRRRRRRR Hat leider auch nicht geholfen.
(Firma: EleLa - www.elela.de) #2975457
Lesenswert?

Du solltest eine allgemeine RCC Initialisierung machen, mit der die 
ganzen GPIO/AFIO Clocks alle aktiviert werden und auch alle anderen 
Pins, die keine Alternative Funktion haben.
Dann brauchst Du nur noch bei der Initialisierung der verwendeten 
Peripherie (z.B. UART) den Clock aktivieren.
Damit ist die Initialisierung leichter und man kann je nach genutzter 
Peripherie auch einfacher/übersichtlicher die zugehörigen Clocks 
aktivieren.
#2975482
Lesenswert?

Im Gegenteil. Die Idee, in jedem Modul alles einzuschalten, was darin 
verwendet wird, ist sehr vernünftig. Es schadet ja nichts, die AFIO 
mehrfach einzuschalten. Es global an einer Stelle einzuschalten 
bedeutet, einer sauberen Modularisierung des Codes Knüppel zwischen die 
Beine zu werfen.

Er hat einfach nur vergessen, die AFIO auch im zweiten Modul 
einzuschalten.
OP #2975503
Lesenswert?

Markus Müller schrieb:
> Darin wird der Clock für "RCC_APB2Periph_AFIO" aktiviert, also das auch
> noch in die Initialisierung von Uart 2 rein nehmen.

Arrrggggr - Ja klar jetzt gehts auch !!;-) Freu


>Du solltest eine allgemeine RCC Initialisierung machen,...
Ja ich denke dies ist der bessere Weg, sonst konfiguriert man sich 
jeweils etwas weg was noch gebraucht wird. quod erat demonstrandum


Die Hardware geht jetzt, jetzt versuch ich mich mal an Interrupt 
basiertem USART...Gibts da auch solche Stolperfallen ? ;-)

Im Anhang nochmal der Code DER für USART1 und USART2 auf STM32F017VC mit 
Olimex STM32P107 Board der funktioniert, falls das mal jemand sucht.
Angehängte Dateien:
(Firma: EleLa - www.elela.de) #2975572
Lesenswert?

Bei den Interrupts gibt es kein extra Clock der aktiviert werden muss, 
dafür muss man sich vorher gedanken machen wie viele priorisierte 
Interrupts man hat und wie viele Interrupts mit der gleichen Prio 
laufen.
Sie auch "NVIC_PriorityGroupConfig()" und in der Doku lesen, ich weiß 
das gerade nicht genau auswendig.

In jedem Fall, der Interrupt mit der gleichen "PreemptionPriority" kann 
einen anderen mit der gleichen "PreemptionPriority" nicht unterbrechen.
Hingegen der mit einer höherwertigen "PreemptionPriority" schon.
Ich weiß grad nur nicht was höherwertig ist, der mit der kleineren oder 
größeren Zahl.
Der "IRQChannelSubPriority" definiert nur die Reihenfolge, wenn mehrere 
Interrupts mit der gleichen "PreemptionPriority" gleichzeitig kommen, 
unterbrechen sich aber nicht gegenseitig.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren