Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: FIQ и IRQ LPC 2106
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
xelax
прерывание от MR1 таймера Timer0, раз в миллисекунду.
Код
void InitTimer1 (void)
{
   T1TCR = 0x00000002; // синхронный сброс счётчика таймера и счётчика предделителя
   T1PR  = 0x0000170A;
   T1MR1 = 0x00000009;
   T1MCR = 0x00000018;  // разрешаю прерывание по 1 мс  
   T1TCR = 0x00000001;   // старт таймера
}

// конфигурирование контроллера прерываний
void InitVIC(void)
{
  /*  // Setup interrupt controller.    
    VICVectCntl3=0x00000025;
    VICVectAddr3 =(unsigned )Timer1Int;
//   VICIntSelect |=0x20;
    VICIntEnable |=0x20;
     VICVectAddr = 0;        
}

#pragma vector=0x1C
__fiq __arm void interrupt_function(void)
{      
  
   T1IR = 0x000000FF;
  
   if (IOPIN_bit.P0_14)  
      IOCLR_bit.P0_14=1;  
   else
      IOSET_bit.P0_14=1;  
}

__arm static void Timer1Int(void)
{        
   T1IR = 0x000000FF;
  
   if (IOPIN_bit.P0_14)
      IOCLR_bit.P0_14=1;  
   else
      IOSET_bit.P0_14=1;  
}



#pragma vector=0x18
__irq __arm void isr_handler_irq(void)
{
  void (*interrupt_function)();
  unsigned int adrvector;

  adrvector = VICVectAddr;                    
  interrupt_function = (void(*)())adrvector;
  (*interrupt_function)();                  

  VICVectAddr = 0;
}


Наблюдаю следующую картину осциллом на 14 пине, когда использую FIQ вместо меандра вижу иногда проскакивают увеличенные в два раза по времени импульсы. Иногда посередине этого импульса виден узкий пичёк. Такое ощущение, что FIQ происходит два раза подряд. Что в коде не так??? IRQ работает нормально.
DASM
а просто в обработчике
Код
static bool b = 0; if (B) IOSET else IOCLR; b = !b;
не пробовали ?
xelax
Цитата(DASM @ Nov 8 2006, 17:54) *
а просто в обработчике
Код
static bool b = 0; if (B) IOSET else IOCLR; b = !b;
не пробовали ?


пробовал, тоже самое.

Ещё интересную деталь выяснил. Если описываю два прерывания. Например добавляю 1мс по Timer0 и в этом прерывании инвертирую пин 1, то перестают работать два IRQ. и пин 14 и пин 1 наблюдаю увеличенные в 2, а то и в 3 раза по времени импульсы. Полистал форум, никто проблем с таймером подобных не испытовал, где-то что-то я не так делаю. Понять пока не могу.
zltigo
Цитата(xelax @ Nov 8 2006, 16:43) *
Наблюдаю следующую картину

Про стек для FIQ забыли?
xelax
Похоже проблема разрешилась.
Дело было вот в чём. В основном цикле был сброс внешнего WDT
Код
if(IOPIN_bit.P0_31){IOCLR_bit.P0_31=1;}
          else {IOSET_bit.P0_31=1;}

В прерывании менялся 14 бит порта. ИМХО операция записи бита в порт происходит (очень приблизительно) 1 .чтение порта + 2. наложение маски + 3. запись в порт. Предположим что в основном цикле записываем 31 бит.
И если между 1 и 2 этапом происходит прерывание, прочитанное значение сохраняется в стек. В прерывании меняется допустим 14 бит. Возвращаемся из прерывания, считывается значение из стека (с неизменённым в прерывании 14 битом), меняется 31 бит и значение пишется в порт. В итоге значение 14 бита потеряно.

Убрав из основного цикла изменение 31 бита, глюк полечился. Возможно мои домыслы неверны, так как начал писать под АРМ неделю назад wink.gif.
Что скажут старожилы форума?

И как вообще такой ситуации избежать?

З.Ы. Забыл самое важное пишу на IAR
zltigo
Цитата(xelax @ Nov 9 2006, 10:53) *
ИМХО операция записи бита в порт происходит

Ничего общего с описанным в случае работы с SET и CLEAR портами нет. Прочитайте об огранизации железа для доступа к портам в LPC.
xelax
Цитата(zltigo @ Nov 9 2006, 12:17) *
Ничего общего с описанным в случае работы с SET и CLEAR портами нет. Прочитайте об огранизации железа для доступа к портам в LPC.


Не спорю, пока про АРМ знаю очень мало. Всё на стадии изучения.
Но тогда как объяснить тем, что глюк полечился, когда убрал из основного цикла следующий код.

Код
if(IOPIN_bit.P0_31){IOCLR_bit.P0_31=1;}
          else {IOSET_bit.P0_31=1;}
Alex03
Цитата(zltigo @ Nov 9 2006, 14:17) *
Цитата(xelax @ Nov 9 2006, 10:53) *

ИМХО операция записи бита в порт происходит

Ничего общего с описанным в случае работы с SET и CLEAR портами нет. Прочитайте об огранизации железа для доступа к портам в LPC.


А как в IAR-e описаны эти IOCLR_bit и IOSET_bit?
У меня IAR-а нет, а если как стандартная Cи-шная структура с битовыми полями - то "IOSET_bit.P0_31=1" всяко чтение-модификация-запись.
xelax
библиотечка iolpc210x.h

Код
/* GPIO registers */
typedef struct {
  __REG32 P0_0            :1;
  __REG32 P0_1            :1;
  __REG32 P0_2            :1;
  __REG32 P0_3            :1;
  __REG32 P0_4            :1;
  __REG32 P0_5            :1;
  __REG32 P0_6            :1;
  __REG32 P0_7            :1;
  __REG32 P0_8            :1;
  __REG32 P0_9            :1;
  __REG32 P0_10           :1;
  __REG32 P0_11           :1;
  __REG32 P0_12           :1;
  __REG32 P0_13           :1;
  __REG32 P0_14           :1;
  __REG32 P0_15           :1;
  __REG32 P0_16           :1;
  __REG32 P0_17           :1;
  __REG32 P0_18           :1;
  __REG32 P0_19           :1;
  __REG32 P0_20           :1;
  __REG32 P0_21           :1;
  __REG32 P0_22           :1;
  __REG32 P0_23           :1;
  __REG32 P0_24           :1;
  __REG32 P0_25           :1;
  __REG32 P0_26           :1;
  __REG32 P0_27           :1;
  __REG32 P0_28           :1;
  __REG32 P0_29           :1;
  __REG32 P0_30           :1;
  __REG32 P0_31           :1;
} __gpio_bits;
Alex03
Ну и если __REG32 это чтонибудь типа volatile uint32_t, и если дальше при объявлении IOSET_bit нет никаких компиляторозависимых модификаторов, то...

"IOSET_bit.P0_31=1" однозначно чтение-модификация-запись.
и ИМХО создатели IAR-а не правы описывая эти регистры таким способом.
IOSET = 0x80000000; наше всё в этом случае! smile.gif
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.