How to understand ADC convert formula under Ember adc.c

10/301/2015 | 01:30 AM

The formula N = ((nvalue << 16) + Nvdd/2) / Nvdd; is from f() int16s halConvertValueToVolts(int16u value) in EM3XX-specific ADC HAL functions adc.c, how to understand this formula? whtat dose nvalue>>16 mean? It makes me confused.Anyone can help me explain it ?

is to normalize the ADC reading relative to Nvdd (which is the ADC reading of VREG2 relative to GND, see halAdcCalibrate() ).

For example, if nvalue is 0, we want N to be 0; if nvalue is Nvdd, we want N to be 2^16. The addition of Nvdd/2 before division is to achieve a rounding effect.

Next, the purpose of

V = (int16s)((N*((int32s)halInternalGetVreg())*5) >> 16);

is to convert N to a voltage value of 1/10 mV precision.

For example, if N is 0, the end result V should be 0. If N is 2^16, the end result V should be (Vreg/2)*10. Therefore the scaling factor is

(Vreg/2)*10/2^16, or Vreg*5/2^16.

Note that the return value of halConvertValueToVolts() is a voltage value of 1/10 mV precision. For example, if V is 6005, you should interpret that as 600.5mV.

I can understand function halAdcCalibrate() now. I know the actual ADC convert formula is Y(output)=ma*x(inputvoltage)+b.According to the halAdcCalibrate(),ma = (Nvdd-Nvss)/(Vreg-VGnd),b = Nvss.But the ma and b is not corresponding the formula N = ((nvalue << 16) + Nvdd/2) / Nvdd...

Why we want the N to be 2^16? It doesn't seem that it has relationship with the 14-bits resolution.The N is the formula looks like a digital value.I don't know which place I should consider else.

yuxiao wrote:

First, the purpose of

N = ((nvalue << 16) + Nvdd/2) / Nvdd;

is to normalize the ADC reading relative to Nvdd (which is the ADC reading of VREG2 relative to GND, see halAdcCalibrate() ).

For example, if nvalue is 0, we want N to be 0; if nvalue is Nvdd, we want N to be 2^16. The addition of Nvdd/2 before division is to achieve a rounding effect.

Next, the purpose of

V = (int16s)((N*((int32s)halInternalGetVreg())*5) >> 16);

is to convert N to a voltage value of 1/10 mV precision.

For example, if N is 0, the end result V should be 0. If N is 2^16, the end result V should be (Vreg/2)*10. Therefore the scaling factor is

(Vreg/2)*10/2^16, or Vreg*5/2^16.

Note that the return value of halConvertValueToVolts() is a voltage value of 1/10 mV precision. For example, if V is 6005, you should interpret that as 600.5mV.

For simplicity's sake (temporarily ignoring calibration and assuming the ADC reading of GND is 0) - the relationship between input and output should be that

ma = Vreg/Nvdd

(note you got it reversed)

The 16-bit left-shift in step1 and 16-bit right-shift in step2 are not necessary mathematically, but useful in numerical computation - we want to have the dividend to have as many bits as possible before a division. Now, you may argue that we could use 17 bits instead of 16, since the input (nvalue) is only 14-bit. Here we use 16 mostly for convenience and better code-readability and adaptability.

0

OK,I can understand the ADC calibration and convertion theory in adc.c file now.But I think the gain 'ma' you said should be ma = Nvdd/Vreg, is that right?

0

Assuming we are still talking about the scale factor in halConvertValueToVolts(), it is the other way around, ma = Vreg/Nvdd. (Note the step1 I mentioned in my first reply where Nvdd is in the denominator.)

The output is the return value of halConvertValueToVolts(), which is the actual voltage.

The input is a unit-less integer value, which is what we read from the A-D converter.

Vreg is the known actual voltage value of VREG.

You might be thinking about the gain in ADC calibration procedure, which is separate from halConvertValueToVolts(). If that's case, we should start a separate topic and be specific about the routine under discussion.

Best regards,

Yuping Xiao

0

As your train of thought, Vreg/Nvdd=Nvalue/V ,this scale relationship is input /output, V=Nvalue*Vreg/Nvdd,it is crystal clear.One more question I want to ask ,the Nvalue = value - Nvss, is the Nvss means the Offset after calibration ?

0

Nvss is the ADC reading when the P channel source is GND, and N channel source is VREF/2. You can interpret that as ADC offset. By obtaining Nvdd and Nvss, you are essentially doing ADC calibration (halAdcCalibrate() in adc.c).

Yuping Xiao

0

I want to know how i can measure adc_offset and adc_gain for em 357 mcu.

## How to understand ADC convert formula under Ember adc.c

The formula

N = ((nvalue << 16) + Nvdd/2) / Nvdd;is fromf() int16s halConvertValueToVolts(int16u value)in EM3XX-specific ADC HAL functions adc.c, how to understand this formula? whtat dose nvalue>>16 mean? It makes me confused.Anyone can help me explain it ?First, the purpose of

N = ((nvalue << 16) + Nvdd/2) / Nvdd;

is to normalize the ADC reading relative to Nvdd (which is the ADC reading of VREG2 relative to GND, see halAdcCalibrate() ).

For example, if nvalue is 0, we want N to be 0; if nvalue is Nvdd, we want N to be 2^16. The addition of Nvdd/2 before division is to achieve a rounding effect.

Next, the purpose of

V = (int16s)((N*((int32s)halInternalGetVreg())*5) >> 16);

is to convert N to a voltage value of 1/10 mV precision.

For example, if N is 0, the end result V should be 0. If N is 2^16, the end result V should be (Vreg/2)*10. Therefore the scaling factor is

(Vreg/2)*10/2^16, or Vreg*5/2^16.

Note that the return value of halConvertValueToVolts() is a voltage value of 1/10 mV precision. For example, if V is 6005, you should interpret that as 600.5mV.

Yuping Xiao

Senior Applications Engineer (Wireless Mesh Networking)

I can understand function halAdcCalibrate() now. I know the actual ADC convert formula is Y(output)=ma*x(inputvoltage)+b.According to the halAdcCalibrate(),ma = (Nvdd-Nvss)/(Vreg-VGnd),b = Nvss.But the ma and b is not corresponding the formula N = ((nvalue << 16) + Nvdd/2) / Nvdd...

Why we want the N to be 2^16? It doesn't seem that it has relationship with the 14-bits resolution.The N is the formula looks like a digital value.I don't know which place I should consider else.

For simplicity's sake (temporarily ignoring calibration and assuming the ADC reading of GND is 0) - the relationship between input and output should be that

ma = Vreg/Nvdd

(note you got it reversed)

The 16-bit left-shift in step1 and 16-bit right-shift in step2 are not necessary mathematically, but useful in numerical computation - we want to have the dividend to have as many bits as possible before a division. Now, you may argue that we could use 17 bits instead of 16, since the input (nvalue) is only 14-bit. Here we use 16 mostly for convenience and better code-readability and adaptability.

OK,I can understand the ADC calibration and convertion theory in adc.c file now.But I think the gain 'ma' you said should be ma = Nvdd/Vreg, is that right?

Assuming we are still talking about the scale factor in halConvertValueToVolts(), it is the other way around, ma = Vreg/Nvdd. (Note the step1 I mentioned in my first reply where Nvdd is in the denominator.)

The output is the return value of halConvertValueToVolts(), which is the actual voltage.

The input is a unit-less integer value, which is what we read from the A-D converter.

Vreg is the known actual voltage value of VREG.

You might be thinking about the gain in ADC calibration procedure, which is separate from halConvertValueToVolts(). If that's case, we should start a separate topic and be specific about the routine under discussion.

Best regards,

Yuping Xiao

As your train of thought, Vreg/Nvdd=Nvalue/V ,this scale relationship is input /output, V=Nvalue*Vreg/Nvdd,it is crystal clear.One more question I want to ask ,the Nvalue = value - Nvss, is the Nvss means the Offset after calibration ?

Nvss is the ADC reading when the P channel source is GND, and N channel source is VREF/2. You can interpret that as ADC offset. By obtaining Nvdd and Nvss, you are essentially doing ADC calibration (halAdcCalibrate() in adc.c).

Yuping Xiao

I want to know how i can measure adc_offset and adc_gain for em 357 mcu.

Is there any predefined value is availble?