Będziemy czytać do pamięci dane ADC bez udziału procesora.
Przewody
Podłączymy czujnik dźwięku.
Czujnik <—> STM32
+ <—> 3,3V
G <—> GND
AO <—> AO
Podpinamy napięcie, oraz wyjście ANALOGOWE (AO) z czujnika do naszego ADC. Wyjście DO (Digital Output) zostawiamy niepodpięte.
CubeMX
Analog – ADC1 – IN0 (checkbox)
Parameter settings: Countinious Conversion Mode: Enabled
Enable regular conversions: Enable
Może być jeszcze (na innej płytce STM32):
DMA continous reques: Enable
System Core – DMA – ADD
ADC1 – DMA1 Channel 1 – Peripherial to Memory – Low
Mode: Circular (zapis bufora w kółko)
Resztę zostaw domyślnie
IDE
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | /* USER CODE BEGIN PD */ #define ADC_BUF_LEN 4096 //size of DMA buffer tab 8kB, each value is 2 bytes //... /* USER CODE BEGIN PV */ uint16_t adc_buf[ADC_BUF_LEN]; //THE Buffer for DMA transfer 8kB //... /* USER CODE BEGIN 2 */ HAL_ADC_Start_DMA(&hadc1, (uint32_t*)adc_buf, ADC_BUF_LEN); //... /* USER CODE BEGIN 4 */ // IRQ - HALF of the buffer filled - handle it void HAL_ADC_ConvHalfCpltCallback(ADC_HandleTypeDef* hadc) { rt_kprintf("H"); } // Called when buffer is completely filled void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc) { rt_kprintf("F"); } //... |
Zasada buffer ring
Mamy dwa bufory: w czasie, gdy STM32 przetwarza bufor HAL_ADC_ConvHalfCpltCallback z tablicy adc_buf (tj. komórki adc_buf[0-2047]), wczytuje się bufor dla funkcji HAL_ADC_ConvCpltCallback tj. adc_buf[2048-4095]). Gdy skończy, odczeka aż zapełni się drugi bufor i na odwrót – wykona teraz funkcję HAL_ADC_ConvCpltCallback w czasie, gdy przez DMA bez udziału STM32 kolejne odczyty będą trafiały do tablicy ale w części przeznaczonej dla nieaktywnej funkcji HAL_ADC_ConvHalfCpltCallback. Jest to uproszczony model buffer ring ale tylko z dwoma buforami.
Bardzo dobrym zwyczajem jest długość bufora będąca potęgą liczby 2 o ile to możliwe, daje to szansę na szybkie policzenie arytmetyki np. dzielenia przy średniej tylko przy użyciu operatorów bitowych np. >> .
Częstotliwość próbkowania
Ciekawe, że mało można znaleźć informacji o częstotliwości próbkowania, która powiązana jest ściśle z zegarem STM32.
Do jej ustawiania służy parametr Sampling Time (CubeMX-ADC1-Parameter Settings-Sampling Time), który wynosi odpowiednio: dla 1,5 aż 585 142 (czyli 0,58 Mhz), dla 239,5 wynosi około 15869Hz – jest to blisko niskiej częstotliwości zapisu WAV (11025).