Я использую ATmega32. У меня есть ISR (USART_RXC_vect) следующим образом
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++;
}
}
После запуска ISR он вызывает следующую функцию, чтобы определить, какая команда получена от ПК.
void USART_Cmd_Eval(void)
{
strcpy(RxCommand,RxBuffer);
if(strcmp(RxCommand, "c") == 0){
RxReady = 1;
ADC_measure();
}
}
Для каждой команды будет вызываться относительная функция. Как показано ниже:
void ADC_measure(void)
{
while(RxReady ==1)
{
_delay_ms(50);
// Measrung ADC values and send them to USART
}
}
Проблема в том, что я не могу отправить другую команду, потому что она застряла в функции ADC_measure. По сути, он не хочет получать другую команду через ISR, я думаю, что он будет продолжать открываться. Поэтому я думаю, что должен сбросить флаг прерывания перед вызовом ADC_measure. Верно? Как это сделать?
Когда выполняется любая процедура прерывания, бит I SREG сбрасывается, чтобы избежать следующего выполнения прерывания. Бит сбрасывается RETI . Т.е. это можно сделать и вручную SBI SREG,I (или через uint8_t sreg = SREG; sreg |= _BV(I); SREG = sreg; ).
Но также может быть вызван повторный вызов USART_RXC_vect ! Мне не нравятся какие-либо _delay() в подпрограммах прерывания, поскольку они должны быть как можно короче. Вы должны перекодировать его.
пользователь3213767
ТМа
пользователь3213767
ТМа