Я пытаюсь забыдлокодить такое поведение на прерываниях:
- жду данных по uart, получаю, отключаю RX_vect.
- включаю таймер прерывания через 1024мс, включаю UDR0_vect.
- передаю данные. отключаю UDR0_vect, Включаю RX_vect.
- ждём данные по uart…
При срабатывании исключение таймера он не ждёт 1024мс, а сразу же выплёвывает то что я ему послал. Если послать данные 2 раза сразу же друг за другом, то таймер после 2го прилёта данных начинает отсчитывать время. Но если их отправлять с интервалом раз в 2 секунды то данные получаю обратно моментально.
int main(void) {
init_uart();
init_interrupt();
xfunc_output = my_putchar;
while (1) {
}
return 0;
}
#define BUFF_SIZE 32
#define BUFF_MASK (BUFF_SIZE - 1)
volatile char buff[BUFF_SIZE];
volatile uint8_t head = 0, tail = 0;
void init_uart(void) {
UBRR0H = UBRRH_VALUE; // Defined in setbaud.h
UBRR0L = UBRRL_VALUE;
UCSR0A |= (1 << U2X0);
UCSR0B = (1 << TXEN0) | (1 << RXEN0); // Enable USART transmitter|reciever
UCSR0C = (1 << UCSZ01) | (1 << UCSZ00); // 8 data bits, 1 stop bit
}
void init_interrupt (void) {
TCCR1B |= (1<<CS12); // 256
UCSR0B |= (1<<RXCIE0);
sei();
}
ISR(TIMER1_OVF_vect){
TIMSK1 &= ~(1<<TOIE0); // disable timer
UDR0 = buff[head];
UCSR0B |= (1<<UDRIE0); // enable UDRE_vect
}
ISR(USART_RX_vect){
buff[tail] = UDR0;
if (buff[tail] == ';') {
buff[tail] = '\0';
UCSR0B &= ~(1<<RXCIE0); // disable RX_vect
enable_timer_tx_data();
}
tail = (tail + 1) & BUFF_MASK;
}
ISR(USART_UDRE_vect){
head = (head + 1) & BUFF_MASK;
UDR0 = buff[head];
if(!buff[head]){
UCSR0B &= ~(1<<UDRIE0); // disable UDRE_vect
head = (head + 1) & BUFF_MASK;
UCSR0B |= (1<<RXCIE0); // enable RX_vect
}
}
void enable_timer_tx_data(void){
/* TCNT1= 34287; // 500 ms */
TCNT1= 0; // 1024 ms
TIMSK1|=(1<<TOIE0);
}
Я плохо разбираюсь в поведении avr и у меня нет понимания что просходит в этой ситуации. Подскажите пожалуйста чяднт?