реклама на сайте
подробности

 
 
> FIQ и IRQ LPC 2106
xelax
сообщение Nov 8 2006, 14:43
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 370
Регистрация: 7-11-06
Пользователь №: 22 035



прерывание от 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 работает нормально.
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов (1 - 9)
DASM
сообщение Nov 8 2006, 14:54
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 3 644
Регистрация: 28-05-05
Пользователь №: 5 493



а просто в обработчике
Код
static bool b = 0; if (B) IOSET else IOCLR; b = !b;
не пробовали ?
Go to the top of the page
 
+Quote Post
xelax
сообщение Nov 8 2006, 15:20
Сообщение #3


Местный
***

Группа: Свой
Сообщений: 370
Регистрация: 7-11-06
Пользователь №: 22 035



Цитата(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 раза по времени импульсы. Полистал форум, никто проблем с таймером подобных не испытовал, где-то что-то я не так делаю. Понять пока не могу.
Go to the top of the page
 
+Quote Post
zltigo
сообщение Nov 8 2006, 17:28
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(xelax @ Nov 8 2006, 16:43) *
Наблюдаю следующую картину

Про стек для FIQ забыли?


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
xelax
сообщение Nov 9 2006, 08:53
Сообщение #5


Местный
***

Группа: Свой
Сообщений: 370
Регистрация: 7-11-06
Пользователь №: 22 035



Похоже проблема разрешилась.
Дело было вот в чём. В основном цикле был сброс внешнего 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

Сообщение отредактировал xelax - Nov 9 2006, 08:55
Go to the top of the page
 
+Quote Post
zltigo
сообщение Nov 9 2006, 09:17
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(xelax @ Nov 9 2006, 10:53) *
ИМХО операция записи бита в порт происходит

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


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
xelax
сообщение Nov 9 2006, 09:24
Сообщение #7


Местный
***

Группа: Свой
Сообщений: 370
Регистрация: 7-11-06
Пользователь №: 22 035



Цитата(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;}
Go to the top of the page
 
+Quote Post
Alex03
сообщение Nov 9 2006, 12:21
Сообщение #8


Местный
***

Группа: Свой
Сообщений: 359
Регистрация: 9-12-05
Пользователь №: 12 034



Цитата(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" всяко чтение-модификация-запись.
Go to the top of the page
 
+Quote Post
xelax
сообщение Nov 9 2006, 12:30
Сообщение #9


Местный
***

Группа: Свой
Сообщений: 370
Регистрация: 7-11-06
Пользователь №: 22 035



библиотечка 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;
Go to the top of the page
 
+Quote Post
Alex03
сообщение Nov 10 2006, 04:05
Сообщение #10


Местный
***

Группа: Свой
Сообщений: 359
Регистрация: 9-12-05
Пользователь №: 12 034



Ну и если __REG32 это чтонибудь типа volatile uint32_t, и если дальше при объявлении IOSET_bit нет никаких компиляторозависимых модификаторов, то...

"IOSET_bit.P0_31=1" однозначно чтение-модификация-запись.
и ИМХО создатели IAR-а не правы описывая эти регистры таким способом.
IOSET = 0x80000000; наше всё в этом случае! smile.gif
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 22nd July 2025 - 04:21
Рейтинг@Mail.ru


Страница сгенерированна за 0.01438 секунд с 7
ELECTRONIX ©2004-2016