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;
}
Example #2
0
/**
 * 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);
}
Example #5
0
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));
	}
}