Пример #1
0
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);
}
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));
	}
}