Перейти к содержанию
    

LPC2478. Запуск АЦП по таймеру. Перенёс из В помощь начинающему

Нужно набрать отсчеты АЦП в буфер и передать их по изернет. С изернет всё нормально, а когда включаю АЦП прерывания от него забивают всё и не дают выполняться основному циклу, передача по изернет соответственно встаёт. И ни какой синхронизации АЦП и таймера нет.

Инициализирую таймеры

Для изернета, взято из примера

 

    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 не знаю?

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

BURST = 0 точно надо сделать, т.к. запуск по таймеру, а не потоком

UM10237.png

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

 

Почитайте эррату, страница 7, хотя запуска по MAT это не должно касаться

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

 

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

 

У меня какая-то общая проблема с прерываниями, включил прерывание от нулевого таймера и они всё забивают.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

включил прерывание от нулевого таймера и они всё забивают.

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

 

Да, и кстати зачем Вам вложенные прерывания? Кроме того Вы неправильно их используете! в ARM7 нельзя просто так разрешить вложенные прерывания, нужен или wrapper или указать компилятору (у IAR __nested)

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Да, и кстати зачем Вам вложенные прерывания?
Не нужны они мне. Почти весь код беру из примеров, наверное пока не до конца со всем разобрался. Вот потому и прошу правильные примеры.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

попасть в прерывание, снять флаг, обработать что-то выйти?

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

 

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

 

Примерчик бы рабочий

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Пришлось доставать старую плату SK-MLPC2478. Ниже прикреплен рабочий тестовый пример под Keil для 3го канала АЦП с запуском по таймеру. Все работает, проверил.

Demo.zip

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...