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?
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.
Benutzer3213767
TMa
Benutzer3213767
TMa