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

STM32F217ZGT6 проблема с ADC+DMA

Есть задача с частотой 20кГц нужно что бы АЦП складывало в буфер 50 выборок.

Настроил АЦП на максимальное быстродействие и работу с ДМА так:

  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

Первый раз буфер заполняется значениями с АЦП и все, дальше ничего не работает.

Подскажите что не так.

Изменено пользователем IgorKossak
[codebox] для длинного кода!!!

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


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

Первый раз буфер заполняется значениями с АЦП и все, дальше ничего не работает.

Подскажите что не так.

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

 

Есть задача с частотой 20кГц нужно что бы АЦП складывало в буфер 50 выборок.

Кстати, в STM32 очень мощные и гибкие (и оттого довольно непонятные) таймеры. Можно сделать так, чтобы таймер выдавал пачки импульсов с нужной времянкой и завести эти импульсы на запрос DMA. Тогда DMA работало бы в непрерывном режиме и просто складывало выборки куда надо.

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


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

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

 

Попробовал полную инициализацию ДМА. Не помогло. Куда копать уже не знаю.

 

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


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

DMA поборол но возникла вторая проблема. Про подаче на вход АЦП сигнала с резисторного делителя питания МК, данные с АЦП скачут где то в 10 значений но есть выбросы до 20. Почему так шумит АЦП?

 

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


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

Потому, что входное сопротивление АЦП порядка 50кОм. Поставь между АЦП и резистивным делителем ОУ.

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


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

Что то полная .опа с АЦП. Шумит зараза сильно. Уже не знаю куда копать.

Изменено пользователем Alex_1811

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


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

Что то полная .опа с АЦП. Шумит зараза сильно. Уже не знаю куда копать.

Копать вот куда:

- убедиться, что питание АЦП чистое

- если Vref подключен отдельно, то тоже должно быть чисто

- источник сигнала должен иметь достаточно низкое выходное сопротивление, чтобы полностью заряжать входную ёмкость АЦП

- разводка платы должна быть без косяков

- ну и сам сигнал может содержать шум

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


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

Что интересное заметил.

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

 

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;
	}

}
}

Изменено пользователем IgorKossak
[codebox] для длинного кода!!!

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


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

Так вот если в процесе работы смотреть содержимое буфера на 92 выборки то там шумные данные но когда я останавливаю отладку то после последноге обновления в этом буфере адекватные данные (шум 1-3 дискреты).

Надо копать в сторону питания. Цифровое и аналоговое питание должно быть отвязано друг от друга. Есть рекомендованная схема в даташите. Невредно добавить ferrite bead где надо (посмотрите схемы демо-плат с разными процами на предмет фильтрации аналогового питания).

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


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

Как уже было сказано, у вас высокое выходное сопротивление, потому - максимально увеличьте время преобразования - до 239.5 циклов, и понизьте частоту до минимума который вам нужен.

Ну и боритесь с помехами по питанию.

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


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

Как уже было сказано, у вас высокое выходное сопротивление, потому - максимально увеличьте время преобразования - до 239.5 циклов, и понизьте частоту до минимума который вам нужен.

Ну и боритесь с помехами по питанию.

Такая же хрень когда закорачиваю вход АЦП на землю. А тут уже сопротивление нулевое.

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


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

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

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

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

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

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

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

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

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

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