Переменная AVR прерывания обновлена ​​в основной

Используя 8-битный AVR micro, я пришел к простой ситуации, которую не так просто решить.

Рассмотрим следующий фрагмент:

static volatile uint8_t counter;

//fires often and I need all the values of the counter.
void isr(void) {
  counter++;
}

int main (void) {

  while(1) {
    send_uart(counter);
    counter = 0;
    delay_ms(1000); //1 sec pause
  }  

  return 0;
}

1.) Может случиться так, что send_uart за ним следует isr, который увеличивает счетчик, а затем следующий оператор обнуляет его. Поэтому я пропущу одну информацию со счетчика.

2.) Если я использую ATOMIC_BLOCK(ATOMIC_RESTORESTATE) в главном fn я могу избежать проблем, объявленных в (1), но может случиться так, что я пропущу ISR, потому что в этом случае INT отключаются на короткое время.

Есть ли лучший способ передачи информации от основного FN к ISR?

1 ответ

Если счетчик выбран, а не сброшен, проблем с синхронизацией не возникнет. Приращения, происходящие при отправке, будут учтены в следующей итерации. Тип данных без знака переменных счетчика гарантирует четко определенное поведение переполнения.

uint8_t cs = 0;                  // counter sample at time of sending
uint8_t n = 0;                   // counter as last reported

while (1) {
  cs = counter;                  // sample the counter
  send_uart((uint8_t)(cs - n));  // report difference between sample and last time
  n = cs;                        // update last reported value
  delay_ms(1000);
}
Другие вопросы по тегам