Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Нужен пример прерывания
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > ARM, 32bit
_Pavel
В апнотах посмотрел, но осталось много вопросов (голого примера прерывания не нашел). Еще хотел бы еще разобраться с программируемым контроллером клоков.
_Pavel
Забыл камень указать - AT91SAM7X
sergeeff
На нашем форуме неоднократно этот вопрос самым подробным образом рассматривался. Что вам не понятно? Какой конкретный пример вы желаете видеть? Чем не устраивают примеры, приведенные Atmel'ом в своих многочисленных примерах? Конкретизируйте!
rezident
Сообщение модератора.
Корневое сообщение топика нарушает п.2.1в Правил форума и больше походит на флуд. _Pavel, конкретизируйте и сформулируйте Ваши вопросы более тщательно. Когда сформулируете конкретные вопросы, тогда и пишите сюда.
Ну и пользуйтесь поиском по форуму. Примеров тут "вагон и маленькая тележка".
_Pavel
Извиняюсь, что совсем абстрактно написал, просто лет 8 не занимался контроллерами. Тогда использовал PIC и 8051, они очень понятные, а сейчас взял АРМ. В поиске посмотрел по ключевому слову "прерывание", но там рассматриваются уже тонкие вопросы.
Пример хотел найти типа - подал на ножку единицу, вызвалось прерывание и зажгло на секунду светодиод.
Глупые вопросы задавать не хотелось бы, с простым примером и с хелпом сам бы разобрался.
Взял пример VirtualCOM, там вроде как есть прерывания. Как я понял вся конфигурация и вектора прерываний задаются в .S файле и по нему возникли вопросы:
CODE

Vectors LDR PC,Reset_Addr
LDR PC,Undef_Addr
LDR PC,SWI_Addr
LDR PC,PAbt_Addr
LDR PC,DAbt_Addr
NOP ; Reserved Vector
; LDR PC,IRQ_Addr
LDR PC,[PC,#-0xF20] ; Vector From AIC_IVR - Так вот непонятно где в программе этот адрес?
; LDR PC,FIQ_Addr
LDR PC,[PC,#-0xF20] ; Vector From AIC_FVR
.........................
Reset_Addr DCD Reset_Handler
Undef_Addr DCD Undef_Handler
SWI_Addr DCD SWI_Handler ;вот эта директива непонятно, что делает?
...........................
Undef_Handler B Undef_Handler
;SWI_Handler B SWI_Handler
PAbt_Handler B PAbt_Handler ;и вот такие бесконечные цыклы непонятно зачем нужны?
sergeeff
У ARM RISC-система команд, т.е. команда всегда помещается в 32 бита (про Thumb режим пока опустим). Таким образом, если надо в качества операнда указать полный 32-разрядный адрес, приходится использовать обходные решения. В вашем коде вы и имеете такой пример.

Про бесконечный цикл. Можно ведь на прерывания никак не реагировать. Программа просто куда-то улетит при возникновении прерывания с непредсказуемым результатом (может и флеш порушится). А так у вас пример реализации предсказуемой реакции на прерывание по Abort'у (вваливание в бесконечный цикл). Радости (пользы программисту) от такой реализации почти никакой, но хоть ничего плохого не произойдет.
_Pavel
Можно еще один глупый вопрос - как связать метку как в этих командах
LDR PC,SWI_Addr
LDR PC,PAbt_Addr
LDR PC,DAbt_Addr
с процедурой в программе? В примере есть чето типа: static __irq void ser_irq_0 (void) { , это то?
sergeeff
Цитата(_Pavel @ Nov 22 2009, 16:37) *
Можно еще один глупый вопрос - как связать метку как в этих командах
LDR PC,SWI_Addr
LDR PC,PAbt_Addr
LDR PC,DAbt_Addr
с процедурой в программе? В примере есть чето типа: static __irq void ser_irq_0 (void) { , это то?


Обычно обработка прерываний от устройств производится совместно с контроллером прерываний. Вот ему и надо сообщить адрес вашей процедуры ser_irq_0 (посмотрите примеры на эту тему). А поддержка собственно контроллера прерываний уже у вас обеспечена в таблице прерываний командой LDR PC,[PC,#-0xF20].
_Pavel
Спасибо, немного понял, буду с настройкой AIC разбираться
Shaienn
Вот простой пример рабочего прерывания.

Код
#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)
         {
             AT91C_BASE_PIOA->PIO_SODR = 1;
             i = 0;
         }
         else
         {
             AT91C_BASE_PIOA->PIO_CODR = 1;
             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 = 0x00000001;
    AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_PIOA);
    AT91C_BASE_PITC->PITC_PIMR = AT91C_PITC_PITEN|AT91C_PITC_PITIEN|0x0ffff7;
    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);
  // Loop forever
  for (;;)

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