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

Может я не туда смотрю ? Глава "13 ARM Cortex® M3 Processor " в ней на стр 167 "13.19 Nested Vectored Interrupt Controller"
Или может ещё где можно почитать ?
IgorKossak
Документацию на ядро следует искать на сайте ARM.
В левой колонке выберите что надо.
MiklPolikov
Цитата(IgorKossak @ Jan 28 2011, 10:59) *
Документацию на ядро следует искать на сайте ARM.
В левой колонке выберите что надо.


Там то же самое что и в pdf , названия 7 регистров почти без описания :
ISER0, ICER0, ISPR0, ICPR0, IABR0, IPR0-IPR7, STIR

А адрес финкции обработкика прерывания как задать ? Явно ведь что не через эти регистры.
DpInRock
стр. 182
MiklPolikov
Почему относящиеся к NVIC регистры ISER ICER ISPR ... не прописаны в библиотеках, которые идут вместе с Keil , например AT91SAM3U4.h ?
DpInRock
А не пробовали ради простого человеческого любопытства заглянуть краем глаза в другие хидеры?
В общем-то чисто так, NVIC - это не совсем периферия конкретной модели, а скорее принадлежность ядра...
aaarrr
Цитата(MiklPolikov @ Jan 29 2011, 03:48) *
AT91SAM3U4.h ?

Если это атмеловский заголовок, то все там замечательно приписано.
MiklPolikov
В примере атмела прерывание настраивается вот такой функцией

Код
IRQ_ConfigureIT(AT91C_ID_RTT, 0, RTT_IRQHandler);


RTT_IRQHandler - функция обработчик .
Она хоть и передайтся в IRQ_ConfigureIT, нотам ни как не используется. Выходит , это работать не будет ?! Может кто-нибудь дать работающий пример ?


Код
void IRQ_ConfigureIT(
    unsigned int source,
    //unsigned int preemptionPriority,
    //unsigned int subPriority,
    unsigned int priority,
    IntFunc handler)
{
    unsigned int priGroup = __NVIC_PRIO_BITS;
    unsigned int nPre = 8 - priGroup;
    unsigned int nSub = priGroup;
    unsigned int preemptionPriority;
    unsigned int subPriority;
    unsigned int IRQpriority;

    preemptionPriority = (priority & 0xff00) >> 8;
    subPriority = (priority & 0xff);

    // Disable the interrupt first
    NVIC_DisableIRQ((IRQn_Type)source);

    // Clear any pending status
    NVIC_ClearPendingIRQ((IRQn_Type)source);

    // Configure interrupt handler
    //if (handler == 0) handler = IrqHandlerNotUsed;
      //  GetExceptionTable()[NVIC_IRQ_HANDLER_INDEX + source] = handler;

    if (subPriority >= (0x01 << nSu)
      subPriority = (0x01 << nSu - 1;
    if (preemptionPriority >= (0x01 << nPre))
      preemptionPriority = (0x01 << nPre) - 1;

    IRQpriority = (subPriority | (preemptionPriority << nSu);
    NVIC_SetPriority((IRQn_Type)source, IRQpriority);
}
aaarrr
Цитата(MiklPolikov @ Jan 30 2011, 15:41) *
Выходит , это работать не будет ?!

Будет. Просто таблица векторов в примере расположена во флеш и инициализируется, соответственно, еще на этапе линковки.
MiklPolikov
Вот оно ! Работающее прерывание от порта !
Код для Keil . PIOA_IRQHandler прописан в STARTAP.s который кейл создаёт сам.


Код
#include "AT91SAM3U4.h"       //это файл не Кейла, а Атмела.  Они имеют одинаковые названия, но отличаются.


#define  LED_ON   *AT91C_PIOB_CODR|=AT91C_PIO_PB0   //Включаем светодиод
#define  LED_OFF  *AT91C_PIOB_SODR|=AT91C_PIO_PB0   //Выключаем светодиод
#define  CHECK_LED   (!(*AT91C_PIOB_PDSR&AT91C_PIO_PB0)) // возвращает   1 если светодиод горит


////////////////настраиваем порт////////////////////
void  INIT_GPIO(void)
{
    ///PB0 выход на светодиод
    *AT91C_PIOB_PER|=AT91C_PIO_PB0;
    *AT91C_PIOB_OER|=AT91C_PIO_PB0;

    ///PA18 PA19  входы кнопок
   *AT91C_PIOA_PER|=AT91C_PIO_PA18|AT91C_PIO_PA19;
   *AT91C_PIOA_PPUER|=AT91C_PIO_PA18|AT91C_PIO_PA19;  // включаем подтягивающие разисторы    
   *AT91C_PIOA_IER|=AT91C_PIO_PA18|AT91C_PIO_PA19;       //разрешаем прерывания    
   *AT91C_PIOA_AIMER|=AT91C_PIO_PA18|AT91C_PIO_PA19;  // событие, вызывающее прерывание, описано в PIO_ELSR и PIO_FRLHSR.          
}
              
///////////////прерывание от  PIOA//////////////////
__irq void PIOA_IRQHandler (void)
{
    volatile unsigned int status;

    status=*AT91C_PIOA_ISR; //сбрасываем флаг прерывания

    if(CHECK_LED)    
       LED_OFF;
    else
       LED_ON;
}


////////////////Настраиваем прерывание от таймера RTT//////////////
void INIT_PIOA_IRQ(void)
{
     AT91C_BASE_NVIC->NVIC_IPR[5]=(5<<20);  // устанавливаем приоритет 5 прерывания.
     AT91C_BASE_NVIC->NVIC_ISER[0]=(1<<AT91C_ID_PIOA);   //включаем прерывание
}

int main(void)
{
     *AT91C_PMC_PCER =0xFFFFFFFF;        //включаем всю периферию.
     INIT_GPIO();
     INIT_PIOA_IRQ();    

     *AT91C_WDTC_WDMR=AT91C_WDTC_WDDIS; //отключаем WDT

     while(1){}
}
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.