Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Никак не пойму прерывания...
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > ARM, 32bit
Shaienn
Добрый день. Перечитал кучу всего, но так и не могу добиться результата.

Задача такая:
Запустить PIT, досчитать до чего-нибудь, вылететь в прерывание по флагу PITS.

Код
#include <AT91SAM7S256.H>                       /* AT91SAMT7S64 definitions  */
#include <lib_AT91SAM7S256.h>
/*
* Main Program
*/
int i;

__irq void isrSYS(void)
{
         unsigned int status = AT91C_BASE_SYS->PITC_PIVR;
         if (i==1)
         {
         AT91C_BASE_PIOA->PIO_SODR = i;
         i=0;
         }
         else
         {
         AT91C_BASE_PIOA->PIO_SODR = i;
         i=1;
         }
         AT91C_BASE_AIC->AIC_EOICR = status;
}

int main (void) {
  // Enable the Clock of the PIO
    AT91C_BASE_PIOA->PIO_PER = (1 << AT91C_PIO_PA0);
    AT91C_BASE_PIOA->PIO_OER = 0x0000ffff;
    AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_PIOA)| (1 << AT91C_ID_SYS);
    AT91C_BASE_PITC->PITC_PIMR = AT91C_PITC_PITEN|AT91C_PITC_PITIEN|0x000007;
      AT91C_BASE_AIC->AIC_SVR[AT91C_ID_SYS] = (unsigned int)isrSYS;
       AT91C_BASE_AIC->AIC_SMR[AT91C_ID_SYS] =  6;
    AT91C_BASE_AIC->AIC_IECR = (1UL << AT91C_ID_SYS);
    AT91C_BASE_AIC->AIC_IECR |= 2;
    AT91C_BASE_AIC->AIC_IDCR &= ~2;

  // Loop forever
  for (;;)
  
  {
  j++;
  }


}


Стартап - стандартный из keil 3.80
Нажмите для просмотра прикрепленного файла

Помогите разобраться, вроде бы и все понятно, а затык sad.gif
aaarrr
Цитата(Shaienn @ Sep 9 2009, 09:00) *
Задача такая:
Запустить PIT, досчитать до чего-нибудь, вылететь в прерывание по флагу PITS.

Код в прерывании у Вас должен выставить в "1" PIOA.0 на втором прерывании - этого не происходит?

Мелкие замечания:
Код
    AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_PIOA)| (1 << AT91C_ID_SYS);

Клоки SYS включать не надо, такого бита попросту нет.

Код
    AT91C_BASE_AIC->AIC_IECR |= 2;
    AT91C_BASE_AIC->AIC_IDCR &= ~2;

Так с write-only регистрами работать нельзя.
Shaienn
Цитата(aaarrr @ Sep 9 2009, 15:27) *
Код в прерывании у Вас должен выставить в "1" PIOA.0 на втором прерывании - этого не происходит?

Есть такая отладочная плата. Т.е. с железной частью все в порядке. На ноге А0 стоит светодиод. При запуске этой программы светодиод гаснет и больше ничего не происходит.

Вопрос: Есть отладчик ULINK. При пошаговом проходе через JTAG прерывания должны срабатывать? Потому что у меня при пошаговом проходе программа не заходит в прерывание, а есть я ставлю brakepoint в теле прерывания и нажимаю run, то заходит.... Я этого не понимаю.

Цитата
Мелкие замечания:
Код
    AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_PIOA)| (1 << AT91C_ID_SYS);

Клоки SYS включать не надо, такого бита попросту нет.

Понятно.

Цитата
Код
    AT91C_BASE_AIC->AIC_IECR |= 2;
    AT91C_BASE_AIC->AIC_IDCR &= ~2;

Так с write-only регистрами работать нельзя.

Этот код взял отсюда. В принципе, насколько я понимаю, он идентичен по смыслу: AT91C_BASE_AIC->AIC_IECR = (1UL << AT91C_ID_SYS);
aaarrr
Цитата(Shaienn @ Sep 9 2009, 16:38) *
отладочная плата. Т.е. с железной частью все в порядке. На ноге А0 стоит светодиод. При запуске этой программы светодиод гаснет и больше ничего не происходит.

Программа выставляет A0 в "1", светодиод гаснет - все правильно.
Код
         if (i==1)
         {
         AT91C_BASE_PIOA->PIO_SODR = i;
         i=0;
         }
         else
         {
         AT91C_BASE_PIOA->PIO_SODR = i;
         i=1;
         }

При i = 0 - ничего не делаем, при i = 1 - ставим "1" на PA0. Если это была попытка выдать меандр, то нужно было сделать так:
Код
         if (i)
         {
             AT91C_BASE_PIOA->PIO_SODR = 1;
             i = 0;
         }
         else
         {
             AT91C_BASE_PIOA->PIO_CODR = 1;
             i = 1;
         }


Цитата(Shaienn @ Sep 9 2009, 16:38) *
Вопрос: Есть отладчик ULINK. При пошаговом проходе через JTAG прерывания должны срабатывать? Потому что у меня при пошаговом проходе программа не заходит в прерывание, а есть я ставлю brakepoint в теле прерывания и нажимаю run, то заходит.... Я этого не понимаю.

М.б. окно с регистрами AIC открыто?

Цитата(Shaienn @ Sep 9 2009, 16:38) *
Этот код взял отсюда. В принципе, насколько я понимаю, он идентичен по смыслу: AT91C_BASE_AIC->AIC_IECR = (1UL << AT91C_ID_SYS);

По смыслу он как раз не идентичен, т.к. содержит явную бессмыслицу.
Shaienn
Спасибо smile.gif Я, глупень, забыл, что в АРМ обнуление регистра выполняется не новой записью в этот регистр, а через соседний регистр CODR... Раньше кодил на AVR smile.gif

Все работает smile.gif
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.