Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: LPC2478. Запуск АЦП по таймеру. Перенёс из В помощь начинающему
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Oleg_IT
Нужно набрать отсчеты АЦП в буфер и передать их по изернет. С изернет всё нормально, а когда включаю АЦП прерывания от него забивают всё и не дают выполняться основному циклу, передача по изернет соответственно встаёт. И ни какой синхронизации АЦП и таймера нет.
Инициализирую таймеры
Для изернета, взято из примера

Код
    T1MCR = (3 << 0);
    T1MR0 = TCNT - 1;
    T1TCR = 1;

Для АЦП

Код
    PINSEL3 |= (3 << 26);
    T0MCR = (1 << 4);  // MR1: Reset
    T0MR1 = 0x00100000;
    T0EMR = (1 << 1) |     // MAT0.1  P1[29]
                     (3 << 6);      //
    T0TCR = 1;

На выходе P1.29 имею меандр, частота управляется (T0MR1).

Инициализирую АЦП, взято из примера

Код
    PCONP |= (1 << 12);
    AD0CR = ( 0x01 << 0 ) |     /* SEL=1,select channel 0~7 on ADC0 */
        ( ( Fpclk / ADC_Clk - 1 ) << 8 ) |  /* CLKDIV = Fpclk / 4000000 - 1 */
        ( 1 << 16 ) |         /* BURST = 1, BURST */
        ( 0 << 17 ) |          /* CLKS = 0, 11 clocks/10 bits */
        ( 1 << 21 ) |          /* PDN = 1, normal operation */
        ( 0 << 22 ) |          /* TEST1:0 = 00 */
        ( 4 << 24 ) |          /* MAT0.1 */
        ( 1 << 27 );        /* EDGE = 1 */

    /* If POLLING, no need to do the following */
    AD0INTEN = 0x1FF;        /* Enable interrupts */
    install_irq( ADC0_INT, (void *)ADC0, HIGHEST_PRIORITY );


Процедура прерывания АЦП, взято из примера

Код
__irq void ADC0 (void) {

    IENABLE;            /* handles nested interrupt */

    val = AD0DR0;                           // Read A/D Data Register
    SendBuff[NumSBuff][cnt] = ((val >> 5) & 0x3FF);          // Extract AD00 Value
    cnt++;
    if (cnt == SENDLEN)
    {
        cnt = 0;
        BuffFull = 1;
        NumSBuff ^= 1;
    }
    IDISABLE;
    VICVectAddr = 0;
}


С АЦП данные идут правильные, проверил в отладчике.
BURST и нулём и единицей делал, запрещал MAT0.1 выходить наружу (PINSEL3 &=~ (3 << 26); ). Ни чего не помогает. Прерываний или вообще нет или они всё забивают.

Дайте пример правильной инициализации АЦП и таймера.

Ещё одно. Таймер для АЦП программирую для инверсии выхода T0EMR = (3 << 6);, следовательно, частота таймера должна быть в два раза больше необходимой частоты отсчёта, т.к. запуск АЦП программируется только на спад или фронт. А как программно изменить состояние MATx.x не знаю?
Mihey_K
BURST = 0 точно надо сделать, т.к. запуск по таймеру, а не потоком

С примером завтра может получится

Почитайте эррату, страница 7, хотя запуска по MAT это не должно касаться
esaulenka
Цитата(Oleg_IT @ Jan 19 2014, 21:54) *
Ещё одно. Таймер для АЦП программирую для инверсии выхода T0EMR = (3 << 6);, следовательно, частота таймера должна быть в два раза больше необходимой частоты отсчёта, т.к. запуск АЦП программируется только на спад или фронт. А как программно изменить состояние MATx.x не знаю?


Простым изменением битов EMx, в данном случае - первого бита T0EMR.
Oleg_IT
Цитата
С примером завтра может получится
Может получится с примером?

Цитата
Простым изменением битов EMx, в данном случае - первого бита T0EMR.
Спасибо, снять уровень получилось.

У меня какая-то общая проблема с прерываниями, включил прерывание от нулевого таймера и они всё забивают.
KRS
Цитата(Oleg_IT @ Jan 21 2014, 22:03) *
включил прерывание от нулевого таймера и они всё забивают.

А Вы их чистите?

Да, и кстати зачем Вам вложенные прерывания? Кроме того Вы неправильно их используете! в ARM7 нельзя просто так разрешить вложенные прерывания, нужен или wrapper или указать компилятору (у IAR __nested)
Oleg_IT
Цитата
Да, и кстати зачем Вам вложенные прерывания?
Не нужны они мне. Почти весь код беру из примеров, наверное пока не до конца со всем разобрался. Вот потому и прошу правильные примеры.
Golikov A.
а по мануалу?
попасть в прерывание, снять флаг, обработать что-то выйти?
Oleg_IT
Цитата
попасть в прерывание, снять флаг, обработать что-то выйти?

Делаю для нулевого таймера (всё беру из примеров) T0IR = 1; VICVectAddr = 0; Или ещё что-то нужно? Обнулял конкретный номер прерывания VICVectAddrX = 0;, прерывание возникает только один раз.

Код
__irq void Timer0 (void) {
    T0IR = 1;
    T0EMR |= (1 << 1);     // MAT0.1  P1[29]
//   VICVectAddr4 = 0;
    VICVectAddr = 0;
}


Примерчик бы рабочий
Mihey_K
Пришлось доставать старую плату SK-MLPC2478. Ниже прикреплен рабочий тестовый пример под Keil для 3го канала АЦП с запуском по таймеру. Все работает, проверил.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.