Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Обработка прерывания от SPI
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Bulat
1. Какому источнику прерывания в регистре AIC_IECR (PID2, 3, 4,...) соответствует прерывание от SPI?
2. Вектор прерывания ARM находится по адресу 0х18. Можно по этому адресу записать команду, типа goto "метка", а метку уже поставить рядом с функцией обработки прерывания, ну и таким образом вызвать функцию обработки прерывания? Ну даже если делать как написано в документации, т.е. производить чтение AIC_IVR, то как именно по адресу 0х18 записать нужную команду. Я понимаю так:

adr[int()]=0x18; //задаем адрес ф-ии int()
void int()
{
goto 1;
}
1: void irq() //функция обрабоки прерывания
{
...
}

Только оператор adr[] IAR не воспринимает.
3. Как по другому задать адрес функции?
Если можно то напишите свой вариант кода на С.
Заранее благодарен!
SpiritDance
1 гыгы
В даташите от атмела есть загадочные места. smile.gif На самом деле узнать ID можно глянув на включаемый файл.
#define AT91C_ID_SPI ((unsigned int) 5) // Serial Peripheral Interface

2.
Нифига не понял. если Вы про то как сконфигурировать AIC то
функция AT91F_AIC_ConfigureIt из файла lib_at91sam7s256.h Вам поможет

3. Что означает вопрос не понял. Получить адрес функции в С просто - это ее имя.
Сергей Борщ
Цитата(Bulat @ Mar 30 2007, 08:53) *
Если можно то напишите свой вариант кода на С.
Вот тут посмотрите. Как раз описывал несколько возможных вариантов.
Bulat
Цитата(Сергей Борщ @ Mar 30 2007, 14:39) *
Вот тут посмотрите. Как раз описывал несколько возможных вариантов.

Спасибо за ссылку!
Посмотрев подход №2 у меня возникло несколько вопросов.

Цитата
2) Делается одна функция-обработчик в которой делается сохранение/восстановление регистров и из этой функции вызываются обработчики, которые представляют из себя обычные функции. Функция-обработчик "подвешивается" на вектор исключения стандартными средствами компилятора:
#pragma vector = 0x0000018
__irq __arm void IRQ_Switch() {
(void (*)(void))(AT91C_BASE_AIC->AT91C_AIC_IVR)();
AT91C_BASE_AIC->AIC_EOICR = 0;
}


void Handler1() {
...........
}
void Handler2() {
...........
}


1)
Цитата
(void (*)(void))(AT91C_BASE_AIC->AT91C_AIC_IVR)();

Что означает (void (*)void))? У меня и компилятор ошибку выдает: expected a field name.
Можно подробнее описать этот момент.
2) Получается в конце функции
Цитата
void Handler1() { ...........}
не надо обнулять
AIC_EOICR?
Заранее благодарен!
3) Функция Handler1() соответствует источнику прерывания PID1?
SpiritDance
Цитата(Bulat @ Apr 6 2007, 08:47) *
1)
Что означает (void (*)void))? У меня и компилятор ошибку выдает: expected a field name.
Можно подробнее описать этот момент.


приведение к типу "указатель на функцию получающую void и возвращающую void" А ругается может потому что скобочку пропустили (void (*)( void))

Цитата(Bulat @ Apr 6 2007, 08:47) *
2) Получается в конце функции не надо обнулять
AIC_EOICR?


Если обработчик прерывания общий то не стоит.
Rahhal
Пардон, если пишу глупость, но:
правильно ли я понимаю, что вектор прерывания связан с источником, а не с событием, и еслиу нас прерывания по нескольким событиям (конец передачи, конец приема и т.д.) от одного источника (UART, SPI...) ВЫЗЫВАЕТСЯ ОДИН И ТОТ ЖЕ обработчик, а в нем сам программист разбирается, что произошло за событие?
SpiritDance
Да
Rahhal
Спасибо!
Bulat
Цитата(SpiritDance @ Apr 6 2007, 12:34) *
приведение к типу "указатель на функцию получающую void и возвращающую void" А ругается может потому что скобочку пропустили (void (*)( void))

Недостающую скобку я поставил, но ошибку всеравно выдает.

И еще по поводу моего третьего вопроса. Если пришел запрос на обработку прерывания от источника PID1, то вызывается функция Handler1(), если от PID2, то Handler2()?

Заранее благодарен!
Сергей Борщ
Цитата(Bulat @ Apr 9 2007, 06:37) *
Недостающую скобку я поставил, но ошибку всеравно выдает.
expected a field name. Посмотрите как описан регистр AT91C_AIC_IVR в заголовочном файле вашего компилятора. Похоже, что AT91C_BASE_AIC описан не как структура и AT91C_AIC_IVR не ее член. Хотя, вы упоминаете IAR, тогда вопрос: какой заголовочный файл (ioAT91xxxxx.h) вы используете?
Цитата(Bulat @ Apr 9 2007, 06:37) *
И еще по поводу моего третьего вопроса. Если пришел запрос на обработку прерывания от источника PID1, то вызывается функция Handler1(), если от PID2, то Handler2()?
Будет вызван тот Handler, адрес которого вы занесете в соответствующий регистр AIC_SVR при инициализации, например:
Код
    AT91C_BASE_AIC->AIC_SVR[AT91C_ID_SYS] = (uint32_t)Handler1;
    AT91C_BASE_AIC->AIC_SVR[AT91C_ID_SPI] = (uint32_t)Handler2;
строка (void (*)(void))(AT91C_BASE_AIC->AT91C_AIC_IVR)(); дословно означает следующее: взять число из регистра AT91C_AIC_IVR, представить себе, что это адрес функции и вызвать функцию по этому адресу. После возврата из функции программа попадет на следующую команду, т.е. на AT91C_BASE_AIC->AIC_EOICR = 0, как и с обычной функцией. Адрес в AT91C_AIC_IVR заносит контроллер прерываний (AIC). Как он это делает - попробуйте понять из описания контроллера.
SpiritDance
Цитата(Сергей Борщ @ Apr 9 2007, 23:26) *
Как он это делает - попробуйте понять из описания контроллера.

biggrin.gif
Sergei_K
Здравствуйте. У меня та же проблема, что у автора.. разбираюсь с прерываниями.. smile.gif
Собсно, заношу в программу код:

__irq __arm void IRQ_Handler1() {



AT91C_BASE_AIC->AIC_EOICR = 0;
}


При компиляции выдает ошибки:

main.c(52): error: #40: expected an identifier
main.c(52): error: #1021: __irq functions must return no result

При занесении:

__irq __arm void IRQ_Switch() {
(void (*)(void))(AT91C_BASE_AIC->AT91C_AIC_IVR)();
AT91C_BASE_AIC->AIC_EOICR = 0;
}


void Handler1() {

}
void Handler2() {

}

к ним добавляется ошибка:

main.c(53): error: #134: expected a field name

Таким образом, это навевает следующий вопрос: можно ли вобще таким образом работать в Keil (именно в нем я и работаю smile.gif ), а если можно - как избавиться от этих ошибок... Если нет - то как с ними работать..
Возможно, если бы знающие люди выложили более полный код (пример) и вопросы бы отпали smile.gif

P.S. Эх.. старый добрый 51.. как все было просто smile.gif
Сергей Борщ
Цитата(Sergei_K @ Apr 10 2007, 11:24) *
Таким образом, это навевает следующий вопрос: можно ли вобще таким образом работать в Keil
Примеры были под IAR. Похоже, у кейла нет ключевого слова __arm, именно на него и ругается компилятор (expected an identifier, __irq functions must return no result). Посмотрите в хелпе как описать arm-функцию.
Цитата(Sergei_K @ Apr 10 2007, 11:24) *
error: #134: expected a field name
Пришлите почтой заголовочный файл с описанием SFR от кейла, посмотрю в чем тут дело.
Sergei_K
С arm-функцией разобрался, спасибо...
Насчет заголовочного файла - вашу почту не нашел, потому выкладываю прямо здесь...
Сергей Борщ
Цитата(Sergei_K @ Apr 11 2007, 11:21) *
Насчет заголовочного файла - вашу почту не нашел, потому выкладываю прямо здесь...
"Какой осел, какой осел!" Писал эту строчку сразу в форум, вот потому и ошибка. Должно быть:
Код
(void (*)(void))(AT91C_BASE_AIC->AIC_IVR)();
или (void (*)(void))(AT91C_AIC_IVR)();
Я всегда пользуюсь вариантом с размещением по вектору команды
Код
        LDR        PC, AT91C_AIC_IVR
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.