//************************************************************************************** // //! adc_init //! //! @param ADCx: ADCx.ADC_CHANNEL, ADCx.ADC_PRESCALAR, ADCx.ADC_REF, //! ADCx.ADC_MODE //! //! @return none //! //! @brief This function is used to initialize the ADC peripherial. // //************************************************************************************** void adc_init(ADC_Init ADCx) { adc_set_channel(ADCx.ADC_CHANNEL); adc_pin_init(ADCx.ADC_CHANNEL); adc_set_prescalar(ADCx.ADC_PRESCALAR); adc_set_ref(ADCx.ADC_REF); adc_set_mode(ADCx.ADC_MODE); }
int main (void) { // This isn't what we're testing exactly, but we need to know if its // working or not to interpret other results. term_io_init (); PFP ("\n"); PFP ("\n"); PFP ("term_io_init() worked.\n"); PFP ("\n"); // FIXME: audit item: I like to put const after type as Dan Saks advises uint8_t const aip = 0; // Analog Input Pin (from 0 for ADC0 to 5 for ADC5) adc_init (ADC_REFERENCE_AVCC); PFP ("Finished adc_init().\n"); adc_pin_init (aip); // This register bit test is hardwired to match the chosen aip value. // The initialization should have done this, but we can't tell just by // observing that the ADC reads voltages correctly, so we check here. if ( ! (DIDR0 & _BV (ADC0D)) ) { PFP ( "failure: Digital input disable bit ADC0D of register DIDR0 not " "set\n" ); assert (0); } PFP ("Finished adc_pin_init().\n"); PFP ("\n"); // Configure pin A1 (aka PC1) as an output, starting out low. PORTC &= ~(_BV (PORTC1)); //FIXXME: could be a no-op, which recent avr libc have a macro for loop_until_bit_is_clear (PORTC, PORTC1); DDRC |= _BV (DDC1); while ( 1 ) { float const supply_voltage = 5.0; uint16_t raw = adc_read_raw (aip); float tap_voltage = adc_read_voltage (aip, supply_voltage); PFP ("ADC input voltage: %f (%d raw)\r\n", tap_voltage, raw); toggle_pc1 (); float const mspr = 500.0; // Milliseconds Per Reading (and LED toggle) _delay_ms (mspr); } return 0; }
//************************************************************************************** // //! adc_set_channel //! //! @param adcChannel: ADC0, ADC1, ADC2, ADC3, ADC4, ADC5 //! //! @return none //! //! @brief This function is used to set the ADC channel for ADC peripherial. // //************************************************************************************** void adc_set_channel(ADC_Channel adcChannel) { ADMUX &= 0xF0; ADMUX |= (adcChannel << MUX0); adc_pin_init(adcChannel); }