uint16_t get_scaled_vcc(void) { uint16_t adc_result = 0; int8_t offset = 0; offset = ADC_Offset_Get_Unsigned(&ADCB, &(ADCB.CH1), true); ADC_Wait_8MHz(&ADCB); ADC_Ch_Conversion_Start(&ADCB.CH1); while(!ADC_Ch_Conversion_Complete(&ADCB.CH1)); adc_result = ADC_ResultCh_GetWord_Unsigned(&ADCB.CH1, offset); return adc_result; }
/** * Name : adc_init * * Synopsis : void adc_init (void) * * Description : Initialize the main system clock * */ void adc_init (void) { /////////////////FROM XPLAINED 1505//////////////////////////////// // Variable for use when we read the result from an ADC channel //PORTQ.PIN2CTRL = (PORTQ.PIN2CTRL & ~PORT_OPC_gm) | PORT_OPC_PULLDOWN_gc; // This pin must be grounded to "enable" NTC-resistor /* Move stored calibration values to ADC B */ ADC_CalibrationValues_Load(&ADCA); /* Set up ADC A to have signed conversion mode and 8 bit resolution. */ ADC_ConvMode_and_Resolution_Config(&ADCA, true, ADC_RESOLUTION_12BIT_gc); // The ADC has different voltage reference options, controlled by the REFSEL bits in the // REFCTRL register. Here the internal reference is selected ADC_Reference_Config(&ADCA, ADC_REFSEL_VCC_gc); // The clock into the ADC decides the maximum sample rate and the conversion time, and // this is controlled by the PRESCALER bits in the PRESCALER register. Here, the // Peripheral Clock is divided by 8 ( gives 250 KSPS with 2Mhz clock ) ADC_Prescaler_Config(&ADCA, ADC_PRESCALER_DIV8_gc); // The used Virtual Channel (CH0) must be set in the correct mode // In this task we will use single ended input, so this mode is selected /* Setup channel 0 to have single ended input. */ ADC_Ch_InputMode_and_Gain_Config(&ADCA.CH0, ADC_CH_INPUTMODE_SINGLEENDED_gc, ADC_CH_GAIN_1X_gc); ADC_Ch_InputMode_and_Gain_Config(&ADCA.CH1, ADC_CH_INPUTMODE_SINGLEENDED_gc, ADC_CH_GAIN_1X_gc); ADC_Ch_InputMode_and_Gain_Config(&ADCA.CH2, ADC_CH_INPUTMODE_SINGLEENDED_gc, ADC_CH_GAIN_1X_gc); // Setting up the which pins to convert. // Note that the negative pin is internally connected to ground //ADC_Ch_InputMux_Config(&ADCB.CH0, ADC_CH_MUXPOS_PIN9_gc, ADC_CH_MUXNEG_PIN1_gc); ADCA.CH0.MUXCTRL |= ADC_CH_MUXPOS_PIN0_gc; ADCA.CH1.MUXCTRL |= ADC_CH_MUXPOS_PIN1_gc; ADCA.CH2.MUXCTRL |= ADC_CH_MUXPOS_PIN2_gc; // Before the ADC can be used it must be enabled ADC_Enable(&ADCA); // Wait until the ADC is ready ADC_Wait_8MHz(&ADCA); // In the while(1) loop, a conversion is started on CH0 and the 8 MSB of the result is // output on the LEDPORT when the conversion is done /* Get offset value for ADC B. */ adcx.offset = ADC_Offset_Get_Signed(&ADCA, &(ADCA.CH0), true); adcy.offset = ADC_Offset_Get_Signed(&ADCA, &(ADCA.CH1), true); adcz.offset = ADC_Offset_Get_Signed(&ADCA, &(ADCA.CH2), true); }
void adc_init(void) { ADC_CalibrationValues_Load(&ADCA); ADC_ConvMode_and_Resolution_Config(&ADCA, ADC_ConvMode_Unsigned, ADC_RESOLUTION_12BIT_gc); ADC_Prescaler_Config(&ADCA, ADC_PRESCALER_DIV16_gc); ADC_Reference_Config(&ADCA, ADC_REFSEL_VCC_gc); ADC_Ch_InputMode_and_Gain_Config(&ADCA.CH0, ADC_CH_INPUTMODE_SINGLEENDED_gc, ADC_CH_GAIN_1X_gc); ADC_Ch_InputMux_Config(&ADCA.CH0, ADC_CH_MUXPOS_PIN7_gc, ADC_CH_MUXNEG_PIN0_gc); ADC_Enable(&ADCA); ADC_Wait_8MHz(&ADCA); }
void adc_temp_init(void) { // enable 1V reference and temperature modules ADC_BandgapReference_Enable(&ADCB); ADC_TempReference_Enable(&ADCB); // load calibration from signature bytes ADC_CalibrationValues_Load(&ADCB); // Conversion mode and resolution (12 bit right-aligned) ADC_ConvMode_and_Resolution_Config(&ADCB, ADC_ConvMode_Unsigned, ADC_RESOLUTION_12BIT_gc); // prescaler from system clock (fastest) ADC_Prescaler_Config(&ADCB, ADC_PRESCALER_DIV4_gc); // internal 1V reference ADC_Reference_Config(&ADCB, ADC_REFSEL_INT1V_gc); // channel 0 for temperature ADC_Ch_InputMode_and_Gain_Config(&ADCB.CH0, ADC_CH_INPUTMODE_INTERNAL_gc, ADC_CH_GAIN_1X_gc); ADC_Ch_InputMux_Config(&ADCB.CH0, ADC_CH_MUXINT_TEMP_gc, ADC_CH_MUXNEG_PIN0_gc); // channel 1 for VCC/10 ADC_Ch_InputMode_and_Gain_Config(&ADCB.CH1, ADC_CH_INPUTMODE_INTERNAL_gc, ADC_CH_GAIN_1X_gc); ADC_Ch_InputMux_Config(&ADCB.CH1, ADC_CH_MUXINT_SCALEDVCC_gc, ADC_CH_MUXNEG_PIN0_gc); ADC_Enable(&ADCB); ADC_Wait_8MHz(&ADCB); }
void InitADC( ADC_t *ADC_Pointer ) { // Initialize sweep for channel 0, 1, 2 and 3 ADC_SweepChannels_Config( ADC_Pointer, ADC_SWEEP_0123_gc ); // Setup event to start synchronized sweep ADC_Events_Config( ADC_Pointer, ADC_EVSEL_0123_gc, ADC_EVACT_SYNCHSWEEP_gc ); // Initialize the four channels to convert in single ended mode ADC_Ch_InputMode_and_Gain_Config( &ADC_Pointer->CH0, ADC_CH_INPUTMODE_SINGLEENDED_gc, ADC_CH_GAIN_1X_gc ); ADC_Ch_InputMode_and_Gain_Config( &ADC_Pointer->CH1, ADC_CH_INPUTMODE_SINGLEENDED_gc, ADC_CH_GAIN_1X_gc ); ADC_Ch_InputMode_and_Gain_Config( &ADC_Pointer->CH2, ADC_CH_INPUTMODE_SINGLEENDED_gc, ADC_CH_GAIN_1X_gc ); ADC_Ch_InputMode_and_Gain_Config( &ADC_Pointer->CH3, ADC_CH_INPUTMODE_SINGLEENDED_gc, ADC_CH_GAIN_1X_gc ); // Route the channels to different pins // Note that in Single Ended Mode, there is no negative input ADC_Ch_InputMux_Config( &ADC_Pointer->CH0, ADC_CH_MUXPOS_PIN1_gc, 0 ); ADC_Ch_InputMux_Config( &ADC_Pointer->CH1, ADC_CH_MUXPOS_PIN2_gc, 0 ); ADC_Ch_InputMux_Config( &ADC_Pointer->CH2, ADC_CH_MUXPOS_PIN3_gc, 0 ); ADC_Ch_InputMux_Config( &ADC_Pointer->CH3, ADC_CH_MUXPOS_PIN4_gc, 0 ); // Sample rate is CPUFREQ / 32. @ 2 MHz this equals 62,5ksps ADC_Prescaler_Config( ADC_Pointer, ADC_PRESCALER_DIV32_gc); // Set up ADCx to have unsigned conversion mode and 8 bit resolution ADC_ConvMode_and_Resolution_Config( ADC_Pointer, false, ADC_RESOLUTION_8BIT_gc ); // Set reference voltage on ADCx to be VCC/1.6 V ADC_Reference_Config( ADC_Pointer, ADC_REFSEL_VCC_gc ); // Enable the ADC ADC_Enable( ADC_Pointer ); // Wait until common mode voltage is stable. Default clk is 2MHz and // therefore within the maximum frequency to use this function. ADC_Wait_8MHz( ADC_Pointer ); }
int main(void) { // Add code to sweep CH0 and CH1 in free running mode // Use the function call in the adc_driver.h ADC_SweepChannels_Config( &ADCB, ADC_SWEEP_01_gc); //Enable internal temperature sensor, to be used by CH1 ADC_TempReference_Enable(&ADCB); // Setup CH1 to have single ended input as in task1 and task2 ADC_Ch_InputMode_and_Gain_Config(&ADCB.CH0, ADC_CH_INPUTMODE_SINGLEENDED_gc, ADC_CH_GAIN_1X_gc); // Set input to CH0 in ADC B to be PIN 1 ADC_Ch_InputMux_Config(&ADCB.CH0, ADC_CH_MUXPOS_PIN1_gc, 0); // Setup CH1 to read internal signal ADC_Ch_InputMode_and_Gain_Config(&ADCB.CH1, ADC_CH_INPUTMODE_INTERNAL_gc, ADC_CH_GAIN_1X_gc); // CH1 is set up to measure the internal temperature sensor ADC_Ch_InputMux_Config(&ADCB.CH1, ADC_CH_MUXINT_TEMP_gc, 0); // Set up ADC B to have unsigned conversion mode and 12 bit resolution ADC_ConvMode_and_Resolution_Config(&ADCB, false, ADC_RESOLUTION_12BIT_gc); // Set reference voltage on ADC B to be VCC/1.6 V ADC_Reference_Config(&ADCB, ADC_REFSEL_VCC_gc); // Sample rate is CPUFREQ/16. ADC_Prescaler_Config(&ADCB, ADC_PRESCALER_DIV16_gc); // Enable ADC B ADC_Enable(&ADCB); // Wait until common mode voltage is stable. Default clk is 2MHz and // therefore within the maximum frequency to use this function. ADC_Wait_8MHz(&ADCB); // Enable ADC B free running mode ADC_FreeRunning_Enable(&ADCB); // Set the LEDPORT as output LEDPORT.DIR = 0xFF; while(1) { // When CH1IF is set, both conversions are done since CH0 is started first // Wait for CH1IF to be set do { } while ((ADCB.INTFLAGS & ADC_CH1IF_bm) != ADC_CH1IF_bm); // Clear CH1 Interrupt Flag ADCB.INTFLAGS |= ADC_CH1IF_bm; // Read the CH0 result register, 12 bit unsigned (0-4095) ADC_result_CH0 = ADCB.CH0RES; // Read the CH1 result register ADC_result_CH1 = ADCB.CH1RES; // Shift CH0 result to get the 4 MSB of the input signal on the 4 LSB of the LEDs ADC_result_CH0 >>= 8; // Shift CH1 result to get the 4 MSB of the temperature on the 4 MSB of the LEDs // Also downscale it to 4 bit. Try touching the Xmega to warm it up. ADC_result_CH1 = ((ADC_result_CH1 - 1) / 16); ADC_result_CH1 <<= 4; // Output on the LEDs, the 4 MSB is the internal temperature reading, // and the 4 LSB is the single ended input reading, LEDPORT.OUT = ~( (ADC_result_CH1 & 0x00F0) | (ADC_result_CH0 & 0x000F)); } }