I am trying to configure ADC1 on the STM32F303RE Nucleo board and I have not been able to find any good documentation on how differential mode works. I used CubeMX to setup the HAL with ADC1 Channel 8 configured for differential mode. It seems from experiment that the ADC Offset Number must be set to enable signed output, and by setting the offset to 2048 I do get differential behavior between the inputs.
sConfig.Channel = ADC_CHANNEL_8; sConfig.Rank = ADC_REGULAR_RANK_1; sConfig.SingleDiff = ADC_DIFFERENTIAL_ENDED; sConfig.SamplingTime = ADC_SAMPLETIME_4CYCLES_5; sConfig.OffsetNumber = ADC_OFFSET_1; sConfig.Offset = 2048;
However, when I test with ADC1_IN8M = 1.5V and swing ADC1_IN8P from 0 to 3.3V (Vref = 3.3V on the Nucleo), the data only runs from -1024 to +1024 and reads zero at 1.5V. Why am I only getting 11bit dynamic range in differential mode? When I switch to single ended it runs from 0 to 4095 as expected.
It is also not clear whether 0V falls within the common mode range for differential mode. The STM documentation says VSSA to Vref is the conversion range, but I get weird conversion results when one of the inputs gets close to zero volts.
Edit: From the STM32F3x reference manual:
When reading data from ADCx_DR (regular channel) or from ADCx_JDRy (injected channel, y=1,2,3,4) corresponding to the channel “i”:
- If one of the offsets is enabled (bit OFFSETy_EN=1) for the corresponding channel, the read data is signed.
- If none of the four offsets is enabled for this channel, the read data is not signed.
What does this mean? Why are there four offsets for each channel and what do they do?