Ich habe folgende Situation. Mit USART2 steuere ich einen Motor-Controller an. Es wird ein Befehl gesendet und von der Motor Steuerung quittiert. In den Funktionen warte ich zum Teil darauf, bis bestimmte Positionen angefahren wurden. Dazu sende ich auch Anfragen an die Motor-Steuerung und werte die Rückantwort aus. Soweit so gut, es funktioniert alles, wenn ich die Befehle vor der Main-Schleife ausprobiere. Sobald ich aber die Steuerbefehle für die Motorsteuerung über PC Kommunikation auszulösen (FTDI an USART1), wird über USART2 zwar gesendet, aber kein RX Interrupt an USART 2 ausgelöst. USART1 Interrupt ist auch aktiv. Das Gleiche passiert, wenn ich über Systick Interrupt Befehle an die Motorsteuerung verschicken möchte. Jedes Mal ist USART2 RX Interrupt deaktiviert, sobald andere Interrupts aktiv sind. Ist es normal und wie kann ich das umgehen? Ich habe mal Statusregister ausgeben lassen, wenn Daten wie gewünscht Empfangen werden, steht im im USART2->SR Register 0xD0, ansonsten steht da eine 0xF8. Kann das jemand entziffern?
Arrtata schrieb: > Ist es > normal Nein. Arrtata schrieb: > Kann das jemand > entziffern? Ja. Das Datenblatt. Vielleicht blockierst du ja irgendwie die Interrupts versehentlich. Ohne Code zu zeigen ist das alles nur raten.
Also Befehle vom PC kommen über USART1 rein mit 115200 Baud über einen FTDI. Die ISR sieht so aus:
1 | void
|
2 | USART1_IRQHandler (void) { |
3 | |
4 | // USART TX handling --------------------------------------------------
|
5 | if (USART_GetITStatus(USART1, USART_IT_TXE) == SET) { |
6 | |
7 | }
|
8 | |
9 | // USART RX handling --------------------------------------------------
|
10 | if (USART_GetITStatus(USART1, USART_IT_RXNE) == SET) { |
11 | |
12 | CommandInBuf[InBufCnt] = USART_ReceiveData (USART1); |
13 | USART_ClearITPendingBit(USART1, USART_IT_RXNE); |
14 | USART_ClearITPendingBit(USART1, USART_IT_TXE); |
15 | if ((CommandInBuf[InBufCnt] == '\n') || (CommandInBuf[InBufCnt] == '\0') || (InBufCnt >= (BUFSIZE - 1))) { |
16 | CommandInBuf[InBufCnt] = '\0'; |
17 | |
18 | //ParseCMD();
|
19 | CommandReceivedFlag = 1; |
20 | |
21 | InBufCnt = 0; |
22 | GPIO_ToggleBits(LED_GPIO_PORT, LED4_PIN); |
23 | |
24 | }
|
25 | else { |
26 | InBufCnt++; |
27 | }
|
28 | }
|
29 | }
|
Bei USART2 ist ebenfalls RX Interrupt aktiviert. Wenn in der UART1 die Funktion ParseCMD(); aufgerufen wird, werden hier Befehle an die Motorsteuerung über USART2 gesendet und auf Quittierungen gewartet (USART2 IR aktiv). Und genau hier funktioniert es nicht. USART2 sendet zwar, aber Emfangsinterrupt ist nicht aktiv, obwohl die Daten über die Leitung laufen. Ich vermute, wenn man in einer ISR ist, werden andere Interrupts ignoriert, obwohl USART2 höhere Priorität hat. Ich habe es jetzt folgendermaßen gelöst, ein Flag CommandReceivedFlag wird gesetzt und in der Mainschleife abgefragt, und somit ParseCMD() ausgelöst. So geht es wunderbar. Mich würde aber trotzdem interessieren, wie man auf Interrupts in einer anderen ISR reagieren kann, ohne dass diese blockiert werden.
Arrtata schrieb: > werden hier Befehle an die > Motorsteuerung über USART2 gesendet und auf Quittierungen gewartet > (USART2 IR aktiv). Und genau hier funktioniert es nicht. Ja DAS ist klar! Wahrscheinlich haben dein USART1 und USART2 Interrupt die selbe Preemption priority, und daher unterbricht der USART2 RX Interrupt den laufenden USART1 Interrupt nicht. Die Priorität kannst du ändern beim Parameter an den NVIC_Init aufruf. Das ist aber keine so gute Idee, denn was ist wenn eine USART1 Interrupt kommt während der USART2 Interrupt am warten ist - der wird dann ignoriert. Arrtata schrieb: > ein Flag CommandReceivedFlag wird gesetzt > und in der Mainschleife abgefragt, und somit ParseCMD() ausgelöst. Ja, das ist die viel bessere Lösung. Wenn man mehrere Dinge hat die gleichzeitig laufen sollen (bei dir: USART1 und USART2 behandlung) sollte man nicht in einem Interrupt auf etwas warten, weil dann der zweite Interrupt nicht kommen kann. Arrtata schrieb: > Mich würde aber trotzdem interessieren, wie man auf > Interrupts in einer anderen ISR reagieren kann, ohne dass diese > blockiert werden. Eben durch Verstellen der Priorität. Aber das ist dann asymmetrisch und funktioniert nur in die eine Richtung.
USART2 hat aber höhere Priorität und trotzdem ist kein USART2 Empfang in der USART1 ISR möglich.
Arrtata schrieb: > USART2 hat aber höhere Priorität und trotzdem ist kein USART2 > Empfang in > der USART1 ISR möglich. Das kann nicht sein. Dann hast du was falsch gemacht.
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.