In the pervious guide (here), we took a look how to configure the DMA with ADC to acquire data from single channel. In this guide, we shall see why DMA is essential when deal with multichannel in ADC and how to configure the ADC and DMA to work together.
In this guide, we shall cover the following:
- Why DMA in ADC with multiple channel.
- STM32CubeMX configuration.
- Driver development.
- Results.
1. Why DMA in ADC with Multiple Channel:
Let say you want ti acquire data from adc from 3-channel in continuous mode. Since each conversion requires 15 cycles for 12-bit since the adc clock is the core frequency over (16MHz/2=8MHz), thats means generating interrupts at rate near half mega hertz which will effect the performance of the mcu. Hence, using DMA in such case makes sense. This will make handling the data easier since each index of the array, it will be the rank of the channel as shown:
2. STM32CubeMX Configuration:
pen adc_single.ioc file as following:
Next, from the user manual of STM32H563ZI Nucleo-144 we can see which pins are connected to A0 to A5 of arduino pins:
Since PA6 is already activated from the previous guide, we shall use PC0 as the second ADC channel as following:
Set PC0 as ADC1_INP10.
Next from ADC section, in ADC1, enable channel as single ended as following:
Next from Parameter settings of ADC:
Set the following:
- Set number of conversion to 2 (depending on the number of channels).
- From Rank 1, set the channel to be channel 3 (depending on your application and enabled channels).
- From Rank 2, set the channel to be channel 10.
In this configuration, the data from channel 3 shall be stored as the first element of the data array and channel 10 will be the second element and so on.
Next from system core, GPDMA1, we shall configure the destination to be increment as following:
Save the project and then the project shall be generated.
3. Firmware Development:
From the previous guide, we shall modify the the variable to be an array as following:
uint16_t adc_value[2];
For launching the ADC in DMA:
HAL_ADC_Start_DMA(&hadc1, (uint32_t)&adc_value, 2);
Modify the length to be 2.
In while 1 loop, we shall print the results of the array as following:
for (uint16_t i=0;i<2;i++) { printf("ADC Value[%d] =%d\r\n",i,adc_value[i]); } HAL_Delay(500);
Save, build and run the project as following:
Thats all.
4. Results:
Open your favourite serial terminal application, set the baudrate to be 115200 and you should get the following:
Here, A0 of arduino pin is connected to GND and A1 of arduino pin is connected to 3V3 of the Nucleo-144.
Happy coding 😉
Add Comment