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

IAR 5.30 - LPC2378

Помогите, пожалуйста!
XVR
Для начала в описании counter поставить volatile
BlackHead
Вылетаю в Abort_Handler !
Видимо, программа обращается по запрещенному адресу ?!
Student Pupkin
Цитата(BlackHead @ Mar 31 2009, 15:56) *
Вылетаю в 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 - разрешить нужные прерывания, расставить приоритеты, прописать адреса обработчиков прерываний.
BlackHead
Немного доработал программу и все заработало! 08.gif

CODE
#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 , то программа не работает!
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.