Converting ADC Results into IQ Format
8 - 26 C2000 Microcontroller Workshop - Numerical Concepts
Converting ADC Results into IQ Format
#define AdcFsVoltage _IQ(3.3) // ADC full scale voltage
_iq Result, temp; // ADC result
void main(void)
{
// convert the unsigned 16-bit result to unsigned 32-bit
temp = AdcResult.ADCRESULT0;
// convert resulting IQ12 to Global IQ format
temp = _IQ12toIQ(temp);
// scale by ADC full-scale range (optional)
Result = _IQmpy(AdcFsVoltage, temp);
}
Getting the ADC Result into IQ Format
AdcResult.
ADCRESULTx
32-bit long
15 031
Do not sign extend
Notice that the 32-bit long is already in IQ12 format
//
//
//
Result = _IQmpy(AdcFsVoltage, _IQ12toIQ( (_iq)AdcResult.ADCRESULT0));
x x x xx x x xx x x x
0 0 0 00 0 0 0 0 0 0 00 0 0 0 0 0 0 0
x x x xx x x xx x x x
0 0 0 0
As you may recall, the converted values of the ADC are placed in the lower 12 bits of the
ADCRESULT0 register. Before these values are filtered using the IQmath library, they need to
to be put into the IQ format as a 32-bit long. For uni-polar ADC inputs (i.e., 0 to 3.3 V inputs), a
conversion to global IQ format can be achieved with:
IQresult_unipolar = _IQmpy(_IQ(3.3),_IQ12toIQ((_iq) AdcResult.ADCRESULT0));
How can we modify the above to recover bi-polar inputs, for example +-1.65 volts? One could
do the following to offset the +1.65V analog biasing applied to the ADC input:
IQresult_bipolar =
_IQmpy(_IQ(3.3),_IQ12toIQ((_iq) AdcResult.ADCRESULT0)) - _IQ(1.65);
However, one can see that the largest intermediate value the equation above could reach is 3.3.
This means that it cannot be used with an IQ data type of IQ30 (IQ30 range is -2 < x < ~2). Since
the IQmath library supports IQ types from IQ1 to IQ30, this could be an issue in some applica-
tions.
The following clever approach supports IQ types from IQ1 to IQ30:
IQresult_bipolar =
_IQmpy(_IQ(1.65),_IQ15toIQ((_iq) ((int16) (AdcResult.ADCRESULT0 ^
0x8000))));
The largest intermediate value that this equation could reach is 1.65. Therefore, IQ30 is easily
supported.