Прерывание таймера отсутствия совпадения - PullRequest
0 голосов
/ 05 августа 2020

Я использую LPC2378 (ARM7TDMI-S) u C для проекта. Timer0 на u C используется для измерения частоты сигнала на одном из входов u C. Он настроен на прерывание по нарастающему фронту сигнала (входной захват), а также прерывание по регистру совпадения. Прерывание регистра совпадения устанавливается таким образом, что прерывание происходит каждые 50 мс. В моем основном коде у меня есть время l oop, которое выйдет только в том случае, если установлена ​​переменная, что происходит только тогда, когда происходит прерывание совпадения таймера0. Моя ISR выглядит так

static __irq __arm void TIMER_handler0(void) {
  
  DWORD T0int;
  T0int = T0IR;
  
  if (T0int & IIR_CR0) {          // interrupt due to rising edge
    T0IR_bit.CR0INT = 1;    // acknowledge interrupt 
    //Do stuff to figure out frequency of input signal

  }
  
  if ((T0int & IIR_MR0) || (T0int & IIR_MR1)) {    // interrupt due to match
    T0IR_bit.MR0INT = 1;    // acknowledge interrupt
    T0CCR_bit.CAP0I = 0;    // turn off both interrupts (capture & match)
    T0MCR_bit.MR0I = 0;   
    T0TCR_bit.CE = 0;       // turn off the counter and reset the counter register
    T0TC = 0;
    timer0busy = 0;
  } 
  VICADDRESS = 0x0;   
}

Хотя l oop в моем основном коде проверяет флаг "timer0busy" и выглядит так:

while(timer0busy) {
       //Do stuff
}

флаг "timer0busy" установлен в 1, когда таймер 0 включен, что выполняется до этого, пока l oop

В некоторых случаях я замечал, что мой u C прекращал отправлять выходные данные через UART. При дальнейшей инвертигации я обнаружил, что он застрял в приведенном выше примере, пока l oop, потому что флаг "timer0busy" никогда не становился равным 0. Я провел еще несколько тестов и решил, что это обычно происходит, когда частота входного сигнала (которая измеряется таймером 0). ) увеличена. Теперь я понимаю, что по мере увеличения частоты входного сигнала прерывания из-за нарастающего фронта также будут увеличиваться, но я не могу понять, почему в какой-то момент перестает происходить прерывание из-за регистра совпадения. Регистр совпадения настроен на прерывание каждые 50 мс независимо от частоты входного сигнала, и когда это прерывание происходит, прерывания отключаются, а флаг устанавливается в 0. Для прерываний регистра захвата и совпадения ISR одинаков. Превышает ли таймер значение совпадения, не будучи пойманным? Я не знаю, как это могло случиться. Что произойдет, если нарастающий фронт и совпадение произойдут одновременно? Может ли это быть результатом, когда это произойдет

1 Ответ

1 голос
/ 05 августа 2020

На какой приблизительно частоте прерывание больше не работает?

Насколько я понимаю, эта часть прерывания выполняется при каждом нарастающем фронте сигнала:

  if (T0int & IIR_CR0) {          // interrupt due to rising edge
      T0IR_bit.CR0INT = 1;    // acknowledge interrupt 
      //Do stuff to figure out frequency of input signal
  }

Вы уверены, что достаточно времени, чтобы работать, прежде чем прерывание снова сработает? Я бы посчитал тактовые циклы, если вы не уверены.

LPC2378 Нет Nester VI C, только обычный VI C. Это означает, что если произошло прерывание A, и пока оно находится в середине выполнения, запускается прерывание B, обычный VI C не может приостановить процесс, вызываемый A, запустить процесс B, затем повторно войти в A. Он запускает процесс A для завершение, затем запускает процесс B.

Я предполагаю, что когда частота вашего сигнала достаточно высока, ваша система вызывает прерывание за прерыванием без времени, чтобы выполнить их до завершения, вызывая быстро растущее наращивание работы, пока VI C паника.

Попробуйте ограничить частоту прерываний из-за нарастающего фронта (например, каждого второго фронта), когда частота становится слишком высокой.

...