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

Стоит задача: необходимо каждые 2 мкс, опрашивать АЦП. И так в течении 2 милисек. Т.е. сделать 1000 отсчетов.
Исходные данные: LPC2194, компилятор IAR, 60 МГц.
Ввиду того, что других прерываний воопче нет, поставил на обработчик прерываний таймера FIQ опрос АЦП. Но опрос происходит всего один раз, при запуске программы.
Как мне настроить прерывания на FIQ от таймера? И как реализовать опрос 1000 раз?-Так как после оцифровки мне нужно обработать данные.
Сейчас я в программе обработки прерывания, поставил счетчик и просто слежу за ним.
И как отследить окончание оцифровки в основной программе?

Интересует именно код....

Заранее большое спасибо!
Methane
А у вас таймер вообще запрограммирован чтобы второй раз сработать?
bullit
Запускаю таймер: T0TCR = 1;
Останавливаю командой: T0TCR = 0;
Получается необходимо запускать T0TCR = 1; а останавливать: T0TCR = 2; Проглядел!

Но вот что я заметил: если зациклить опрос АЦП for-ом, то минимальное время достигает 1,8 мкс. А при применении таймера минимум я выжал 3,5 мкс. Как можно оптимизировать?
SasaVitebsk
Цитата(bullit @ May 19 2009, 16:34) *
Стоит задача: необходимо каждые 2 мкс, опрашивать АЦП. И так в течении 2 милисек. Т.е. сделать 1000 отсчетов.
Исходные данные: LPC2194, компилятор IAR, 60 МГц.

Предполагаю, что на LPC вы вообще с 2 мкс опрашивать ничего не сможете. smile.gif Даже таймер опросом. smile.gif
Ну а прерывания и подавно. smile.gif
Согласно даташиту (1-ый лист):
Four channel 10-bit ADC with conversion time as low as 2.44 μs

То есть уже выше. smile.gif Иными словами без таймера в цикле вы не получите выше 2.44mks. Но мой прогноз что ещё раза в полтора умножь на работу с переферией. Медленная до ужаса.

Цитата(bullit @ May 19 2009, 19:19) *
Но вот что я заметил: если зациклить опрос АЦП for-ом, то минимальное время достигает 1,8 мкс. А при применении таймера минимум я выжал 3,5 мкс. Как можно оптимизировать?

При применении таймера опросом всётаки 3 мкс захватить получается. Меньше - никак. По крайней мере для LPC2106F/00.
bullit
Во время опроса АЦП, мк не выполняет ни каких операций - только работа на прерывания.
Да забыл уточнить - опрос не встроенного АЦП, а внешнего.
CODE
void ReadADC(void)
{
u8 mb;
u8 sb;
u8 *ptr1 = (u8 *)&data[0];
u8 *ptr2 = (u8 *)&data2[0];
for (u16 i = 0; i<=999; i++) {
CONV_START
READ_LOWBYTE1
READ_LOWBYTE2
CONV_STOP
while(BUSY_ADC1 == 1){}; //Ждем Busy
// Чтение с первого канала
START_READ1
START_READ1
mb = FIO0PIN0;
*ptr1++ = (mb);
READ_HIGHBYTE1
START_READ1
sb = FIO0PIN0;
*ptr1++ = (sb);
STOP_READ1
// Чтение со второго канала
START_READ2
mb = FIO0PIN0;
*ptr2++ = (mb);//& 0xff
READ_HIGHBYTE2
sb = FIO0PIN0;
*ptr2++ = (sb);
STOP_READ2
}// конец for
CONV_STOP
}


Вот этот for и вставлен в прерывание (точнее его содержимое), а затем if-ом проверяю счетчик (думается самое слабое место)... остальные переменные объявленны как глобальные....
SasaVitebsk
Цитата(bullit @ May 19 2009, 19:36) *
Вот этот for и вставлен в прерывание (точнее его содержимое), а затем if-ом проверяю счетчик (думается самое слабое место)... остальные переменные объявленны как глобальные....

Как то у вас всё сумбурно получается.
Из первого поста можно понять, что вы каждый опрос ацп пытаетесь запустить от таймера. При этом сам цикл измерения составляет 2 мкс.
В приведенной цитате вы пишите о том, что вы в обработчик запихиваете for с опросом 990 раз. Причём в каждом опросе вы минимум 3 раза читаете порт. Предполагаю, что минимум 2 раза в него пишите чтобы запустить преобразование. (Предполагаю, так как не вижу раскрытых макросов).
То есть само прерывание у вас довольно громоздко.

Тем не менее сам принцип я попробую описать.
У меня это выглядит так.
Инициализация

// Если мастер, то регенерация экрана осуществляется по таймеру
T0IR = (uint32_t)-1; // сбросить флаги прерываний
T0TCR = (1<<1)|(1<<0); // разрешить работу таймера
T0TCR = (1<<0); // разрешить работу таймера
T0PR = 0; // прескалер = 1

T0MR0 = PCLK / (FREGENER*8*7); // Частота прерываний FREGENER герц * 8 строк * 8 градаций яркости (-1)
T0MCR = (1<<1)|(1<<0); // режим перезагрузки и прерывание

вызов прерывания
__fiq __arm void FIQ_Handler() // Отображение картинки Master, Slave

завершение
T0IR = (unsigned)-1; // сбросить флаги прерываний таймера



Да забыл ещё в инициализации это
VICIntSelect = (1<<VIC_TIMER0); // Прерывание от таймера 0 = FIQ
VICIntEnable = (1<<VIC_TIMER0)|(1<<VIC_UART0); // Разрешить прерывание от таймера 0 и от USART0
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.