/******************************************************************************* * Code ******************************************************************************/ void static DEMO_InitPDB_ADC(void) { adc16_config_t adc16ConfigStruct; adc16_channel_config_t adc16ChannelConfigStruct; /* * adc16ConfigStruct.referenceVoltageSource = kADC16_ReferenceVoltageSourceVref; * adc16ConfigStruct.clockSource = kADC16_ClockSourceAsynchronousClock; * adc16ConfigStruct.enableAsynchronousClock = true; * adc16ConfigStruct.clockDivider = kADC16_ClockDivider8; * adc16ConfigStruct.resolution = kADC16_ResolutionSE12Bit; * adc16ConfigStruct.longSampleMode = kADC16_LongSampleDisabled; * adc16ConfigStruct.enableHighSpeed = false; * adc16ConfigStruct.enableLowPower = false; * adc16ConfigStruct.enableContinuousConversion = false; */ ADC16_GetDefaultConfig(&adc16ConfigStruct); ADC16_Init(DEMO_ADC_BASE, &adc16ConfigStruct); #if defined(FSL_FEATURE_ADC16_HAS_CALIBRATION) && FSL_FEATURE_ADC16_HAS_CALIBRATION ADC16_EnableHardwareTrigger(DEMO_ADC_BASE, false); ADC16_DoAutoCalibration(DEMO_ADC_BASE); #endif /* FSL_FEATURE_ADC16_HAS_CALIBRATION */ ADC16_EnableHardwareTrigger(DEMO_ADC_BASE, true); adc16ChannelConfigStruct.channelNumber = DEMO_ADC_USER_CHANNEL; adc16ChannelConfigStruct.enableInterruptOnConversionCompleted = true; /* Enable the interrupt. */ #if defined(FSL_FEATURE_ADC16_HAS_DIFF_MODE) && FSL_FEATURE_ADC16_HAS_DIFF_MODE adc16ChannelConfigStruct.enableDifferentialConversion = false; #endif /* FSL_FEATURE_ADC16_HAS_DIFF_MODE */ ADC16_SetChannelConfig(DEMO_ADC_BASE, DEMO_ADC_CHANNEL_GROUP, &adc16ChannelConfigStruct); }
/*! * @brief Initialize the ADCx for Hardware trigger. */ static bool ADC16_InitHardwareTrigger(ADC_Type *base) { #if defined(FSL_FEATURE_ADC16_HAS_CALIBRATION) && FSL_FEATURE_ADC16_HAS_CALIBRATION uint16_t offsetValue = 0; /*!< Offset error from correction value. */ #endif adc16_config_t adcUserConfig; adc16_channel_config_t adcChnConfig; #if defined(FSL_FEATURE_ADC16_HAS_CALIBRATION) && FSL_FEATURE_ADC16_HAS_CALIBRATION /* Auto calibration */ ADC16_DoAutoCalibration(base); offsetValue = base->OFS; ADC16_SetOffsetValue(base, offsetValue); #endif /* * Initialization ADC for * 16bit resolution, interrupt mode, hw trigger enabled. * normal convert speed, VREFH/L as reference, * disable continuous convert mode. */ /* * adcUserConfig.referenceVoltageSource = kADC16_ReferenceVoltageSourceVref; * adcUserConfig.clockSource = kADC16_ClockSourceAsynchronousClock; * adcUserConfig.enableAsynchronousClock = true; * adcUserConfig.clockDivider = kADC16_ClockDivider8; * adcUserConfig.resolution = kADC16_ResolutionSE12Bit; * adcUserConfig.longSampleMode = kADC16_LongSampleDisabled; * adcUserConfig.enableHighSpeed = false; * adcUserConfig.enableLowPower = false; * adcUserConfig.enableContinuousConversion = false; */ ADC16_GetDefaultConfig(&adcUserConfig); adcUserConfig.resolution = kADC16_Resolution16Bit; /* enabled hardware trigger */ ADC16_EnableHardwareTrigger(base, true); adcUserConfig.enableContinuousConversion = false; adcUserConfig.clockSource = kADC16_ClockSourceAsynchronousClock; adcUserConfig.longSampleMode = kADC16_LongSampleCycle24; adcUserConfig.enableLowPower = 1; #if ((defined BOARD_ADC_USE_ALT_VREF) && BOARD_ADC_USE_ALT_VREF) adcUserConfig.referenceVoltageSource = kADC16_ReferenceVoltageSourceValt; #endif ADC16_Init(base, &adcUserConfig); adcChnConfig.channelNumber = kAdcChannelTemperature; #if defined(FSL_FEATURE_ADC16_HAS_DIFF_MODE) && FSL_FEATURE_ADC16_HAS_DIFF_MODE adcChnConfig.enableDifferentialConversion = false; #endif adcChnConfig.enableInterruptOnConversionCompleted = true; /* Configure channel 0 */ ADC16_SetChannelConfig(base, DEMO_ADC16_CHANNEL_GROUP, &adcChnConfig); return true; }
/*! * @brief calibrate parameters: VDD and ADCR_TEMP25 */ static void ADC16_CalibrateParams(ADC_Type *base) { uint32_t bandgapValue = 0; /*! ADC value of BANDGAP */ uint32_t vdd = 0; /*! VDD in mV */ adc16_config_t adcUserConfig; adc16_channel_config_t adcChnConfig; pmc_bandgap_buffer_config_t pmcBandgapConfig; pmcBandgapConfig.enable = true; #if (defined(FSL_FEATURE_PMC_HAS_BGEN) && FSL_FEATURE_PMC_HAS_BGEN) pmcBandgapConfig.enableInLowPowerMode = false; #endif #if (defined(FSL_FEATURE_PMC_HAS_BGBDS) && FSL_FEATURE_PMC_HAS_BGBDS) pmcBandgapConfig.drive = kPmcBandgapBufferDriveLow; #endif /* Enable BANDGAP reference voltage */ PMC_ConfigureBandgapBuffer(PMC, &pmcBandgapConfig); /* * Initialization ADC for * 16bit resolution, interrupt mode, hw trigger disabled. * normal convert speed, VREFH/L as reference, * disable continuous convert mode */ /* * adcUserConfig.referenceVoltageSource = kADC16_ReferenceVoltageSourceVref; * adcUserConfig.clockSource = kADC16_ClockSourceAsynchronousClock; * adcUserConfig.enableAsynchronousClock = true; * adcUserConfig.clockDivider = kADC16_ClockDivider8; * adcUserConfig.resolution = kADC16_ResolutionSE12Bit; * adcUserConfig.longSampleMode = kADC16_LongSampleDisabled; * adcUserConfig.enableHighSpeed = false; * adcUserConfig.enableLowPower = false; * adcUserConfig.enableContinuousConversion = false; */ ADC16_GetDefaultConfig(&adcUserConfig); adcUserConfig.resolution = kADC16_Resolution16Bit; adcUserConfig.enableContinuousConversion = false; adcUserConfig.clockSource = kADC16_ClockSourceAsynchronousClock; adcUserConfig.enableLowPower = 1; adcUserConfig.longSampleMode = kADC16_LongSampleCycle24; #ifdef BOARD_ADC_USE_ALT_VREF adcUserConfig.referenceVoltageSource = kADC16_ReferenceVoltageSourceValt; #endif ADC16_Init(base, &adcUserConfig); #if defined(FSL_FEATURE_ADC16_HAS_CALIBRATION) && FSL_FEATURE_ADC16_HAS_CALIBRATION /* Auto calibration */ ADC16_DoAutoCalibration(base); #endif #if defined(FSL_FEATURE_ADC16_HAS_HW_AVERAGE) && FSL_FEATURE_ADC16_HAS_HW_AVERAGE /* Use hardware average to increase stability of the measurement */ ADC16_SetHardwareAverage(base, kADC16_HardwareAverageCount32); #endif /* FSL_FEATURE_ADC16_HAS_HW_AVERAGE */ adcChnConfig.channelNumber = kAdcChannelBandgap; #if defined(FSL_FEATURE_ADC16_HAS_DIFF_MODE) && FSL_FEATURE_ADC16_HAS_DIFF_MODE adcChnConfig.enableDifferentialConversion = false; #endif adcChnConfig.enableInterruptOnConversionCompleted = false; ADC16_SetChannelConfig(base, DEMO_ADC16_CHANNEL_GROUP, &adcChnConfig); /* Wait for the conversion to be done */ while (!ADC16_GetChannelStatusFlags(base, DEMO_ADC16_CHANNEL_GROUP)) { } /* Get current ADC BANDGAP value */ bandgapValue = ADC16_GetChannelConversionValue(base, DEMO_ADC16_CHANNEL_GROUP); ADC16_PauseConversion(base); /* Get VDD value measured in mV: VDD = (ADCR_VDD x V_BG) / ADCR_BG */ vdd = ADCR_VDD * V_BG / bandgapValue; /* Calibrate ADCR_TEMP25: ADCR_TEMP25 = ADCR_VDD x V_TEMP25 / VDD */ adcrTemp25 = ADCR_VDD * V_TEMP25 / vdd; /* ADCR_100M = ADCR_VDD x M x 100 / VDD */ adcr100m = (ADCR_VDD * M) / (vdd * 10); /* Disable BANDGAP reference voltage */ pmcBandgapConfig.enable = false; PMC_ConfigureBandgapBuffer(PMC, &pmcBandgapConfig); }
/*! * @brief Main function */ int main(void) { adc16_config_t adc16ConfigStruct; adc16_channel_config_t adc16ChannelConfigStruct; BOARD_InitPins(); BOARD_BootClockRUN(); BOARD_InitDebugConsole(); EnableIRQ(DEMO_ADC16_IRQn); PRINTF("\r\nADC16 interrupt Example.\r\n"); /* * adc16ConfigStruct.referenceVoltageSource = kADC16_ReferenceVoltageSourceVref; * adc16ConfigStruct.clockSource = kADC16_ClockSourceAsynchronousClock; * adc16ConfigStruct.enableAsynchronousClock = true; * adc16ConfigStruct.clockDivider = kADC16_ClockDivider8; * adc16ConfigStruct.resolution = kADC16_ResolutionSE12Bit; * adc16ConfigStruct.longSampleMode = kADC16_LongSampleDisabled; * adc16ConfigStruct.enableHighSpeed = false; * adc16ConfigStruct.enableLowPower = false; * adc16ConfigStruct.enableContinuousConversion = false; */ ADC16_GetDefaultConfig(&adc16ConfigStruct); ADC16_Init(DEMO_ADC16_BASE, &adc16ConfigStruct); ADC16_EnableHardwareTrigger(DEMO_ADC16_BASE, false); /* Make sure the software trigger is used. */ #if defined(FSL_FEATURE_ADC16_HAS_CALIBRATION) && FSL_FEATURE_ADC16_HAS_CALIBRATION if (kStatus_Success == ADC16_DoAutoCalibration(DEMO_ADC16_BASE)) { PRINTF("ADC16_DoAutoCalibration() Done.\r\n"); } else { PRINTF("ADC16_DoAutoCalibration() Failed.\r\n"); } #endif /* FSL_FEATURE_ADC16_HAS_CALIBRATION */ 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. */ #if defined(FSL_FEATURE_ADC16_HAS_DIFF_MODE) && FSL_FEATURE_ADC16_HAS_DIFF_MODE adc16ChannelConfigStruct.enableDifferentialConversion = false; #endif /* FSL_FEATURE_ADC16_HAS_DIFF_MODE */ g_Adc16InterruptCounter = 0U; while (1) { GETCHAR(); g_Adc16ConversionDoneFlag = false; /* When in software trigger mode, each conversion would be launched once calling the "ADC16_ChannelConfigure()" function, which works like writing a conversion command and executing it. For another channel's conversion, just to change the "channelNumber" field in channel configuration structure, and call the function "ADC16_ChannelConfigure()"" again. Also, the "enableInterruptOnConversionCompleted" inside the channel configuration structure is a parameter for the conversion command. It takes affect just for the current conversion. If the interrupt is still required for the following conversion, it is necessary to assert the "enableInterruptOnConversionCompleted" every time for each command. */ 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); } }