/** * \brief Initialize ADC * * Here the averaging feature is disabled. */ static void main_adc_init(void) { /* ADC module configuration structure */ struct adc_config adc_conf; /* ADC channel configuration structure */ struct adc_channel_config adcch_conf; /* Configure the ADC module: * - unsigned, more than 12-bit results * - VCC /2 voltage reference * - 200 kHz maximum clock rate * - freerun conversion triggering * - enabled internal temperature sensor */ adc_read_configuration(&ADCA, &adc_conf); adc_set_conversion_parameters(&adc_conf, ADC_SIGN_OFF, ADC_RES_12, ADC_REF_VCCDIV2); adc_set_clock_rate(&adc_conf, 200000UL); adc_set_conversion_trigger(&adc_conf, ADC_TRIG_FREERUN, 1, 0); adc_enable_internal_input(&adc_conf, ADC_INT_TEMPSENSE); adc_write_configuration(&ADCA, &adc_conf); /* Configure ADC channel 0: * - single-ended measurement from temperature sensor * - interrupt flag set on completed conversion */ adcch_read_configuration(&ADCA, ADC_CH0, &adcch_conf); adcch_set_input(&adcch_conf, ADCCH_POS_TEMPSENSE, ADCCH_NEG_NONE, 1); adcch_set_interrupt_mode(&adcch_conf, ADCCH_MODE_COMPLETE); adcch_disable_interrupt(&adcch_conf); adcch_write_configuration(&ADCA, ADC_CH0, &adcch_conf); /* Enable ADC which starts the freerun conversion.*/ adc_enable(&ADCA); }
int main(void) { struct adc_config adc_conf; struct adc_channel_config adcch_conf; board_init(); sysclk_init(); sleepmgr_init(); irq_initialize_vectors(); cpu_irq_enable(); gfx_mono_init(); // Enable back light of display ioport_set_pin_high(LCD_BACKLIGHT_ENABLE_PIN); // Initialize configuration structures. adc_read_configuration(&ADCA, &adc_conf); adcch_read_configuration(&ADCA, ADC_CH0, &adcch_conf); /* Configure the ADC module: * - unsigned, 12-bit results * - VCC voltage reference * - 200 kHz maximum clock rate * - manual conversion triggering * - temperature sensor enabled * - callback function */ adc_set_conversion_parameters(&adc_conf, ADC_SIGN_ON, ADC_RES_12, ADC_REF_VCC); adc_set_clock_rate(&adc_conf, 200000UL); adc_set_conversion_trigger(&adc_conf, ADC_TRIG_MANUAL, 1, 0); adc_enable_internal_input(&adc_conf, ADC_INT_TEMPSENSE); adc_write_configuration(&ADCA, &adc_conf); adc_set_callback(&ADCA, &adc_handler); /* Configure ADC channel 0: * - single-ended measurement from temperature sensor * - interrupt flag set on completed conversion * - interrupts disabled */ adcch_set_input(&adcch_conf, ADCCH_POS_PIN1, ADCCH_NEG_NONE, 1); adcch_set_interrupt_mode(&adcch_conf, ADCCH_MODE_COMPLETE); adcch_enable_interrupt(&adcch_conf); adcch_write_configuration(&ADCA, ADC_CH0, &adcch_conf); // Enable the ADC and start the first conversion. adc_enable(&ADCA); adc_start_conversion(&ADCA, ADC_CH0); do { // Sleep until ADC interrupt triggers. sleepmgr_enter_sleep(); } while (1); }
int main(void) { struct adc_config adc_conf; struct adc_channel_config adcch_conf; board_init(); sysclk_init(); sleepmgr_init(); irq_initialize_vectors(); cpu_irq_enable(); // Initialize configuration structures. adc_read_configuration(&ADCA, &adc_conf); adcch_read_configuration(&ADCA, ADC_CH0, &adcch_conf); /* Configure the ADC module: * - unsigned, 12-bit results * - bandgap (1 V) voltage reference * - 200 kHz maximum clock rate * - manual conversion triggering * - temperature sensor enabled * - callback function */ adc_set_conversion_parameters(&adc_conf, ADC_SIGN_OFF, ADC_RES_12, ADC_REF_BANDGAP); adc_set_clock_rate(&adc_conf, 200000UL); adc_set_conversion_trigger(&adc_conf, ADC_TRIG_MANUAL, 1, 0); adc_enable_internal_input(&adc_conf, ADC_INT_TEMPSENSE); adc_write_configuration(&ADCA, &adc_conf); adc_set_callback(&ADCA, &adc_handler); /* Configure ADC channel 0: * - single-ended measurement from temperature sensor * - interrupt flag set on completed conversion * - interrupts disabled */ adcch_set_input(&adcch_conf, ADCCH_POS_TEMPSENSE, ADCCH_NEG_NONE, 1); adcch_set_interrupt_mode(&adcch_conf, ADCCH_MODE_COMPLETE); adcch_enable_interrupt(&adcch_conf); adcch_write_configuration(&ADCA, ADC_CH0, &adcch_conf); // Get measurement for 85 degrees C (358 kelvin) from calibration data. tempsense = adc_get_calibration_data(ADC_CAL_TEMPSENSE); // Enable the ADC and start the first conversion. adc_enable(&ADCA); adc_start_conversion(&ADCA, ADC_CH0); do { // Sleep until ADC interrupt triggers. sleepmgr_enter_sleep(); } while (1); }
void owltemp_init() { struct adc_config adc_conf; struct adc_channel_config adcch_conf; // Clear the configuration structures. memset(&adc_conf, 0, sizeof(struct adc_config)); memset(&adcch_conf, 0, sizeof(struct adc_channel_config)); /* Configure the ADC module: * - unsigned, 12-bit results * - bandgap (1 V) voltage reference * - 200 kHz maximum clock rate * - manual conversion triggering * - temperature sensor enabled * - callback function */ adc_set_conversion_parameters(&adc_conf, ADC_SIGN_OFF, ADC_RES_12, ADC_REF_BANDGAP); adc_set_clock_rate(&adc_conf, 200000UL); adc_set_conversion_trigger(&adc_conf, ADC_TRIG_MANUAL, 0, 0); adc_enable_internal_input(&adc_conf, ADC_INT_TEMPSENSE); adc_write_configuration(&ADCA, &adc_conf); adc_set_callback(&ADCA, &adc_handler); /* Configure ADC channel 0: * - single-ended measurement from temperature sensor * - interrupt flag set on completed conversion * - interrupts disabled */ adcch_set_input(&adcch_conf, ADCCH_POS_TEMPSENSE, ADCCH_NEG_NONE, 1); adcch_set_interrupt_mode(&adcch_conf, ADCCH_MODE_COMPLETE); adcch_enable_interrupt(&adcch_conf); adcch_write_configuration(&ADCA, 0, &adcch_conf); // Get measurement for 85 degrees C (358 kelvin) from calibration data. tempsense = adc_get_calibration_data(ADC_CAL_TEMPSENSE); // Enable the ADC and start the first conversion. adc_enable(&ADCA); adc_start_conversion(&ADCA, ADC_CH0); }
/** * \brief Initialize ADC */ static void main_adc_init(void) { /* ADC module configuration structure */ struct adc_config adc_conf; /* ADC channel configuration structure */ struct adc_channel_config adcch_conf; /* Configure the ADC module: * - signed, 12-bit results * - voltage reference = VCC / 1.6 = 3.3V / 1.6 * - 200 kHz maximum clock rate * - manual conversion triggering */ adc_read_configuration(&ADCA, &adc_conf); /* Initialize structures. */ adc_set_conversion_parameters(&adc_conf, ADC_SIGN_ON, ADC_RES_12, ADC_REF_VCC); adc_set_clock_rate(&adc_conf, 200000UL); adc_set_conversion_trigger(&adc_conf, ADC_TRIG_MANUAL, 1, 0); adc_write_configuration(&ADCA, &adc_conf); /* Configure ADC channel: * - differential measurement mode * - Input voltage V+ is ADC2 pin (PA2 pin) * - Input voltage V- is ADC3 pin (PA3 pin) * - 1x gain * - interrupt flag set on completed conversion */ adcch_read_configuration(&ADCA, ADC_CH0, &adcch_conf); adcch_set_input(&adcch_conf, ADCCH_POS_PIN2, ADCCH_NEG_PIN3, 1); adcch_set_interrupt_mode(&adcch_conf, ADCCH_MODE_COMPLETE); adcch_disable_interrupt(&adcch_conf); adcch_write_configuration(&ADCA, ADC_CH0, &adcch_conf); /* Enable ADC */ adc_enable(&ADCA); /* Do useful conversion */ adc_start_conversion(&ADCA, ADC_CH0); adc_wait_for_interrupt_flag(&ADCA, ADC_CH0); }
/** * \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 app_sampling_init(void) { /* QDec configuration */ qdec_get_config_defaults(&qdec_config); qdec_config_phase_pins(&qdec_config, &PORTA, 6, false, 500); qdec_config_enable_rotary(&qdec_config); qdec_config_tc(&qdec_config, &TCC5); qdec_config_revolution(&qdec_config, 40); qdec_enabled(&qdec_config); /* ! ADC module configuration */ struct adc_config adc_conf; /* Configure the ADC module: * - signed, 12-bit results * - VCC reference * - 200 kHz maximum clock rate * - manual conversion triggering * - callback function */ adc_read_configuration(&LIGHT_SENSOR_ADC_MODULE, &adc_conf); adc_set_conversion_parameters(&adc_conf, ADC_SIGN_ON, ADC_RES_12, ADC_REF_VCC); adc_set_clock_rate(&adc_conf, 200000); adc_set_conversion_trigger(&adc_conf, ADC_TRIG_MANUAL, 1, 0); adc_write_configuration(&LIGHT_SENSOR_ADC_MODULE, &adc_conf); adc_set_callback(&LIGHT_SENSOR_ADC_MODULE, &app_sampling_handler); adc_enable(&LIGHT_SENSOR_ADC_MODULE); /* Configure ADC A channel 0 for light and NTC sensors. * - differantial measurement (V- linked on internal GND) * - gain x0.5 * - interrupt flag set on completed conversion * - interrupts enabled */ adcch_read_configuration(&LIGHT_SENSOR_ADC_MODULE, ADC_CH0, &adcch_conf); adcch_set_input(&adcch_conf, LIGHT_SENSOR_ADC_INPUT, ADCCH_NEG_INTERNAL_GND, 0); adcch_set_interrupt_mode(&adcch_conf, ADCCH_MODE_COMPLETE); adcch_enable_interrupt(&adcch_conf); adcch_write_configuration(&LIGHT_SENSOR_ADC_MODULE, ADC_CH0, &adcch_conf); fifo_init(&app_sampling_fifo_desc, app_sampling_fifo_buffer, APP_SAMPLING_FIFO_SIZE); rtc_set_callback(&app_sampling_start); /* Display background */ gfx_mono_draw_line(DISPLAY_SAMPLING_TEXT_POS_X - 3, 0, DISPLAY_SAMPLING_TEXT_POS_X - 3, 32, GFX_PIXEL_SET); app_sampling_display_rate(); gfx_mono_draw_string(DISPLAY_LIGHT_TEXT, DISPLAY_LIGHT_TEXT_POS_X, DISPLAY_LIGHT_TEXT_POS_Y, &sysfont); gfx_mono_draw_filled_rect( DISPLAY_LIGHT_PROBAR_START_POS_X, DISPLAY_LIGHT_PROBAR_START_POS_Y, DISPLAY_LIGHT_PROBAR_START_SIZE_X, DISPLAY_LIGHT_PROBAR_START_SIZE_Y, GFX_PIXEL_SET); gfx_mono_draw_filled_rect( DISPLAY_LIGHT_PROBAR_STOP_POS_X, DISPLAY_LIGHT_PROBAR_STOP_POS_Y, DISPLAY_LIGHT_PROBAR_STOP_SIZE_X, DISPLAY_LIGHT_PROBAR_STOP_SIZE_Y, GFX_PIXEL_SET); /* Start a RTC alarm immediatly */ rtc_set_alarm_relative(0); }
int main(void) { struct adc_config adc_conf; struct adc_channel_config adcch_conf; board_init(); sysclk_init(); sleepmgr_init(); irq_initialize_vectors(); cpu_irq_enable(); // Initialize configuration structures. adc_read_configuration(&ADCA, &adc_conf); adcch_read_configuration(&ADCA, ADC_CH0, &adcch_conf); /* Configure the ADC module: * - unsigned, 12-bit results * - bandgap (1 V) voltage reference * - 200 kHz maximum clock rate * - manual conversion triggering */ adc_set_conversion_parameters(&adc_conf, ADC_SIGN_OFF, ADC_RES_12, ADC_REF_BANDGAP); adc_set_clock_rate(&adc_conf, 200000UL); adc_set_conversion_trigger(&adc_conf, ADC_TRIG_MANUAL, 1, 0); adc_write_configuration(&ADCA, &adc_conf); /* Configure ADC channel 0: * - single-ended measurement from configured input pin * - interrupt flag set on completed conversion */ adcch_set_input(&adcch_conf, INPUT_PIN, ADCCH_NEG_NONE, 1); adcch_set_interrupt_mode(&adcch_conf, ADCCH_MODE_COMPLETE); adcch_disable_interrupt(&adcch_conf); adcch_write_configuration(&ADCA, ADC_CH0, &adcch_conf); // Enable the ADC and do one dummy conversion. adc_enable(&ADCA); adc_start_conversion(&ADCA, ADC_CH0); adc_wait_for_interrupt_flag(&ADCA, ADC_CH0); // Light up LED 1, wait for button press. ioport_set_pin_low(LED1_PIN); wait_for_button(); // Perform oversampling of offset. cal_data.offset = get_mean_sample_value(); // Light up LED 2, wait for button press. ioport_set_pin_low(LED2_PIN); wait_for_button(); // Perform oversampling of 0.9 V for gain calibration. cal_data.gain = get_mean_sample_value() - cal_data.offset; // Turn off LEDs. ioport_set_pin_high(LED1_PIN); ioport_set_pin_high(LED2_PIN); // Enable interrupts on ADC channel, then trigger first conversion. adcch_enable_interrupt(&adcch_conf); adcch_write_configuration(&ADCA, ADC_CH0, &adcch_conf); adc_start_conversion(&ADCA, ADC_CH0); do { // Sleep until ADC interrupt triggers. sleepmgr_enter_sleep(); } while (1); }
/** * \brief This function processes sampled ADC values and calculate * the oversampling result * - Offset error compensation is applied on accumulated ADC value * - After, scaling is done with scaled factor. * - Finally, Analog value at ADC input pin is calculated * - Reset all variable used in ADC ISR and enable ADC interrupt to start * next oversampling Process. */ void adc_oversampled(void) { /* ***********Processing and display of oversampled * Input************* **/ /* Assign sign as +ve (as zero) in default for Rrw ADC count display */ uint8_t sign_flag = 0; /* Offset error Compensation for entire number of samples */ adc_result_accum_processed = adc_result_accumulator - adc_offset; /* Gain error Compensation for entire number of samples */ adc_result_accum_processed = (adc_result_accum_processed * ADC_GAIN_ERROR_FACTOR) >> 16; /* Scale the accumulated result to get over sampled Result */ adc_result_accum_processed = adc_result_accum_processed >> ADC_OVER_SAMP_SCALING_FACTOR; /* Calculate the analog input voltage value * - Input Analog value = (ADC_Count * Reference * Volt)/(2^adcresolution)) */ v_input = (adc_result_accum_processed) * (ADC_OVER_SAMP_REF_VOLT_IN_MICRO); v_input = v_input / ADC_OVER_SAMP_MAX_COUNT; /* If input is negative, assign sign for display and use absolute value */ if (v_input < 0) { v_input = abs(v_input); v_input_ascii_buf[0] = '-'; } else { v_input_ascii_buf[0] = '+'; } /* Convert calculated analog value to ASCII for display */ convert_to_ascii(&v_input_ascii_buf[ASCII_BUFFER_SIZE - 1], v_input); /* Display the result on LCD display */ gfx_mono_draw_string(v_input_ascii_buf, 0, 10, &sysfont); /* If ADC count is negative, assign sign for display and use absolute * value */ if (adc_result_accum_processed < 0) { adc_result_accum_processed = abs(adc_result_accum_processed); sign_flag = 1; } else { sign_flag = 0; } /* Display oversampled raw ADC count on LCD display */ display_adccount((int64_t)adc_result_accum_processed, (uint8_t)42, sign_flag ); /* ***********Processing and display of Single Sampled * Input************* **/ /* Offset error compensation for one sample */ adc_result_one_sample_processed = adc_result_one_sample - adc_offset_one_sample; /* Gain error compensation for one sample */ adc_result_one_sample_processed = (adc_result_one_sample_processed * ADC_GAIN_ERROR_FACTOR) >> 16; /* Calculate the analog input voltage value without oversampling * - Input analog value = (ADC_Count * Reference * Volt)/(2^adcresolution)) */ v_input_one_sample = (adc_result_one_sample_processed) * (ADC_OVER_SAMP_REF_VOLT_IN_MICRO); v_input_one_sample = v_input_one_sample / ADC_NO_OVER_SAMP_MAX_COUNT; /* If input is negative, assign sign for display and use absolute value */ if (v_input_one_sample < 0) { v_input_one_sample = abs(v_input_one_sample); v_input_ascii_buf[0] = '-'; } else { v_input_ascii_buf[0] = '+'; } /* Convert calculated analog value to ASCII for display(no oversampling) */ convert_to_ascii(&v_input_ascii_buf[ASCII_BUFFER_SIZE - 1], v_input_one_sample); /* Display the result on LCD display(no oversampling) */ gfx_mono_draw_string(v_input_ascii_buf, 75, 10, &sysfont); /* If ADC count is negative, assign sign for display and use absolute * value */ if (adc_result_one_sample_processed < 0) { adc_result_one_sample_processed = abs( adc_result_one_sample_processed); sign_flag = 1; } else { sign_flag = 0; } /* Display oversampled raw ADC count on LCD display */ display_adccount((int64_t)adc_result_one_sample_processed, (uint8_t)117, sign_flag ); /*Reset ADC_result accumulator value and ADC_sample count to zero * for next oversampling process */ adc_result_accumulator = 0; adc_result_accum_processed = 0; adc_samplecount = 0; adc_result_one_sample = 0; adc_result_one_sample_processed = 0; /* Configure conversion complete interrupt for ADCB-CH0 to re-start * over sampling */ adcch_set_interrupt_mode(&adc_ch_conf, ADCCH_MODE_COMPLETE); adcch_enable_interrupt(&adc_ch_conf); adcch_write_configuration(&ADCB, ADC_CH0, &adc_ch_conf); }
/** * \brief This function initialize the ADCB,gets ADCB-CH0 offset and configure * ADCB-CH0 for oversampling * - ADCB-CH0 is configured in 12bit, signed differential mode without gain * - To read ADC offset, ADCB-Pin3(PB3) used as both +ve and -ve input * - After reading ADC offset,to start oversampling,ADCB +ve and -ve input * are configured */ void init_adc(void) { /* Initialize configuration structures */ adc_read_configuration(&ADCB, &adc_conf); adcch_read_configuration(&ADCB, ADC_CH0, &adc_ch_conf); /* Configure the ADCB module: * - Signed, 12-bit resolution * - External reference on AREFB pin. * - 250 KSPS ADC clock rate * - Manual conversion triggering * - Callback function */ adc_set_conversion_parameters(&adc_conf, ADC_SIGN_ON, ADC_RES_12, ADC_REF_AREFB); adc_set_clock_rate(&adc_conf, 250000UL); adc_set_conversion_trigger(&adc_conf, ADC_TRIG_MANUAL, 1, 0); adc_write_configuration(&ADCB, &adc_conf); adc_set_callback(&ADCB, &adc_handler); /* Configure ADC B channel 0 for offset calculation * - Differential mode without gain * - Selected Pin3 (PB3) as +ve and -ve input for offset calculation */ adcch_set_input(&adc_ch_conf, ADCCH_POS_PIN3, ADCCH_NEG_PIN3, 1); adcch_write_configuration(&ADCB, ADC_CH0, &adc_ch_conf); /* Enable ADCB */ adc_enable(&ADCB); /* Get ADC offset in to ADC_Offset variable and disable ADC */ adc_offset_one_sample = adc_offset_get_signed(); /* Find ADC_Offset for for total number of samples */ adc_offset = adc_offset_one_sample * ADC_OVER_SAMPLED_NUMBER; /* Disable ADC to configure for oversampling */ adc_disable(&ADCB); /* Configure the ADCB module for oversampling: * - Signed, 12-bit resolution * - External reference on AREFB pin. * - 250 KSPS ADC clock rate * - Free running mode on Channel0 ( First Channel) */ adc_set_conversion_trigger(&adc_conf, ADC_TRIG_FREERUN_SWEEP, 1, 0); adc_write_configuration(&ADCB, &adc_conf); /* Configure ADC B channel 0 for oversampling input * - Differential mode without gain * - Selected Pin1 (PB1) as +ve and Pin2 (PB2) as-ve input * - Conversion complete interrupt */ adcch_set_input(&adc_ch_conf, ADC_OVER_SAMP_POSTIVE_PIN, ADC_OVER_SAMP_NEGATIVE_PIN, 1); adcch_set_interrupt_mode(&adc_ch_conf, ADCCH_MODE_COMPLETE); adcch_enable_interrupt(&adc_ch_conf); adcch_write_configuration(&ADCB, ADC_CH0, &adc_ch_conf); /* Enable ADCB */ adc_enable(&ADCB); }