[Cortex-M3/stm32] Interrupt Routine

Gast #1394581
Lesenswert?

Hallo,
ich habe eine Interrupt Routine, die bei Empfang des ersten Zeichens 
funktioniert. Danach wird der Interrupt immer wieder angesprungen (ohne 
Empfang). Was fehlt mir da?
1
void USART1_IRQHandler(void)
2
{
3
    taskDISABLE_INTERRUPTS();
4

5
    portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
6
    portCHAR cChar;
7

8
    extern xQueueHandle xQueue;
9

10
    if (USART_GetITStatus( USART1, USART_IT_RXNE ) != RESET)
11
    {
12
        cChar = USART_ReceiveData( USART1 );
13
        xQueueSendFromISR( xQueue, &cChar, &xHigherPriorityTaskWoken );
14
    }  
15

16
    if (USART_GetITStatus(USART1, USART_IT_TXE) != RESET)
17
    {
18
        // not implemented
19

20
    }
21

22
    /* Clear the USART1 Receive interrupt */
23
    USART_ClearITPendingBit(USART1, USART_IT_RXNE); 
24
    USART_ClearITPendingBit(USART1, USART_IT_TXE); 
25

26
    taskENABLE_INTERRUPTS();
27
    portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );
28
}

Ich verwende FreeRTOS, aber das soll angeblich unabhängig sein bei 
Interrupt Routinen ???


Philipp
Gast #1395709
Lesenswert?

Finde auch nix in Deinem Code. Sollte eigentlich tun. Das 
USART_ClearITPendingBit(SART1, USART_IT_RXNE) solltest Du dir sogar 
sparen können, da mit dem Lesen des Empfangsregister das RXNE Flag 
gelöscht wird (Du solltest es Dir sogar sparen wegen möglicher 
race-condition).

Das disablen und enablen von Interrupts sollte auch nicht nötig sein 
(ich gehe mal davon aus, dass die Prioritäten FreeRTOS, uart2 richtig 
gesetzt sind).

Bei mir tut das hier:
1
void USART1_IRQHandler(void)
2
{
3
        portBASE_TYPE task_woken = pdFALSE;
4
        char c;
5

6
        if (USART1->SR & USART_SR_RXNE)
7
        {
8
                /* rx data ready */
9
                c = USART1->DR;
10
                /* try to enqueue */
11
                xQueueSendFromISR(serial_queues.uart1_rx_queue, (void *)&c, &task_woken);
12
        }
13
        /* only try to get data from queue if tx register empty
14
         * and int is enabled. if we would not check for int enabled, rx from queue
15
         * would be tried on every rx interrupt since txe is allways set when tx register
16
         * is empty
17
         */
18
        if ((USART1->SR & USART_SR_TXE) && (USART1->CR1 & USART_CR1_TXEIE))
19
        {
20
                /* tx register empty */
21

22
                if (xQueueReceiveFromISR(serial_queues.uart1_tx_queue, (void *)&c, &task_woken))
23
                {
24
                        /* got data from queue, send it */
25
                        USART1->DR = c;
26
                }
27
                else
28
                {
29
                        /* queue empty, disable further ints */
30
                        USART1->CR1 &= ~USART_CR1_TXEIE;
31
                }
32
        }
33
        portEND_SWITCHING_ISR(task_woken);
34
}

Grundsätzlich beim STM32:

In der ST FAQ (http://www.st.com/stonline/faq/user_faqbrowser.php) nach 
"Interrupt re-enters" suchen (FAQ #1224). Grr.. direkter Link geht 
nicht.

Sollte aber bei Dir nicht das Problem sein, da nach dem Löschen des 
Flags (beim Lesen des Registers) ja noch genug passiert vor dem 
Rücksprung.

Gruß
Clemens
Gast #1395877
Lesenswert?

Danke. Ich glaube, daß bei mir die Interrupt Prioritäten nicht passen. 
Das FreeRTOS hängt nach einiger Zeit, aber die Interrupt Routinen 
funktionieren noch. Hast du ein paar Informationen für mich bez. Prios. 
ST und FreeRTOS bin ich eigentlich alles durch - ohne Ergebnis.

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