/* This function get the offset of the ADC * * This function makes an internal coupling to the same pin and calculate * the internal offset in the ADC. * * \note This function only return the low byte of the 12-bit convertion, * because the offset should never be more than +-8 LSB off. * * \param adc Pointer to the ADC to calculate offset from. * * \return Offset on the selected ADC */ uint8_t ADC_Offset_Get(ADC_t * adc) { uint8_t offset; // Set up ADC to get offset. ADC_ConvMode_and_Resolution_Config(adc, true, ADC_RESOLUTION_12BIT_gc); ADC_Prescaler_Config(adc , ADC_PRESCALER_DIV8_gc); ADC_Referance_Config(adc , ADC_REFSEL_INT1V_gc); ADC_Ch_InputMode_and_Gain_Config(&(adc->CH0), ADC_CH_INPUTMODE_DIFF_gc, ADC_CH_GAIN_1X_gc); ADC_Ch_InputMux_Config(&(adc->CH0), ADC_CH_MUXPOS_PIN0_gc, ADC_CH_MUXNEG_PIN0_gc); // Enable ADC. ADC_Enable(adc); // Wait until ADC is ready. ADC_Wait_32MHz(adc); // Do one conversion to find offset. ADC_Ch_Conversion_Start(&(adc->CH0)); do{ }while(!ADC_Ch_Conversion_Complete(&(adc->CH0))); offset = ADC_ResultCh_GetLowByte(&(adc->CH0), 0x00); // Disable ADC. ADC_Disable(adc); return offset; }
uint16_t readADC(){ uint16_t ADC_result = 0; int8_t offset; /* Move stored calibration values to ADC B */ ADC_CalibrationValues_Load(&ADCA); /* Set up ADC B to have signed conversion mode and 12 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 decide 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_DIFF_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(&ADCA.CH0, ADC_CH_MUXPOS_PIN0_gc, ADC_CH_MUXNEG_PIN1_gc); // Before the ADC can be used it must be enabled ADC_Enable(&ADCA); // Wait until the ADC is ready ADC_Wait_32MHz(&ADCA); // In the while(1) loop, a conversion is started on CH0 and the 8 MSB of the result is // ouput on the LEDPORT when the conversion is done /* Get offset value for ADC B. */ offset = ADC_Offset_Get_Unsigned(&ADCA, &(ADCA.CH0), true); for(int i = 0; i<5; i++){ ADC_Ch_Conversion_Start(&ADCA.CH0); while(!ADC_Ch_Conversion_Complete(&ADCA.CH0)); //ADCB.INTFLAGS = ADC_CH0IF_bm; // Clear CH0IF by writing a one to it ADC_result += ADCA.CH0RES;// - offset; } return ADC_result/5; }
uint16_t get_chip_temperature(void) { uint16_t adc_result = 0; int8_t offset = 0; offset = ADC_Offset_Get_Unsigned(&ADCB, &(ADCB.CH0), true); ADC_Ch_Conversion_Start(&ADCB.CH0); while(!ADC_Ch_Conversion_Complete(&ADCB.CH0)); adc_result = ADC_ResultCh_GetWord_Unsigned(&ADCB.CH0, offset); return adc_result; }
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; }
uint16_t get_ambient_light(void) { uint16_t adc_result = 0; int8_t offset = 0; offset = ADC_Offset_Get_Unsigned(&ADCA, &(ADCA.CH0), true); // enable ambient light sensor AMBIENT_PORT.DIRSET = AMBIENT_ENABLE_bm; AMBIENT_PORT.OUTSET = AMBIENT_ENABLE_bm; _delay_us(100); ADC_Ch_Conversion_Start(&ADCA.CH0); while(!ADC_Ch_Conversion_Complete(&ADCA.CH0)); adc_result = ADC_ResultCh_GetWord_Unsigned(&ADCA.CH0, offset); // disable ambient light sensor (to save battery) AMBIENT_PORT.OUTCLR = AMBIENT_ENABLE_bm; return adc_result; }