MK22 differential adc-channel in 16bit mode puts out half of the actual value

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

MK22 differential adc-channel in 16bit mode puts out half of the actual value

750 Views
philippthornhil
Contributor II

Hello,

I'm currently working on the adc of the MK22FN128VLH10 microcontroller. I used the example, given with the FRDM-K22-board, to initialize a differential channel in 16bit mode. The outputted value is only half of the actual value. I've checked the hardware. The voltage is applied correctly to the pins.

Is there any configuration I have to make to make the adc work correctly?

Here the code:

int main(void)
{
    adc16_config_t adc16ConfigStruct;
    adc16_channel_config_t adc16ChannelConfigStruct;

    BOARD_InitPins();
    BOARD_BootClockRUN();
    BOARD_InitDebugConsole();
    vPowerSupplyEnableV5PL();
    EnableIRQ(DEMO_ADC16_IRQn);
    PRINTF("\r\nADC16 interrupt Example.\r\n");
    ADC16_GetDefaultConfig(&adc16ConfigStruct);
    adc16ConfigStruct.resolution = kADC16_Resolution16Bit;
    ADC16_Init(DEMO_ADC16_BASE, &adc16ConfigStruct);
    ADC16_EnableHardwareTrigger(DEMO_ADC16_BASE, false); /* Make sure the software trigger is used. */
    if (kStatus_Success == ADC16_DoAutoCalibration(DEMO_ADC16_BASE))
    {
        PRINTF("ADC16_DoAutoCalibration() Done.\r\n");
    }
    else
    {
        PRINTF("ADC16_DoAutoCalibration() Failed.\r\n");
    }
    PRINTF("Press any key to get user channel's ADC value ...\r\n");
    adc16ChannelConfigStruct.channelNumber = DEMO_ADC16_USER_CHANNEL;
    adc16ChannelConfigStruct.enableInterruptOnConversionCompleted = true; /* Enable the interrupt. */
    adc16ChannelConfigStruct.enableDifferentialConversion = true;
    ADC16_SetChannelMuxMode( DEMO_ADC16_BASE, kADC16_ChannelMuxB );

    g_Adc16InterruptCounter = 0U;

    while (1)
    {
        GETCHAR();
        g_Adc16ConversionDoneFlag = false;
        ADC16_SetChannelConfig(DEMO_ADC16_BASE, DEMO_ADC16_CHANNEL_GROUP, &adc16ChannelConfigStruct);
        while (!g_Adc16ConversionDoneFlag)
        {
        }
        PRINTF("ADC Value: %d\r\n", g_Adc16ConversionValue);
        PRINTF("ADC Interrupt Count: %d\r\n", g_Adc16InterruptCounter);
    }
}

Greetings,

Philipp

P.S.: vPowerSupplyEnableV5PL sets a few gpios.

0 Kudos
2 Replies

594 Views
Robin_Shen
NXP TechSupport
NXP TechSupport

Hi Philipp Thornhill,

I didn't find any obvious problems.
Would you please show us the outputted value and voltage applied correctly to the pins?
Additionally please notice the Data result register description of 16-bit differential mode.

Data result register description.png

Best Regards,

Robin

 

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos

594 Views
philippthornhil
Contributor II

Hello Robin Shen,

Your picture helped me to solve my problem. The problem was, that i didn't notice the sign bit. I have written a function with which the applied voltage can be calculated on the basis of the measured adc value. This function showed me the wrong voltage value, because of the wrong resolution.

Code:

#define RESOLUTION                      (uint32_t) 16 //has to be 15 because of the sign bit
#define MAX_RES_VAL                     ((uint32_t) 1 << RESOLUTION)

double getvoltage(uint32_t adcvalue)
{
  return (double)((double) U_REF * (double)adcvalue / (double) MAX_RES_VAL);
}

 Thank you for your help.

Greetings,

Philipp

0 Kudos