Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: STM32F217ZGT6 проблема с ADC+DMA
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Alex_1811
Есть задача с частотой 20кГц нужно что бы АЦП складывало в буфер 50 выборок.
Настроил АЦП на максимальное быстродействие и работу с ДМА так:
CODE
NVIC->ISER[(DMA2_Stream0_IRQn >> 0x05)] = (u32)0x01 << (DMA2_Stream0_IRQn & (u8)0x1F); /* Enable DMA interrupt */

RCC->APB2ENR |= (1<<8);

RCC->AHB1ENR |= (1<<22); // DMA1EN
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOBEN; // Ðàçðåøèòü òàêòèðîâàíèå PORTE.

ADC1->CR1 |= ADC_CR1_AWDIE| // AWD on injected channels whith interrupt
ADC_CR1_SCAN; // Scan mode + auto injection
ADC1->SMPR2 = 0x0000; // 1.5 sampling time
ADC1->SQR1 = 0x00; // 1 conversion

ADC1->SQR3 = ADC_SQR3_SQ1_3; // 8 chanell

ADC1->CR2 = ADC_CR2_EXTSEL_0 | ADC_CR2_EXTSEL_1 | ADC_CR2_EXTSEL_2 // run SWSTART
//| ADC_CR2_EXTEN
| ADC_CR2_DMA
| ADC_CR2_CONT; // enable externall run


ADC1->SMPR1 = 0x0920000B;

GPIOB->MODER |= (GPIO_MODER_MODER0); // PORTB.0 Analog input


// DMA configuring
DMA2_Stream0->CR |= DMA_SxCR_PL | DMA_SxCR_MSIZE_0 | DMA_SxCR_PSIZE_0 |
//Hight pry, 16 byte mem, 16 byte pereph
DMA_SxCR_MINC |
//DMA_CCR1_CIRC|
DMA_SxCR_HTIE |
DMA_SxCR_TCIE; // mem inc, circular, enterrupts by Half and End of conv

DMA2_Stream0->NDTR = ADC_ARRAY_SIZE;
DMA2_Stream0->PAR = (uint32_t)&ADC1->DR;
DMA2_Stream0->M0AR = (uint32_t)&TOK_HI[0];
// On converting
ADC1->CR2 |= ADC_CR2_ADON; // Adc ON
// Additional delay to Vref on


DMA2_Stream0->CR &= ~DMA_SxCR_EN; /* Disable DMA */
DMA2_Stream0->NDTR = ADC_ARRAY_SIZE;
DMA2_Stream0->CR |= DMA_SxCR_EN; /* Enable DMA */
ADC1->CR2 |= ADC_CR2_SWSTART;


И дальше по таймеру (период 50мкС) запускаю захват данных с АЦП.
Код
    
    DMA2_Stream0->CR &= ~DMA_SxCR_EN; // Disable DMA
    DMA2->LIFCR |= ((1<<0)|(1<<2)|(1<<3)|(1<<4)|(1<<5));
    DMA2_Stream0->NDTR = ADC_ARRAY_SIZE;
    DMA2_Stream0->CR |= DMA_SxCR_EN; //Enable DMA

Первый раз буфер заполняется значениями с АЦП и все, дальше ничего не работает.
Подскажите что не так.
scifi
Цитата(Alex_1811 @ Jun 8 2012, 16:42) *
Первый раз буфер заполняется значениями с АЦП и все, дальше ничего не работает.
Подскажите что не так.

Помню, тоже делал повторный запуск DMA. Оказалось, повторную инициализацию DMA следует проводить полностью, то есть не следует полагаться на то, что, к примеру, регистр DMA2_Stream0->PAR сохранит своё значение.

Цитата(Alex_1811 @ Jun 8 2012, 16:42) *
Есть задача с частотой 20кГц нужно что бы АЦП складывало в буфер 50 выборок.

Кстати, в STM32 очень мощные и гибкие (и оттого довольно непонятные) таймеры. Можно сделать так, чтобы таймер выдавал пачки импульсов с нужной времянкой и завести эти импульсы на запрос DMA. Тогда DMA работало бы в непрерывном режиме и просто складывало выборки куда надо.
Alex_1811
Цитата(scifi @ Jun 8 2012, 16:16) *
Помню, тоже делал повторный запуск DMA. Оказалось, повторную инициализацию DMA следует проводить полностью, то есть не следует полагаться на то, что, к примеру, регистр DMA2_Stream0->PAR сохранит своё значение.


Попробовал полную инициализацию ДМА. Не помогло. Куда копать уже не знаю.
Alex_1811
DMA поборол но возникла вторая проблема. Про подаче на вход АЦП сигнала с резисторного делителя питания МК, данные с АЦП скачут где то в 10 значений но есть выбросы до 20. Почему так шумит АЦП?
011119xx
Потому, что входное сопротивление АЦП порядка 50кОм. Поставь между АЦП и резистивным делителем ОУ.
Alex_1811
Что то полная .опа с АЦП. Шумит зараза сильно. Уже не знаю куда копать.
scifi
Цитата(Alex_1811 @ Jul 17 2012, 10:38) *
Что то полная .опа с АЦП. Шумит зараза сильно. Уже не знаю куда копать.

Копать вот куда:
- убедиться, что питание АЦП чистое
- если Vref подключен отдельно, то тоже должно быть чисто
- источник сигнала должен иметь достаточно низкое выходное сопротивление, чтобы полностью заряжать входную ёмкость АЦП
- разводка платы должна быть без косяков
- ну и сам сигнал может содержать шум
Alex_1811
Что интересное заметил.
У меня данные с АЦП скидываются в буфер через ДМА по 92 выборки. А потом по таймеру этот буфер копируется в большой буфер на 4000 выборок который я вывожу в виде графика на ПК. Так вот если в процесе работы смотреть содержимое буфера на 92 выборки то там шумные данные но когда я останавливаю отладку то после последноге обновления в этом буфере адекватные данные (шум 1-3 дискреты).

CODE
void TIM1_CC_IRQHandler(void)
{

if (TIM1->SR & TIM_SR_CC3IF)
{
DMA2_Stream0->CR &= ~DMA_SxCR_EN; // Disable DMA

DMA2->LIFCR |= ((1<<0)|(1<<2)|(1<<3)|(1<<4)|(1<<5));
DMA2_Stream0->CR ^= DMA_SxCR_CT; // switch buffer
if (DMA2_Stream0->CR & DMA_SxCR_CT)
setBuf = 1;
DMA2_Stream0->NDTR = ADC_ARRAY_SIZE;
DMA2_Stream0->CR |= DMA_SxCR_EN; //Enable DMA
ADC1->CR2 |= ADC_CR2_ADON;
ADC1->CR2 |= ADC_CR2_SWSTART;


//******************************************************************************
// *************** копируем данные в буфер для вывода графика ******************
//******************************************************************************
if (grFlag == 1)
{

DMA2_Stream1->NDTR = 93;
if (DMA2_Stream0->CR & DMA_SxCR_CT)
DMA2_Stream1->PAR = (uint32_t)&TOK_HI_0[0];
else
DMA2_Stream1->PAR = (uint32_t)&TOK_HI_1[0];
DMA2->LIFCR |= ((1<<6)|(1<<8)|(1<<9)|(1<<10)|(1<<11));
DMA2_Stream1->M0AR = (uint32_t)&GR_BUFF[indexGR];
DMA2_Stream1->CR |= DMA_SxCR_EN; //Enable DMA
indexGR += 93;
}

}
}
scifi
Цитата(Alex_1811 @ Jul 17 2012, 12:34) *
Так вот если в процесе работы смотреть содержимое буфера на 92 выборки то там шумные данные но когда я останавливаю отладку то после последноге обновления в этом буфере адекватные данные (шум 1-3 дискреты).

Надо копать в сторону питания. Цифровое и аналоговое питание должно быть отвязано друг от друга. Есть рекомендованная схема в даташите. Невредно добавить ferrite bead где надо (посмотрите схемы демо-плат с разными процами на предмет фильтрации аналогового питания).
kan35
Как уже было сказано, у вас высокое выходное сопротивление, потому - максимально увеличьте время преобразования - до 239.5 циклов, и понизьте частоту до минимума который вам нужен.
Ну и боритесь с помехами по питанию.
Alex_1811
Цитата(kan35 @ Jul 17 2012, 15:04) *
Как уже было сказано, у вас высокое выходное сопротивление, потому - максимально увеличьте время преобразования - до 239.5 циклов, и понизьте частоту до минимума который вам нужен.
Ну и боритесь с помехами по питанию.

Такая же хрень когда закорачиваю вход АЦП на землю. А тут уже сопротивление нулевое.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.