реклама на сайте
подробности

 
 
4 страниц V  < 1 2 3 4 >  
Reply to this topicStart new topic
> прерывания от таймеров в SAM, опять затупил :(
AVR
сообщение Aug 5 2006, 22:50
Сообщение #31


фанат Linux'а
*****

Группа: Свой
Сообщений: 1 353
Регистрация: 23-10-05
Из: SPB.RU
Пользователь №: 10 008



Ура! Огромное спасибо всем за помощь! Срабатывает, и не раз =) Тему можно закрыть.
ЗЫ
Сегодня я самый счастливый нуб на свете =)

Сообщение отредактировал AVR - Aug 5 2006, 22:51


--------------------
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Aug 5 2006, 22:56
Сообщение #32


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата
Точно, всё аналогично AVRкам, тоже надо добавить прагму vector = 0x18 перед обработчиком IRQ =)

Что-то меня настораживает. Все же на 0x18 должно быть ldr pc, [pc, #-0xf20], или что-нибудь не столь лаконичное, но аналогичное по смыслу.
А pragma vector = 0x18 - какая-то вредная штуковина, ИМХО.
Go to the top of the page
 
+Quote Post
AVR
сообщение Aug 5 2006, 23:13
Сообщение #33


фанат Linux'а
*****

Группа: Свой
Сообщений: 1 353
Регистрация: 23-10-05
Из: SPB.RU
Пользователь №: 10 008



Цитата(aaarrr @ Aug 6 2006, 02:56) *
Что-то меня настораживает. Все же на 0x18 должно быть ldr pc, [pc, #-0xf20], или что-нибудь не столь лаконичное, но аналогичное по смыслу.
А pragma vector = 0x18 - какая-то вредная штуковина, ИМХО.

Не, всё на самом деле нормально, теперь по адресу 0x18 висит инструкция ldr pc, [pc, #+24]
А использование pragma vector = 0x18 прописано в справке на iccarm для обработчиков прерываний.


--------------------
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Aug 5 2006, 23:46
Сообщение #34


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Я тоже начинал с такого варианта прерываний. Он простой и файл стартап не нужно исправлять. Особенно если в системе только одно прерывание от таймера, то лучше вообще не мудрить.

Сообщение отредактировал GetSmart - Aug 5 2006, 23:49


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Aug 6 2006, 00:05
Сообщение #35


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Ну если так проще, тогда ладно.

P.S. Интересно, кто-нибудь еще использовал в своих проектах RTT?
Go to the top of the page
 
+Quote Post
AVR
сообщение Aug 6 2006, 12:20
Сообщение #36


фанат Linux'а
*****

Группа: Свой
Сообщений: 1 353
Регистрация: 23-10-05
Из: SPB.RU
Пользователь №: 10 008



Цитата(aaarrr @ Aug 6 2006, 04:05) *
P.S. Интересно, кто-нибудь еще использовал в своих проектах RTT?

У меня ещё вопрос возник: почему atmel называет это риалтайм таймером, если к нему подается только источник SLCK, частота которого только приблизительно равна 32768 Гц. Часы на таком явно не организовать... Есть ли возможность настроить на другой источник тактов?
ЗЫ
Можно ли и как заставить SAM7S пропускать MCK на один из выходов PIO, чтобы, например, тактировать внешнюю периферию такую как CPLD?
ЗЫЗЫ
Посоветуйте, пожалуйста, какую-нибудь микросхему SRAM в DIP корпусе на 64 КБайт.

Сообщение отредактировал AVR - Aug 6 2006, 12:44


--------------------
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Aug 6 2006, 13:53
Сообщение #37


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(AVR @ Aug 6 2006, 16:20) *
Есть ли возможность настроить на другой источник тактов?

Нет.

Цитата(AVR @ Aug 6 2006, 16:20) *
Можно ли и как заставить SAM7S пропускать MCK на один из выходов PIO, чтобы, например, тактировать внешнюю периферию такую как CPLD?

Можно. Почитайте про Programmable Clock Output в PMC.
Go to the top of the page
 
+Quote Post
AVR
сообщение Aug 8 2006, 11:57
Сообщение #38


фанат Linux'а
*****

Группа: Свой
Сообщений: 1 353
Регистрация: 23-10-05
Из: SPB.RU
Пользователь №: 10 008



Что нужно сделать, чтобы срабатывали несколько разных перерываний? Ведь тогда получается разные обработчики должны начинаться на 0x18, а одновременно это невозможно... Для чего тогда нужен AIC, если он сам автоматом не загружает в PC адрес нужно обработчика... blink.gif

Сообщение отредактировал AVR - Aug 8 2006, 11:58


--------------------
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Aug 8 2006, 12:07
Сообщение #39


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(AVR @ Aug 8 2006, 14:57) *
Что нужно сделать, чтобы срабатывали несколько разных перерываний? Ведь тогда получается разные обработчики должны начинаться на 0x18, а одновременно это невозможно... Для чего тогда нужен AIC, если он сам автоматом не загружает в PC адрес нужно обработчика... blink.gif

Код
__arm __irq void IRQ_Handler(void) {
     void (*AT91C_AIC_IVR)();
     AT91C_BASE_AIC->AT91C_AIC_EOICR = 0;
}

что-то вроде этого. Или же по адресу 0x18 в асмовом файле разместить
Код
        LDR        PC, AT91C_AIC_IVR
и каждый обработчик оформлять как __arm __irq не забывая в конце каждого обработчика вставлять AT91C_BASE_AIC->AT91C_AIC_EOICR = 0;


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
AVR
сообщение Aug 8 2006, 12:13
Сообщение #40


фанат Linux'а
*****

Группа: Свой
Сообщений: 1 353
Регистрация: 23-10-05
Из: SPB.RU
Пользователь №: 10 008



Сергей Борщ, спасибо a14.gif


--------------------
Go to the top of the page
 
+Quote Post
Timofey
сообщение Aug 16 2006, 05:33
Сообщение #41


Частый гость
**

Группа: Участник
Сообщений: 119
Регистрация: 3-07-06
Пользователь №: 18 528



Прошу прощения, что поднимаю старую тему и за очередной глупый для Вашего внимания вопрос, но ... объясните мне пожалуйста, в чем причина?
Использую таймер и он в обработчике виснет:


void channal (void)
{
for (int chan=0;chan<9;chan++){
while (!((AT91C_BASE_SPI->SPI_SR) & AT91C_SPI_TXEMPTY));
AT91F_SPI_CfgPCS(AT91C_BASE_SPI,0);
AT91F_SPI_PutChar (AT91C_BASE_SPI, SPI_SEND[chan],0 );
while (!((AT91C_BASE_SPI->SPI_SR) & AT91C_SPI_TXEMPTY));
AT91F_SPI_CfgPCS(AT91C_BASE_SPI,0);
AT91F_SPI_PutChar (AT91C_BASE_SPI, SPI_SEND[chan],0 );
while (!((AT91C_BASE_SPI->SPI_SR) & AT91C_SPI_TXEMPTY));
AT91F_SPI_CfgPCS(AT91C_BASE_SPI,0);
AT91F_SPI_PutChar (AT91C_BASE_SPI, SPI_SEND[chan],0 );
while (!((AT91C_BASE_SPI->SPI_SR) & AT91C_SPI_TXEMPTY));
tin=AT91F_SPI_GetChar(AT91C_BASE_SPI);
DATA[shet_i][chan]=tin & 0x0FFE;


switch (BUFF_STATUS[5]){
case 0x01:
DATA[shet_i][chan]=filt_niz_chas(DATA[shet_i][chan]);
break;

case 0x10:
DATA[shet_i][chan]=filt_vis_chas(DATA[shet_i][chan]);
break;

case 0x11:
DATA[shet_i][chan]=filt_niz_chas(DATA[shet_i][chan]);
DATA[shet_i][chan]=filt_vis_chas(DATA[shet_i][chan]);
break;
}

if (DATA[shet_i][chan]>max_data[chan]) max_data[chan]=DATA[shet_i][chan]; //находим максимум

BUFF_STATUS[(chan+7)*2+1]=max_data[chan];
BUFF_STATUS[(chan+7)*2]=max_data[chan] >> 8;
}



}


void Periodic_Interval_Timer_handler (void)
{
unsigned int status;

status = AT91C_BASE_PITC->PITC_PIVR;
status =status;

AT91F_PIO_ClearOutput(AT91C_BASE_PIOA, LED1);
spiflag=1;
channal();
AT91C_BASE_AIC->AIC_EOICR=0x00;
AT91F_PIO_SetOutput(AT91C_BASE_PIOA, LED1);
}


Инициализация таймера:
AT91F_PMC_EnablePeriphClock ( AT91C_BASE_PMC, 1 << AT91C_ID_PIOA ) ;
AT91F_AIC_ConfigureIt ( AT91C_BASE_AIC,
AT91C_ID_SYS,
RTTC_INTERRUPT_LEVEL,
AT91C_AIC_SRCTYPE_EXT_LOW_LEVEL,
Periodic_Interval_Timer_handler);
AT91C_BASE_PITC->PITC_PIMR = AT91C_PITC_PITEN | AT91C_PITC_PITIEN | PIV_2_MS;
AT91F_AIC_EnableIt (AT91C_BASE_AIC, AT91C_ID_SYS);



PIV_2_MS=467 //по моим подсчетам должно быть в районе 156 мксек, верно?


Вобщем при запуске программы лампочка загорается и почти мгновенно тухнет. Еле заметишь, вобщем такое ощущение что заходит один раз в прерывание и там остается, выполнив все. Частота SPI 15 МГц. По приблизительным подсчетам вся программа должна успевать выполнятся до следующего прерывания. Или я ошибаюсь? И вобще нужны ли ожидания перед отправкой 16-ти бит в SPI? Может эти вайлы вобще нафиг выкинуть? На shet_i не обращайте внимания, он обрабатывается в другой части программы, до которой не доходит.
Если закоментировать строку channal() то все работает .... то есть лампочка тускло так горит ....
Ставил __irq компилятор выдает ошибку: Error[Pe167]: argument of type "void (__arm __irq __atpcs *)(void)" is incompatible with parameter of type "void (*)()"
Прошу сильно не ругаться, и смеятся не до колик, собственно я еще полный ламер, а даташит читать - с английским не важнец .... Кстати, может кто нить подскажет где можно в Екатеринбурге купить книжку по SAM7 на РУССКОМ? Или может через инет заказать ....

Сообщение отредактировал Timofey - Aug 16 2006, 05:35
Go to the top of the page
 
+Quote Post
AVR
сообщение Aug 16 2006, 20:14
Сообщение #42


фанат Linux'а
*****

Группа: Свой
Сообщений: 1 353
Регистрация: 23-10-05
Из: SPB.RU
Пользователь №: 10 008



Цитата(Timofey @ Aug 16 2006, 09:33) *
Если закоментировать строку channal() то все работает .... то есть лампочка тускло так горит ....
Ставил __irq компилятор выдает ошибку: Error[Pe167]: argument of type "void (__arm __irq __atpcs *)(void)" is incompatible with parameter of type "void (*)()"

Я, конечно, и сам ламер, но всё же есть некоторые догадки...
По всей видимости, функция "channal" выполняется слишком долго (вообще помещать такие страшные функции в обработчики это не очень хорошо smile.gif ), попробуйте вынести её в основной цикл программы, а при срабатывании прерывания по таймеру просто инкрементируйте некую переменную, которая сообщит программе в основном цикле о том, что нужно вызвать channal (и при этом декрементируйте эту переменную). Если эта переменная будет больше единицы, значит channal выполняется дольше чем нужно.
ЗЫ
Попробуйте добавить такой код. Саму же функцию обработчика определенного прерывания нужно оформить как обычную функцию без __irq
Код
#pragma vector = 0x18
__irq __arm void IRQ()
{
    void (*IRQ_Handler)() = (void(*)())AT91C_BASE_AIC->AIC_IVR;
    IRQ_Handler();
    AT91C_BASE_AIC->AIC_EOICR = 0;
}


--------------------
Go to the top of the page
 
+Quote Post
Timofey
сообщение Aug 17 2006, 03:56
Сообщение #43


Частый гость
**

Группа: Участник
Сообщений: 119
Регистрация: 3-07-06
Пользователь №: 18 528



Цитата(AVR @ Aug 17 2006, 02:14) *
По всей видимости, функция "channal" выполняется слишком долго (вообще помещать такие страшные функции в обработчики это не очень хорошо smile.gif ), попробуйте вынести её в основной цикл программы, а при срабатывании прерывания по таймеру просто инкрементируйте некую переменную, которая сообщит программе в основном цикле о том, что нужно вызвать channal (и при этом декрементируйте эту переменную).

За код спасибо. На счет того что в прерывании лучше вобще ничего делать, я знаю, но дело в том что больше никак. Мне нужно все это делать именно в прерывании ... В этом то и фишка ...
Go to the top of the page
 
+Quote Post
SpiritDance
сообщение Sep 11 2006, 11:07
Сообщение #44


Дух погибшего транзистора
****

Группа: Свой
Сообщений: 877
Регистрация: 6-09-05
Из: Москва
Пользователь №: 8 288



Исходные данные

Инициализация
Код
void init_interrupt_PIT(t_uint32 Interval, void InterruptHandler(void))
{
    volatile t_uint32 temp;

//    if (InterruptHandler != NULL)
//    {
        AT91F_AIC_ConfigureIt(AT91C_BASE_AIC, AT91C_ID_SYS,
                              PIT_PRIORITY, AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE,
                              InterruptHandler);
//    }
//    else
//    {
//        AT91F_AIC_ConfigureIt(AT91C_BASE_AIC, AT91C_ID_SYS,
//                              PIT_PRIORITY, AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE,
//                              (void(*)(void))ih_PIT);
//    }
    temp = AT91C_BASE_PITC->PITC_PIVR;
    AT91C_BASE_PITC->PITC_PIMR = temp;

    AT91C_BASE_PITC->PITC_PIMR = (Interval & AT91C_PITC_PIV)
                               |
                               AT91C_PITC_PITEN
                               |
                               AT91C_PITC_PITIEN;
}

Вызов
Код
    init_interrupt_PIT(0x000000FF, (void(*)(void))ih_fromPIT);

Обработчик
Код
void ih_fromPIT(void) __irq
{
    if (AT91C_BASE_PITC->PITC_PISR & AT91C_PITC_PITS )
    {
        g_systemSignals.displayStart = 1;        
    }    
    /* îáðàáîò÷èê çàâåðøåí */
    AT91C_BASE_AIC->AIC_EOICR = 0;
}

Других обработчиков от системного контроллера нет.

Вопрос. Почему обработчик ни разу не вызывается? Что я не понимаю?


--------------------
Yes, there are two paths you can go by But in the long run Theres still time to change the road youre on.
Go to the top of the page
 
+Quote Post
SpiritDance
сообщение Sep 11 2006, 12:28
Сообщение #45


Дух погибшего транзистора
****

Группа: Свой
Сообщений: 877
Регистрация: 6-09-05
Из: Москва
Пользователь №: 8 288



Кто-нибудь может скинуть рабочий код для PIT?
Странно но заработало вот так (я там кстати включить прерывание забыл blush.gif )
Код
void init_interrupt_PIT(t_uint32 Interval, void InterruptHandler(void))
{
    if (InterruptHandler != NULL)
    {
        AT91F_AIC_ConfigureIt(AT91C_BASE_AIC, AT91C_ID_SYS,
                              PIT_PRIORITY, AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE,
                              InterruptHandler);
    }
    else
    {
        AT91F_AIC_ConfigureIt(AT91C_BASE_AIC, AT91C_ID_SYS,
                              PIT_PRIORITY, AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE,
                              (void(*)(void))ih_PIT);
    }
    AT91F_AIC_EnableIt(AT91C_BASE_AIC, AT91C_ID_SYS);

    AT91C_BASE_PITC->PITC_PIMR = (((__int64)(MCK / 16) * Interval / 1000000) & AT91C_PITC_PIV)
                               |
                               AT91C_PITC_PITEN
                               |
                               AT91C_PITC_PITIEN;
}

void ih_fromPIT(void) __irq
{
    volatile t_uint32 temp = 0;
    if (AT91C_BASE_PITC->PITC_PISR & AT91C_PITC_PITS )
    {
        g_systemSignals.displayStart = 1;
        temp = AT91C_BASE_PITC->PITC_PIVR;
    }    
    /* îáðàáîò÷èê çàâåðøåí */
    AT91C_BASE_AIC->AIC_EOICR = temp;
}

При этом если не читать PIVR флаг прерывания не снимается.
Отсюда вопрос каким образом от данного таймера получить интервал прерываний больший 20-разрядной части и зачем вообще нужен PICNT?


--------------------
Yes, there are two paths you can go by But in the long run Theres still time to change the road youre on.
Go to the top of the page
 
+Quote Post

4 страниц V  < 1 2 3 4 >
Reply to this topicStart new topic
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 21st July 2025 - 13:40
Рейтинг@Mail.ru


Страница сгенерированна за 0.01528 секунд с 7
ELECTRONIX ©2004-2016