2023-11-28 02:22 PM - edited 2023-11-30 06:40 AM
I'm running an STM32L452RCTX uC, and I'm trying to implement a 2.5Vref+ ADC.
Things weren't looking quite right on the pins I intend to implement, so for now I'm driving a floating TP with a power supply so I can directly test input vs output.
When driving the pin to ground, the output is around 2000 (I've seen it in the 198X through 200X range).
When increasing the voltage, I reach the full 4095 at 2.35V, which I feel is reasonably close to my measured 2.482 reference for my application.
I've scoured everywhere I can think of, and I can't seem to find any information on why this might happen. The behavior is almost as if the Vref- is somewhere near -2.5V, but I have that pin (confirmed through measurement) tied to ground.
As for circuitry, I have 3.3V running through a 470 ohm resistor to the top of a 2.5V zener (LM4040), across two caps to ground (2.2uF and 0.1uF), and through a series 0 ohm resistor into the Vref+ pin. The Vref- pin is soldered directly to the ground plane. The test point I am driving is about 3mm from the pin of the uC.
And the programming, using the HAL drivers:
//Additional initializations beyond HAL implementation
HAL_ADC_Stop(&hadc1);
HAL_ADCEx_Calibration_Start(&hadc1, ADC_SINGLE_ENDED);
//Battery checker, in main loop
if(check_adc && ((hadc1.State & HAL_ADC_STATE_READY) == HAL_ADC_STATE_READY))
{
//Configure ADC for conversion
adc_channel = TP_ADC;
sConfig.Channel = adc_channel;
sConfig.Rank = 1;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
if (HAL_ADC_Start(&hadc1) != HAL_OK)
{
Error_Handler();
}
if (HAL_ADC_PollForConversion(&hadc1, 100) != HAL_OK)
{
Error_Handler();
}
if (HAL_ADC_Stop(&hadc1) != HAL_OK)
{
Error_Handler();
}
if (HAL_ADC_Start(&hadc1) != HAL_OK)
{
Error_Handler();
}
if (HAL_ADC_PollForConversion(&hadc1, 100) != HAL_OK)
{
Error_Handler();
}
uint16_t temmp = hadc1.Instance->DR;
HAL_ADC_Stop(&hadc1);
check_adc = NO;
adc_check_timer = ADC_CHECK_TIME;
}
Registers while device is paused, currently a floating pin:
And measured results of the DR register:
Pin grounded: 0x7C0
Pin floating: 0x8E2
Pin 3.324V: 0xFBF
Solved! Go to Solution.
2023-11-29 02:50 PM - edited 2023-11-29 02:53 PM
The ADC channel could be in differential mode. Are you missing sConfig.SingleDiff = ADC_SINGLE_ENDED? Or other members of sConfig? That part of your code isn't shown.
Perhaps run a known working example on your board, only changing the channel number to what you're testing:
2023-11-29 03:04 PM
> ADC reading of internal VREFINT returns 0x5a +/- 2
That sounds very wrong.
> My VDDA pin is the same pin as VREF+, and is soldered directly to the ground plane.
You surely meant VSSA and VREF-.
> The ADC channel could be in differential mode.
Sounds much like so.
Read out and check/post content of ADC registers.
JW
2023-11-29 03:33 PM
Are you using a 2 prong wall wart to supply the signal? Strange results can happen if the negative output is not well grounded.
2023-11-30 12:13 AM
>> My VDDA pin is the same pin as VREF+, and is soldered directly to the ground plane.
> You surely meant VSSA and VREF-.
Hopefully, almost got a heart attack when I read that! :D
> The ADC channel could be in differential mode.
+1
2023-11-30 06:31 AM
@TDK:
This is single-ended, and configured as such. I did post a screenshot of the ioc setup, I'll amend my original post with this information.
I'll give it a shot, couldn't hurt. I *can* tell you I've compared my code to several of the sample projects for ADC, as well as comparing with code written by my boss on a different project, and the code looks correct.
I agree, but it is what I see on ADC_CHANNEL_0 DR
Yes, you are correct. My brain likes to flip opposites. On another note, I don't think I'll ever understand how to properly use pointers without looking it up first.
I agree something seems fishy here, and that would be a nice solution, but alas, it is very much configured in single-ended mode.
I'll post a screenshot (or a few) of my register readouts for ADC1 and ADC123_Common in the original post.
I am using a BK Precision 1735A 30V/3A DC power supply, which itself is plugged into a 6-outlet extension strip to the wall, but an o-scope reading of all pins in question show expected voltage with very low noise.
@LCE:
I probably would have also, brain flip ;)
As above, definitely configured for single-ended.
I'll update the original post with all this additional info.
2023-11-30 10:00 AM
> I'll post a screenshot (or a few) of my register readouts for ADC1 and ADC123_Common in the original post.
OK so you've posted a screenshot, where ADC_SQR1=0x1C0, i.e. one conversion and that's on channel 7; and ADC_DIFSEL=0x80, which means the conversion on channel 7 is differential.
The mcu does not work out of what you've clicked in CubeMX, it works out of the registers' content.
JW
2023-11-30 10:33 AM
So I guess when you configure one channel, you don't configure them all ;)
Thank you so much for that!
At ground, measuring 0x000.
At 3.3V, measuring 0xFFF.
At the middle of a 1/2 resistor divider, 0x7FF.