Search code examples
embeddedbufferstm32dmaadc

STM32: how does the DMA save values of an ADC with 3 channels as half word into a buffer?


I have a STM32L151RBT6 with 1 ADC and 2 channels configured. The ADC is configured in "scan mode" and "continuous mode". The ADC has a resolution of 12 bits. The ADC values are saved into a buffer, where every element of the array is 32 bits in size. The DMA saves the ADC values as half word, so every element of the array contains 2 ADC values. So, if you zoom into an element, it would look like this:

MSB 0000 0000 0000 0000 0000 0000 0000 0000 LSB
    |--| |------------| |--| |------------|
    |    |              |    |
    |    |              |    |ADC CH0 Value
    |    |              |
    |    |              |Filler Bits
    |    |
    |    |ADC CH1 Value
    |
    | Filler Bits

Note that every value is only 12 bits in size, since the ADC resolution is 12 bits.

Now comes my question: How would the DMA save the ADC values into the array, if I would configure 3 ADC channels, without reducing the resolution?

This is my DMA configuration:

static uint32_t ADC_ConvertedValue[16];

HAL_ADC_Start_DMA(&hadc, ADC_ConvertedValue, 32);

Solution

  • The ADC/DMA doesn't care that you defined your array to be an array of uint32_t. It just needs a memory address (probably aligned on a 2-byte boundary), and it will write the data in. You could define it as an array of char and it would be equally happy, so long as the alignment and size were ok.

    Since you are running the ADC in 12-bit mode, and it is storing samples as 16-bit values, it would be much more natural to define the array as:

    static uint16_t ADC_ConvertedValue[32];
    

    Then you could access your samples using simple array indexing, rather than having to manually extract them from 32-bit values.

    If you persist in using uint32_t, and changed the number of channels to 3, then the first array member would have samples from channels 0 and 1, then the next array member would have samples from channels 2 and 0, then the next would have 1 and 2, etc.