Faris 1 30 марта, 2009 Опубликовано 30 марта, 2009 · Жалоба Добрый день! Недавно начал изучать программирование под ARM. Не пойму где в моем коде ошибка. IAR 5.30 - LPC2378 Помогите, пожалуйста! Proba.zip Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
xvr 12 31 марта, 2009 Опубликовано 31 марта, 2009 · Жалоба Для начала в описании counter поставить volatile Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Faris 1 31 марта, 2009 Опубликовано 31 марта, 2009 · Жалоба Вылетаю в Abort_Handler ! Видимо, программа обращается по запрещенному адресу ?! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Student Pupkin 0 2 апреля, 2009 Опубликовано 2 апреля, 2009 · Жалоба Вылетаю в Abort_Handler ! Видимо, программа обращается по запрещенному адресу ?! Странный обработчик прерывания.... irq __arm void Timer0_Handler(void) { T0IR = 1; // сброс флага прерывания counter++; VICADDRESS = 0; } Должно быть так (вроде бы): //Функция обработки прерывания IRQ __arm __irq void IRQ_Handler(){ void (*pISR)(); pISR=(void(*)())VICADDRESS; (*pISR)(); VICADDRESS=0; } Потом что за функция - install_handler? Какие то манипуляции .... Ничего не понял, да и не разбирался. А где настройка контроллера прерываний - VIC? Что-то типа этого: //Настройка VIC на обработку прерываний от таймера (TIMER0) void VIC_init(){ void (*pIRQ)(); VICINTENCLEAR = 0xFFFFFFFF; VICINTENABLE = (1UL << VIC_TIMER0); pIRQ=timer_isr; VICVECTADDR4=(unsigned long)pIRQ; } Это куски из моей первой программы, правда для LPC2478, но они вроде с LPC23xx похожи в этом плане. Светодиод мигал как миленький. Фунция timer_isr описана где-то дальше, в ней собственно и делаете все, что нужно (очистка флага прерывания от таймера, включить-выключить светодиод и т.д.). Советую почитать User Manual, при контроллер прерываний VIC. Кстати, вещи типа vec |= 0xea000000; /* add opcode for B instruction */ делать вроде бы не нужно. При объявлении(определении) __arm __irq функции компилятор поместит в таблице векторов исключений команду перехода на нее. Идея тут вообщем такая - описываете функцию __arm __irq void IRQ_Handler(), ничего с таблицей векторов мудрить не надо. В этой функции - читаете из VICADDRESS (регистр в VIC - см. доку) адресс попрограммы обработки прерывания и вызываете ее. Если источников прерываний несколько, то VIC выставит нужный адресс , для каждого источника прерывания свой, с учетом приоритетов и т.д. Естественно предварительно необходимо настроить сам VIC - разрешить нужные прерывания, расставить приоритеты, прописать адреса обработчиков прерываний. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Faris 1 4 апреля, 2009 Опубликовано 4 апреля, 2009 · Жалоба Немного доработал программу и все заработало! :08: #include <nxp/iolpc2378.h> //#include "device.h" char counter = 0; char flag = 0; __irq __arm void Timer0_Handler(void) { flag = 1; T0IR = 1; // сброс флага прерывания VICADDRESS = 0; } //============================================================================ void Init_Timer0(void) { T0PR = 12000; // предделитель для импульсов 1 мс T0MR0 = 1000; // до этого значения считаем, =1сек T0TCR = 2; // сброс счетчика и предделителя таймера 0 T0MCR = 3; // сброс и прерывание от совпадения от MR0 T0TCR = 1; // разрешить таймер 0 VICVECTADDR4 = (unsigned long)Timer0_Handler; // присваиваем адрес вектора прерывания VICVECTPRIORITY4 = 3; // приоритет не более 3 VICINTENABLE = (1 << VIC_TIMER0); // разрешить прерывание } //=========================================================================== int main() { // Init_PLL(); Init_Timer0(); while (1) { if (flag == 1){ flag = 0; counter >>= 1; if (counter == 0) { counter = 0x80; } FIO2CLR = 0xFF; FIO2SET = counter; } } } только вот не пойму, почему в строке VICVECTPRIORITY4 = 3; когда ставлю приоритет равным более 4 , то программа не работает! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться