www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik [Cortex-M3/stm32] Interrupt Routine


Autor: Philipp (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

void USART1_IRQHandler(void)
{
    taskDISABLE_INTERRUPTS();

    portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
    portCHAR cChar;

    extern xQueueHandle xQueue;

    if (USART_GetITStatus( USART1, USART_IT_RXNE ) != RESET)
    {
        cChar = USART_ReceiveData( USART1 );
        xQueueSendFromISR( xQueue, &cChar, &xHigherPriorityTaskWoken );
    }  

    if (USART_GetITStatus(USART1, USART_IT_TXE) != RESET)
    {
        // not implemented

    }

    /* Clear the USART1 Receive interrupt */
    USART_ClearITPendingBit(USART1, USART_IT_RXNE); 
    USART_ClearITPendingBit(USART1, USART_IT_TXE); 

    taskENABLE_INTERRUPTS();
    portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );
}


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


Philipp

Autor: Clemens Gerlach (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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:
void USART1_IRQHandler(void)
{
        portBASE_TYPE task_woken = pdFALSE;
        char c;

        if (USART1->SR & USART_SR_RXNE)
        {
                /* rx data ready */
                c = USART1->DR;
                /* try to enqueue */
                xQueueSendFromISR(serial_queues.uart1_rx_queue, (void *)&c, &task_woken);
        }
        /* only try to get data from queue if tx register empty
         * and int is enabled. if we would not check for int enabled, rx from queue
         * would be tried on every rx interrupt since txe is allways set when tx register
         * is empty
         */
        if ((USART1->SR & USART_SR_TXE) && (USART1->CR1 & USART_CR1_TXEIE))
        {
                /* tx register empty */

                if (xQueueReceiveFromISR(serial_queues.uart1_tx_queue, (void *)&c, &task_woken))
                {
                        /* got data from queue, send it */
                        USART1->DR = c;
                }
                else
                {
                        /* queue empty, disable further ints */
                        USART1->CR1 &= ~USART_CR1_TXEIE;
                }
        }
        portEND_SWITCHING_ISR(task_woken);
}

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

Autor: Philipp (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Philipp (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ach ja, das Problem hat sich seit dem hierher verlagert :-)

Beitrag "STM32 Prioritäten"

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.