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
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?
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...
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.
Wolfram L. schrieb: > Warum die beiden unterschiedliche Clock sources verwenden(sollen) ist > mir unklar. Ist mir jetzt klar wenn man ins Blockschaltbild sieht.. nur USART1 ist auf dem HighSpeed IO Bus "APB2"..
Du solltest entweder die primären Pins von UART2 verwenden, oder das Remapping auf die verwendeten sekundären Pins einrichten.
Um den USART2 mit PD5/PD6 nutzen zu können müssen die Pins geremapt werden. Siehe als "Alternate functions" "Remap"
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); }
Wolfram L. schrieb: > Aber ich dachte ich benutze die primären(!) Pins ? Bei UART1 ja. Bei UART2 liegen auch auf PortA, nicht PortD. > Woran erkennt man das ? Eingehende Lektüre der Reference.
Wolfram L. schrieb: > Hier der letzte Versuch: RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2 | RCC_APB2Periph_GPIOD, -^- -^-
Poste doch nochmal die "STM32_USART_Test.c" wie sie jetzt aus sieht, falls es immer noch nicht geht.
Die Zeile ist falsch: RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2 | RCC_APB2Periph_GPIOD, ENABLE); Also der "RCC_APB1PeriphClockCmd" >> "APB1" kann nie den RCC_APB2Periph_GPIOD im APB2 aktivieren. siehe auch hier: Beitrag "Re: STM32 und usart1/2 Initialisierung"
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.
Ja, klar geht das nicht. Du hast in der main() die Initialisierung der UASRT 1 deaktiviert / auskommentiert. Darin wird der Clock für "RCC_APB2Periph_AFIO" aktiviert, also das auch noch in die Initialisierung von Uart 2 rein nehmen.
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.
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.
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.
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.