Wie lösche ich ein UART-Interrupt-Flag manuell?

Ich verwende einen ATmega32. Ich habe ISR (USART_RXC_vect) wie folgt

ISR(USART_RXC_vect)
{
    char ReceivedChar ;     
    ReceivedChar = UDR; // Fetch the received byte value into the variable "ReceivedChar"

    if(ReceivedChar == '\n'){       
        RxBuffer[RxPos] = '\0' ;                    
        RxReady=0;
        USART_Cmd_Eval();            
    }
    else{
        RxBuffer[RxPos] = ReceivedChar;
        RxPos++; 
    }
}

Nach dem Auslösen des ISR ruft es die folgende Funktion auf, um zu definieren, welcher Befehl vom PC empfangen wird.

void USART_Cmd_Eval(void)
{
            strcpy(RxCommand,RxBuffer);

            if(strcmp(RxCommand, "c") == 0){
                    RxReady = 1;                     
                    ADC_measure();
            }   
}

Für jeden Befehl wird die entsprechende Funktion aufgerufen. Wie folgt:

void ADC_measure(void)
{
        while(RxReady ==1)
        {
                _delay_ms(50);
                // Measrung ADC values and send them to USART
        }
}

Das Problem ist: Ich kann keinen weiteren Befehl senden, weil er in der Funktion ADC_measure feststeckt. Grundsätzlich möchte es keinen weiteren Befehl erhalten, obwohl ISR, ich denke, es wird weiterhin offen bleiben. Daher denke ich, dass ich das Interrupt-Flag löschen sollte, bevor ich ADC_measure aufrufe. Rechts? Wie kann das gehen?

Antworten (1)

Wenn eine Unterbrechungsroutine ausgeführt wird, wird das I- Bit von SREG gelöscht, um die nächste Unterbrechungsausführung zu vermeiden. Das Bit wird durch RETI zurückgesetzt . Dh man kann es auch manuell SBI SREG,I machen (oder über uint8_t sreg = SREG; sreg |= _BV(I); SREG = sreg; ).

Aber auch USART_RXC_vect darf wieder aufgerufen werden! Ich mag kein _delay() in Interrupt-Routinen, da es so kurz wie möglich sein muss. Du solltest es umcodieren.

vielen Dank für Ihre Antwort. Mein Ziel ist es, dass USART_RXC erneut aufgerufen wird, während die adc_meassure-Funktion ausgeführt wird. Außerdem, welche Verzögerung sollte entfernt werden ??
USART_RXC_vect->USART_Cmd_Eval->ADC_measure->_delay_ms() und es gibt sogar eine lange While- Schleife in der ADC_measure- Funktion.
ach, du hast recht. Hast du dafür eine andere Lösung? Ich meine, wo kann ich die While-Schleife nach dem Schließen von USART_RXC und USART_Cmd_Eval ausführen?
Ich würde es in der Hauptprogrammschleife tun (wenn Sie Arduino verwenden, ist es loop() ). Nur um das RxReady- Flag zu sehen, deklarieren Sie es als flüchtig und fügen Sie etwas Anti-Race-Condition-Zeug hinzu.