¿cómo borrar un indicador de interrupción de UART manualmente?

1

Estoy usando un ATmega32. Tengo ISR (USART_RXC_vect) de la siguiente manera

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

    if(ReceivedChar == '\n'){       
        RxBuffer[RxPos] = '
void USART_Cmd_Eval(void)
{
            strcpy(RxCommand,RxBuffer);

            if(strcmp(RxCommand, "c") == 0){
                    RxReady = 1;                     
                    ADC_measure();
            }   
}
' ; RxReady=0; USART_Cmd_Eval(); } else{ RxBuffer[RxPos] = ReceivedChar; RxPos++; } }

Después de activar el ISR, llama a la siguiente función para definir qué comando se recibe desde la PC.

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

Para cada comando, se llamará la función relativa. Como siguiendo:

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

    if(ReceivedChar == '\n'){       
        RxBuffer[RxPos] = '
void USART_Cmd_Eval(void)
{
            strcpy(RxCommand,RxBuffer);

            if(strcmp(RxCommand, "c") == 0){
                    RxReady = 1;                     
                    ADC_measure();
            }   
}
' ; RxReady=0; USART_Cmd_Eval(); } else{ RxBuffer[RxPos] = ReceivedChar; RxPos++; } }

El problema es: no puedo enviar otro comando porque está bloqueado en la función ADC_measure. Básicamente, no quiere recibir otro comando a través de ISR, creo que continuará abierto. Por lo tanto, creo que debería borrar el indicador de interrupción antes de llamar a ADC_measure. ¿Derecha? ¿Cómo puedo hacer esto?

    
pregunta user3213767

1 respuesta

3

Cuando se ejecuta cualquier rutina de interrupción, se borra el bit I de SREG para evitar la siguiente ejecución de interrupción. El bit se restablece mediante RETI . Es decir. También puede hacerlo manualmente SBI SREG, I (o mediante uint8_t sreg = SREG; sreg | = _BV (I); SREG = sreg; ).

¡Pero también se puede volver a llamar a USART_RXC_vect ! No me gusta ningún _delay () en las rutinas de interrupción, ya que debe ser lo más corto posible. Deberías recodificarlo.

    
respondido por el TMa

Lea otras preguntas en las etiquetas