///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // uint8_t adc_start_conversion_get_value(adc_channel_t adc_channel) // // Description: // Starts an ADC conversion on the specified ADC channel and returns the value when finished. It is unnecessary to call adc_set_input_channel() // or adc_start_conversion() before using this function, as this function does that itself. This function should only be used with single step // acquisition mode. // // Parameters: // adc_channel_t adc_channel - ADC channel with which to run the acquisition // // Return value: // Value of last conversion // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// uint16_t adc_start_single_conversion_get_value(adc_channel_t adc_channel) { adc_start_single_conversion(adc_channel); while(adc_is_conversion_in_progress()); return adc_get_result(); }
/** * \brief Wrapper function for getting and ADC sample * * \param adc_ch which channel to get the ADC samples from * /returns 16-bit signed ADC result */ static int16_t adc_get_sample(uint8_t adc_ch) { int16_t result = 0; adc_start_conversion(&CALIBRATION_ADC, adc_ch); adc_wait_for_interrupt_flag(&CALIBRATION_ADC, adc_ch); result = adc_get_result(&CALIBRATION_ADC, adc_ch); adc_clear_interrupt_flag(&CALIBRATION_ADC, adc_ch); return result; }
/** * \brief Get mean sample value * * Performs 2 to the power of \ref OVERSAMPLING_FACTOR successive conversions, * and computes the mean value of the resulting sample values. * * \return Mean sample value. */ static uint16_t get_mean_sample_value(void) { uint32_t sum = 0; uint16_t i; // Sum the configured number of samples. for (i = 0; i < (1 << OVERSAMPLING_FACTOR); i++) { adc_start_conversion(&ADCA, ADC_CH0); adc_wait_for_interrupt_flag(&ADCA, ADC_CH0); sum += adc_get_result(&ADCA, ADC_CH0); } // Compute sample mean by scaling down according to oversampling factor. sum >>= OVERSAMPLING_FACTOR; return sum; }
/** * \brief This function get the offset of the ADCB when it is configured * in signed mode * \note The ADC must be configured and enabled before this function is run. * \return Offset on the ADCB */ static int8_t adc_offset_get_signed(void) { int16_t offset = 0; uint8_t i; /* Sum four samples */ for (i = 0; i < 4; i++) { /* Do one conversion to find offset */ adc_start_conversion(&ADCB, ADC_CH0); adc_wait_for_interrupt_flag(&ADCB, ADC_CH0); /* Accumulate conversion results */ offset += adc_get_result(&ADCB, ADC_CH0); } /* Return mean value */ return ((int8_t)(offset / 4)); }
int main(void) { int16_t adc_res; setClockTo32MHz(); InitDelayTimer(); //InitSerial(); sei(); adc_init(); _delay_ms(2000); //printf("Initializing ADC.\r\n\tOffset ADC: %d\r\n", ADC_ch_u.offset); while(1) { _delay_ms(1000); adc_res = adc_get_result(&ADC_ch_u); //printf("ADC value: %d\r\n", adc_res); } }
int read_cap_level(uint16_t avg_no) { int32_t adcresult = 0; for (uint16_t i = 0; i < avg_no; i++) { ADC_set_input_config (ADCCH_POS_PIN6); //connect ADC to ADC1 which is shorted to VDD. ioport_set_pin_dir(TOUCH_ADC_POS_PIN, IOPORT_DIR_OUTPUT); ioport_set_pin_level(TOUCH_ADC_POS_PIN, false); //set measurement pin to GND PORTA.PIN0CTRL = PORT_OPC_TOTEM_gc; //totem pole ioport_set_pin_dir(TOUCH_ADC_POS_PIN, IOPORT_DIR_INPUT); //input ADC_set_input_config (ADCCH_POS_PIN3); //connect ADC to ADC3 which is sensor previously charged to VDD. adc_start_conversion(&MY_ADC, CAP_ADC); adc_wait_for_interrupt_flag(&MY_ADC, CAP_ADC); adcresult += adc_get_result(&MY_ADC, CAP_ADC); } return adcresult / avg_no; }
int read_cap_level_ref(uint16_t avg_no) { int32_t adcresult = 0; for (uint16_t i = 0; i < avg_no; i++) { ADC_set_input_config (ADCCH_POS_PIN6); //connect ADC to ADC1 which is shorted to VDD. ioport_set_pin_dir(TOUCH_ADC_REF_PIN, IOPORT_DIR_OUTPUT); ioport_set_pin_level(TOUCH_ADC_REF_PIN, false); //set measurement pin to GND _delay_us(10); //make sure it is discharged PORTA.PIN2CTRL = PORT_OPC_TOTEM_gc; //totem pole ioport_set_pin_dir(TOUCH_ADC_REF_PIN, IOPORT_DIR_INPUT); //input ADC_set_input_config (ADCCH_POS_PIN2); //connect ADC to ADC2 which is not connected to anything _delay_us(10); adc_start_conversion(&MY_ADC, CAP_ADC); adc_wait_for_interrupt_flag(&MY_ADC, CAP_ADC); adcresult += adc_get_result(&MY_ADC, CAP_ADC); } return adcresult / avg_no; }
/** * \internal * \brief Measure differential input MUX combinations on channel * * Measures a set of input MUX combinations on a single channel, using averaging * of the number of samples specified with \ref NUM_AVERAGE_SAMPLES. * * \pre This function does not configure the ADC, only the ADC channel, and * therefore the specified ADC needs to be configured before this function * is run. * * \param adc Pointer to ADC to measure with. * \param ch_mask Mask for channel to measure with. * \param mux_pos_inputs Pointer to array of positive input MUX settings. * \param mux_neg_inputs Pointer to array of negative input MUX settings. * \param num_inputs Number of input MUX setting pairs. * \param results Pointer to array to store results in. * \param gain Gain to use for all measurements. * * \note The array which \e results points to must have at least \e num_inputs * elements. */ static void differential_signed_average(ADC_t *adc, uint8_t ch_mask, const uint8_t *mux_pos_inputs, const uint8_t *mux_neg_inputs, uint8_t num_inputs, int16_t *results, uint8_t gain) { struct adc_channel_config adcch_conf; uint8_t input; uint8_t i; int32_t sum; memset(&adcch_conf, 0, sizeof(struct adc_channel_config)); // Common configuration adcch_set_interrupt_mode(&adcch_conf, ADCCH_MODE_COMPLETE); adcch_disable_interrupt(&adcch_conf); for (input = 0; input < num_inputs; input++) { adcch_set_input(&adcch_conf, mux_pos_inputs[input], mux_neg_inputs[input], gain); adcch_write_configuration(adc, ch_mask, &adcch_conf); // Enable and do dummy conversion adc_enable(adc); adc_start_conversion(adc, ch_mask); adc_wait_for_interrupt_flag(adc, ch_mask); // Read an average sum = 0; for (i = 0; i < NUM_AVERAGE_SAMPLES; i++) { adc_start_conversion(adc, ch_mask); adc_wait_for_interrupt_flag(adc, ch_mask); sum += (int16_t)adc_get_result(adc, ch_mask); } adc_disable(adc); results[input] = sum / NUM_AVERAGE_SAMPLES; } }
void alphasense_adc_getValue( void ) { //ALPHASENSE_STATS * const ps = &g_internal; struct adc_config adc_conf; struct adc_channel_config adcch_conf; uint8_t inputgain = 1;//, elements = 20; //char szBUF[64]; // DISABLE jtag - it locks the upper 4 pins of PORT B CCP = CCP_IOREG_gc; // Secret handshake MCU.MCUCR = 0b00000001; PORTB.PIN0CTRL = PORT_OPC_TOTEM_gc; // Auxiliary Electrode PORTB.PIN2CTRL = PORT_OPC_TOTEM_gc; // Working Electrode PORTB.PIN6CTRL = PORT_OPC_TOTEM_gc; // GND x offset adc_read_configuration(&ALPHASENSE_ADC, &adc_conf); adcch_read_configuration(&ALPHASENSE_ADC, ALPHASENSE_ADC_CH, &adcch_conf); adc_set_conversion_parameters(&adc_conf, ADC_SIGN_OFF, ADC_RES_12, ADC_REF_VCC); adc_set_conversion_trigger(&adc_conf, ADC_TRIG_MANUAL, 1, 0); adc_set_clock_rate(&adc_conf, 200000UL); adc_write_configuration(&ALPHASENSE_ADC, &adc_conf); adcch_set_input(&adcch_conf, ADCCH_POS_PIN6, ADCCH_NEG_NONE, inputgain); adcch_write_configuration(&ALPHASENSE_ADC, ALPHASENSE_ADC_CH, &adcch_conf); adc_enable(&ALPHASENSE_ADC); adc_start_conversion(&ALPHASENSE_ADC, ALPHASENSE_ADC_CH); adc_wait_for_interrupt_flag(&ALPHASENSE_ADC, ALPHASENSE_ADC_CH); adc_start_conversion(&ALPHASENSE_ADC, ALPHASENSE_ADC_CH); adc_wait_for_interrupt_flag(&ALPHASENSE_ADC, ALPHASENSE_ADC_CH); const int16_t off = adc_get_result(&ALPHASENSE_ADC, ALPHASENSE_ADC_CH); adc_disable(&ALPHASENSE_ADC); //sprintf_P(szBUF,PSTR("Offset: %u\t"),off); //debug_string(NORMAL,szBUF,false); //adcch_set_input(&adcch_conf, ADCCH_POS_BANDGAP, ADCCH_NEG_NONE, inputgain); //adcch_write_configuration(&ALPHASENSE_ADC, ALPHASENSE_ADC_CH, &adcch_conf); //adc_enable(&ALPHASENSE_ADC); //adc_start_conversion(&ALPHASENSE_ADC, ALPHASENSE_ADC_CH); //adc_wait_for_interrupt_flag(&ALPHASENSE_ADC, ALPHASENSE_ADC_CH); //const uint16_t gain = adc_get_result(&ALPHASENSE_ADC, ALPHASENSE_ADC_CH); //adc_disable(&ALPHASENSE_ADC); ////sprintf_P(szBUF,PSTR("gain: %u\t"),gain); ////debug_string(NORMAL,szBUF,false); adcch_set_input(&adcch_conf, ADCCH_POS_PIN0, ADCCH_NEG_NONE, inputgain); adcch_write_configuration(&ALPHASENSE_ADC, ALPHASENSE_ADC_CH, &adcch_conf); adc_enable(&ALPHASENSE_ADC); adc_start_conversion(&ALPHASENSE_ADC, ALPHASENSE_ADC_CH); adc_wait_for_interrupt_flag(&ALPHASENSE_ADC, ALPHASENSE_ADC_CH); adc_start_conversion(&ALPHASENSE_ADC, ALPHASENSE_ADC_CH); adc_wait_for_interrupt_flag(&ALPHASENSE_ADC, ALPHASENSE_ADC_CH); const int16_t adc_w = adc_get_result(&ALPHASENSE_ADC, ALPHASENSE_ADC_CH)-off; adc_disable(&ALPHASENSE_ADC); //sprintf_P(szBUF,PSTR("ADC_WORK: %u\t"),adc_w); //debug_string(NORMAL,szBUF,false); adcch_set_input(&adcch_conf, ADCCH_POS_PIN2, ADCCH_NEG_NONE, inputgain); adcch_write_configuration(&ALPHASENSE_ADC, ALPHASENSE_ADC_CH, &adcch_conf); adc_enable(&ALPHASENSE_ADC); adc_start_conversion(&ALPHASENSE_ADC, ALPHASENSE_ADC_CH); adc_wait_for_interrupt_flag(&ALPHASENSE_ADC, ALPHASENSE_ADC_CH); adc_start_conversion(&ALPHASENSE_ADC, ALPHASENSE_ADC_CH); adc_wait_for_interrupt_flag(&ALPHASENSE_ADC, ALPHASENSE_ADC_CH); const int16_t adc_a = adc_get_result(&ALPHASENSE_ADC, ALPHASENSE_ADC_CH)-off; adc_disable(&ALPHASENSE_ADC); //sprintf_P(szBUF,PSTR("ADC_AUX: %u\r\n"),adc_a); //debug_string(NORMAL,szBUF,false); //adc_enable(&ALPHASENSE_ADC); // //for (int i=0;i<elements;i++) //{ //adc_start_conversion(&ALPHASENSE_ADC, ALPHASENSE_ADC_CH); //adc_wait_for_interrupt_flag(&ALPHASENSE_ADC, ALPHASENSE_ADC_CH); //adc_start_conversion(&ALPHASENSE_ADC, ALPHASENSE_ADC_CH); //adc_wait_for_interrupt_flag(&ALPHASENSE_ADC, ALPHASENSE_ADC_CH); //result[i]=adc_get_result(&ALPHASENSE_ADC, ALPHASENSE_ADC_CH); // //} //adc_disable(&ALPHASENSE_ADC); PORTB.PIN0CTRL = PORT_OPC_PULLUP_gc; PORTB.PIN2CTRL = PORT_OPC_PULLUP_gc; PORTB.PIN6CTRL = PORT_OPC_PULLUP_gc; g_recordingData_Alphasense = true; g_partialSumWork+=(int32_t)adc_w; g_partialSumAux+=(int32_t)adc_a; g_partialCount_Alphasense++; g_recordingData_Alphasense = false; //sprintf_P(szBUF,PSTR("Sample: %u\tPartialSumWork: %lu\tPartialSumAux: %lu\r\n"),g_partialCount, g_partialSumWork,g_partialSumAux); //debug_string(NORMAL,szBUF,false); //ps->working = adc_w; //ps->aux = adc_a; }