1891ВМ12Я 0 5 августа, 2006 Опубликовано 5 августа, 2006 (изменено) · Жалоба Ура! Огромное спасибо всем за помощь! Срабатывает, и не раз =) Тему можно закрыть. ЗЫ Сегодня я самый счастливый нуб на свете =) Изменено 5 августа, 2006 пользователем AVR Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 69 5 августа, 2006 Опубликовано 5 августа, 2006 · Жалоба Точно, всё аналогично AVRкам, тоже надо добавить прагму vector = 0x18 перед обработчиком IRQ =) Что-то меня настораживает. Все же на 0x18 должно быть ldr pc, [pc, #-0xf20], или что-нибудь не столь лаконичное, но аналогичное по смыслу. А pragma vector = 0x18 - какая-то вредная штуковина, ИМХО. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
1891ВМ12Я 0 5 августа, 2006 Опубликовано 5 августа, 2006 · Жалоба Что-то меня настораживает. Все же на 0x18 должно быть ldr pc, [pc, #-0xf20], или что-нибудь не столь лаконичное, но аналогичное по смыслу. А pragma vector = 0x18 - какая-то вредная штуковина, ИМХО. Не, всё на самом деле нормально, теперь по адресу 0x18 висит инструкция ldr pc, [pc, #+24] А использование pragma vector = 0x18 прописано в справке на iccarm для обработчиков прерываний. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GetSmart 0 5 августа, 2006 Опубликовано 5 августа, 2006 (изменено) · Жалоба Я тоже начинал с такого варианта прерываний. Он простой и файл стартап не нужно исправлять. Особенно если в системе только одно прерывание от таймера, то лучше вообще не мудрить. Изменено 5 августа, 2006 пользователем GetSmart Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 69 6 августа, 2006 Опубликовано 6 августа, 2006 · Жалоба Ну если так проще, тогда ладно. P.S. Интересно, кто-нибудь еще использовал в своих проектах RTT? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
1891ВМ12Я 0 6 августа, 2006 Опубликовано 6 августа, 2006 (изменено) · Жалоба P.S. Интересно, кто-нибудь еще использовал в своих проектах RTT? У меня ещё вопрос возник: почему atmel называет это риалтайм таймером, если к нему подается только источник SLCK, частота которого только приблизительно равна 32768 Гц. Часы на таком явно не организовать... Есть ли возможность настроить на другой источник тактов? ЗЫ Можно ли и как заставить SAM7S пропускать MCK на один из выходов PIO, чтобы, например, тактировать внешнюю периферию такую как CPLD? ЗЫЗЫ Посоветуйте, пожалуйста, какую-нибудь микросхему SRAM в DIP корпусе на 64 КБайт. Изменено 6 августа, 2006 пользователем AVR Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 69 6 августа, 2006 Опубликовано 6 августа, 2006 · Жалоба Есть ли возможность настроить на другой источник тактов? Нет. Можно ли и как заставить SAM7S пропускать MCK на один из выходов PIO, чтобы, например, тактировать внешнюю периферию такую как CPLD? Можно. Почитайте про Programmable Clock Output в PMC. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
1891ВМ12Я 0 8 августа, 2006 Опубликовано 8 августа, 2006 (изменено) · Жалоба Что нужно сделать, чтобы срабатывали несколько разных перерываний? Ведь тогда получается разные обработчики должны начинаться на 0x18, а одновременно это невозможно... Для чего тогда нужен AIC, если он сам автоматом не загружает в PC адрес нужно обработчика... :blink: Изменено 8 августа, 2006 пользователем AVR Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 143 8 августа, 2006 Опубликовано 8 августа, 2006 · Жалоба Что нужно сделать, чтобы срабатывали несколько разных перерываний? Ведь тогда получается разные обработчики должны начинаться на 0x18, а одновременно это невозможно... Для чего тогда нужен AIC, если он сам автоматом не загружает в PC адрес нужно обработчика... :blink: __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; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
1891ВМ12Я 0 8 августа, 2006 Опубликовано 8 августа, 2006 · Жалоба Сергей Борщ, спасибо :a14: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Timofey_219 0 16 августа, 2006 Опубликовано 16 августа, 2006 (изменено) · Жалоба Прошу прощения, что поднимаю старую тему и за очередной глупый для Вашего внимания вопрос, но ... объясните мне пожалуйста, в чем причина? Использую таймер и он в обработчике виснет: 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 на РУССКОМ? Или может через инет заказать .... Изменено 16 августа, 2006 пользователем Timofey Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
1891ВМ12Я 0 16 августа, 2006 Опубликовано 16 августа, 2006 · Жалоба Если закоментировать строку channal() то все работает .... то есть лампочка тускло так горит .... Ставил __irq компилятор выдает ошибку: Error[Pe167]: argument of type "void (__arm __irq __atpcs *)(void)" is incompatible with parameter of type "void (*)()" Я, конечно, и сам ламер, но всё же есть некоторые догадки... По всей видимости, функция "channal" выполняется слишком долго (вообще помещать такие страшные функции в обработчики это не очень хорошо :) ), попробуйте вынести её в основной цикл программы, а при срабатывании прерывания по таймеру просто инкрементируйте некую переменную, которая сообщит программе в основном цикле о том, что нужно вызвать 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; } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Timofey_219 0 17 августа, 2006 Опубликовано 17 августа, 2006 · Жалоба По всей видимости, функция "channal" выполняется слишком долго (вообще помещать такие страшные функции в обработчики это не очень хорошо :) ), попробуйте вынести её в основной цикл программы, а при срабатывании прерывания по таймеру просто инкрементируйте некую переменную, которая сообщит программе в основном цикле о том, что нужно вызвать channal (и при этом декрементируйте эту переменную). За код спасибо. На счет того что в прерывании лучше вобще ничего делать, я знаю, но дело в том что больше никак. Мне нужно все это делать именно в прерывании ... В этом то и фишка ... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SpiritDance 0 11 сентября, 2006 Опубликовано 11 сентября, 2006 · Жалоба Исходные данные Инициализация 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; } Других обработчиков от системного контроллера нет. Вопрос. Почему обработчик ни разу не вызывается? Что я не понимаю? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SpiritDance 0 11 сентября, 2006 Опубликовано 11 сентября, 2006 · Жалоба Кто-нибудь может скинуть рабочий код для PIT? Странно но заработало вот так (я там кстати включить прерывание забыл ) 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? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться