Skocz do zawartości
Tded

DMA ADC max sample STM32F103

Pomocna odpowiedź

Witam, jak osiągnąć maksymalny sampling rate na ADC + DMA?
SysClock ustawiony na 72Mhz. 
APB2CLKDivider i APB1CLKDivider ustawione na 1.

ADC leci w ContinuousConvMode = ENABLE i ExternalTrigConv = ADC_SOFTWARE_START;
SamplingTime = ADC_SAMPLETIME_13CYCLES_5;

DMA zapisuje do bufora[128] z jednego kanału ADC i wysyłam sobie to na ekran co jakiś czas.
Oczekuję zapisu badania sygnału do 20kHz, jak na razie nie łapie mi poprawnie nawet sygnału 9kHz,

 

Co tu zrobić, dać zewnętrzny trigger z jakiegoś timera ustawionego na przerwanie co 44.1kHz? Jest to szybsze?

Udostępnij ten post


Link to post
Share on other sites

F103 to bardzo prosty uK, w porównaniu oczywiście do innych, większych braci od ST. Z tego powodu jego dzielniki zegara dla ADC nie są zbyt rozbudowane, a co za tym idzie jedynie przy zegarze systemowym 56 MHz, jeśli dobrze pamiętam, można uzyskać maksymalną częstotliwość zegara ADC tj. 14 MHz. Dodatkowo musisz wybrać najmniejszy możliwy czas przetwarzania ADC tzn:

SamplingTime = ADC_SAMPLETIME_1CYCLES_5;

W ten sposób możesz uzyskać SR na poziomie  1 MSPS, czyli maksymalny dla tego uK

  • Lubię! 1

Udostępnij ten post


Link to post
Share on other sites

Mam problem z obsługą przerwania wypełnienia bufora, na debugu widzę, że w ogóle nie wykonuje jego obsługi, o co tu chodzi?

void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* adc_dma){
    HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13);
}

Deklaracja dma:
 

		__HAL_RCC_DMA1_CLK_ENABLE();
		__HAL_RCC_ADC1_CLK_ENABLE();


	    RCC_PeriphCLKInitTypeDef adc_clk;
	    adc_clk.PeriphClockSelection = RCC_PERIPHCLK_ADC;
	    adc_clk.AdcClockSelection = RCC_ADCPCLK2_DIV4;
	    HAL_RCCEx_PeriphCLKConfig(&adc_clk);

		adc_dma.Instance = ADC1;
		adc_dma.Init.ContinuousConvMode = ENABLE;
		adc_dma.Init.ExternalTrigConv = ADC_SOFTWARE_START;
		adc_dma.Init.DataAlign = ADC_DATAALIGN_RIGHT;
		adc_dma.Init.ScanConvMode = ADC_SCAN_DISABLE;
		adc_dma.Init.NbrOfConversion = 1;
		adc_dma.Init.DiscontinuousConvMode = DISABLE;
		adc_dma.Init.NbrOfDiscConversion = 0;
	    HAL_ADC_Init(&adc_dma);

	    HAL_ADCEx_Calibration_Start(&adc_dma);

	    ADC_ChannelConfTypeDef adc_ch;
	    adc_ch.Channel = ADC_CHANNEL_0;
	    adc_ch.Rank = ADC_REGULAR_RANK_1;
	    adc_ch.SamplingTime = ADC_SAMPLETIME_1CYCLE_5;
	    HAL_ADC_ConfigChannel(&adc_dma, &adc_ch);


		dma.Instance = DMA1_Channel1;
		dma.Init.Direction = DMA_PERIPH_TO_MEMORY;
		dma.Init.PeriphInc = DMA_PINC_DISABLE;						//Adres rejestru danych przetwornika jest stały, więc wyłączamy zwiększanie adresu
		dma.Init.MemInc = DMA_MINC_ENABLE;							//chcemy zapisywać w kolejnych zmiennych, włączamy więc zwiększanie adresu w pamięci
		dma.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;		//użyjemy 16-bitowych wartości do przechowywania wyników
		dma.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;		//
		dma.Init.Mode = DMA_NORMAL;								//pozwala na pobieranie kolejnych danych do tego samego bufora
		dma.Init.Priority = DMA_PRIORITY_HIGH;
		HAL_DMA_Init(&dma);
		__HAL_LINKDMA(&adc_dma, DMA_Handle, dma);						//powiązanie - kanał DMA z modułem ADC
		HAL_DMA_IRQHandler(&dma);
		HAL_ADC_IRQHandler(&adc_dma);


		HAL_ADC_Start_DMA(&adc_dma, (uint32_t*)bufor, 128);
		if(HAL_ADC_Start_DMA(&adc_dma, (uint32_t*)bufor, 128)!= HAL_OK)
		{
			while(1);
		}
		HAL_ADC_Start(&adc_dma);

 

Udostępnij ten post


Link to post
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.


×
×
  • Utwórz nowe...