3.14) On-chip ADC: features, block diagram, operation, SFR used, C programs to convert the analog signal to digital

posted by Hamid Sayyed • November 12, 2025 0 Comments

In embedded systems, analog signals such as temperature, pressure, or light intensity are very common. These signals are continuous in nature and cannot be directly processed by a microcontroller, as it works only with digital data (0s and 1s). The ATmega16 microcontroller comes with an in-built Analog to Digital Converter (ADC) which allows it to convert these real-world analog signals into digital numbers that can be used for computation or control operations. The ADC module of ATmega16 is a key feature that eliminates the need for external ADC ICs, saving both cost and board space. It can read analog inputs from multiple channels, supports adjustable voltage references, and provides an accurate digital output proportional to the input signal voltage. This feature makes ATmega16 suitable for sensor-based and control applications such as temperature monitoring, speed sensing, and robotic automation. Let us now explore the internal working, registers used, and practical C programming of the on-chip ADC in detail.

Features of On-Chip ADC in ATmega16

  • It is a 10-bit successive approximation ADC.
  • Supports up to 8 multiplexed single-ended input channels (ADC0 to ADC7).
  • Conversion time depends on ADC clock frequency, typically between 65 to 260 µs.
  • Can operate in both single conversion and free-running modes.
  • Supports auto-triggering and interrupt-driven ADC operations.
  • Voltage reference can be internal (2.56V), AVCC, or external AREF pin.
  • Digital input buffers can be disabled on ADC pins to reduce power consumption.

Block Diagram of ADC in ATmega16

Analog Inputs Analog MUX Sample & Hold Comparator SAR Logic

Simplified block diagram of 10-bit ADC in ATmega16

Operation of the ADC

The ADC works on the principle of successive approximation. The analog input voltage is first selected using the analog multiplexer. This voltage is then held by the sample-and-hold circuit during conversion. The successive approximation register (SAR) compares the input voltage with a reference voltage and generates a digital output that corresponds to the analog value. The result of this conversion is stored in two data registers (ADCL and ADCH). Depending on configuration, data can be left or right-adjusted for easy reading. Each conversion is started by setting the ADSC bit in ADCSRA register, and the completion is indicated when the ADIF flag is set.

SFR Registers Used for ADC

RegisterDescription
ADMUXMultiplexer Selection Register – selects input channel and reference voltage.
ADCSRAControl and Status Register A – controls enabling, start of conversion, and interrupt flag.
ADCLADC Data Register Low Byte – stores lower 8 bits of conversion result.
ADCHADC Data Register High Byte – stores upper 2 bits of conversion result.
SFIORSpecial Function IO Register – controls auto-trigger sources.
The ADC clock is derived from the system clock and divided by a prescaler. For accurate conversion, the ADC clock frequency should be between 50 kHz and 200 kHz.

C Program to Convert Analog Signal to Digital (ATmega16)


#include <avr/io.h>
#define F_CPU 8000000UL
#include <util/delay.h>

void ADC_Init() {
    ADMUX = (1<<REFS0);                 // AVCC as reference, ADC0 channel selected
    ADCSRA = (1<<ADEN)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0); // Enable ADC, prescaler 128
}

uint16_t ADC_Read(uint8_t channel) {
    channel &= 0x07;                     // Select channel 0–7
    ADMUX = (ADMUX & 0xF8) | channel;    // Set channel in ADMUX
    ADCSRA |= (1<<ADSC);                // Start conversion
    while(ADCSRA & (1<<ADSC));          // Wait till conversion complete
    return ADCW;                         // Return 10-bit result
}

int main(void) {
    uint16_t adc_result;
    DDRC = 0xFF;                         // PORTC as output
    ADC_Init();

    while(1) {
        adc_result = ADC_Read(0);        // Read analog value from channel 0
        if(adc_result > 512)
            PORTC = 0xFF;                // Turn ON LEDs if value above mid
        else
            PORTC = 0x00;                // Turn OFF LEDs otherwise
        _delay_ms(100);
    }
}
  

Practical Considerations

  • Always connect a small capacitor (100nF) between AREF and GND to stabilize the reference voltage.
  • Use analog channels only as input; avoid driving them as digital outputs.
  • Ensure the input voltage never exceeds the reference voltage or AVCC.
  • ADC accuracy depends on reference stability and noise; keep analog traces short.

Conclusion

The on-chip ADC of ATmega16 provides a flexible and powerful way to read analog sensor values and process them digitally. Its 10-bit resolution, multiple channels, and adjustable voltage reference make it highly suitable for precision control systems. By learning how to configure its registers and program conversions using C, students can easily interface various analog sensors and implement automation, monitoring, and signal processing applications effectively.

Comments

Post a Comment

Subscribe to Post Comments [Atom]