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

Czujnik dźwięku
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).