Skip to main content
Associate II
October 21, 2024
Solved

ADC Differential Mode Reading Incorrect

  • October 21, 2024
  • 4 replies
  • 1422 views

Hi,

I got some problem with using ADC Differential Mode. 

When I am using ADC Single Ended Mode:

Channel 8 Reading: ~8735
Channel 9 Reading: ~10907

When I am using ADC Differential Mode:
Reading: ~7106

That's weird. ADC Differential Mode should be subtracting both reading so suppose I should get 8735-10907=-2172? Why I will get 7106? Is it the signing problem? I already use int16_t instead of uint16_t

Does anyone can help me on this?

Thank you!!!!

 

Screenshot 2024-10-21 at 14.22.14.png

Screenshot 2024-10-21 at 14.22.26.png

 

 

Best answer by waclawek.jan

Differential conversion results are mid-centered and half-gain to fit the full range. 

8192 + (-2172 / 2) = 7106.

See relevant sections of ADC chapter in RM.

JW

P.S. Read also relevant sections of datasheet, note the rather limited common-mode range.

4 replies

waclawek.jan
waclawek.janBest answer
Super User
October 21, 2024

Differential conversion results are mid-centered and half-gain to fit the full range. 

8192 + (-2172 / 2) = 7106.

See relevant sections of ADC chapter in RM.

JW

P.S. Read also relevant sections of datasheet, note the rather limited common-mode range.

James613Author
Associate II
October 21, 2024

Hi,

Oh I see! Thank you so much!!!!

James613Author
Associate II
October 21, 2024

Hi,

But is there anyway to directly output signed value from ADC?

 

 

MasterT
Lead II
October 21, 2024

Try data alignment "right adjust"

waclawek.jan
Super User
October 22, 2024

> But is there anyway to directly output signed value from ADC?

See Offset section of Data management subchapter of ADC chapter in RM, and description of ADC_OFRy register.

JW

James613Author
Associate II
October 22, 2024

Hi,

Thank you so much! I did it!

ADC1->OFR1 = 0; // Clear the offset register first

ADC1->OFR1 |= (8192 << ADC_OFR1_OFFSET1_Pos); // Set the OFFSET to 8192

ADC1->OFR1 |= (1 << ADC_OFR1_SSAT_Pos); // Enable signed saturation

ADC1->OFR1 &= ~(1 << 24); // Set POSOFF to 0 (negative offset)

ADC1->OFR1 |= (8 << ADC_OFR1_OFFSET1_CH_Pos); // Apply the offset to ADC Channel 1

 

And also set left shift bit by 1 to mutiply the result by 2.