Professional Documents
Culture Documents
ADC + Interrupt
ADC + Interrupt
• The ADC reports a ratio-metric value. This means that the ADC
assumes 5V is 1023 and anything less than 5V will be a ratio between
5V and 1023.
• 𝑅𝑒𝑠𝑜𝑙𝑢𝑡𝑖𝑜𝑛 𝑜𝑓 𝑡ℎ𝑒 𝐴𝐷𝐶
𝑆𝑦𝑠𝑡𝑒𝑚 𝑉𝑜𝑙𝑡𝑎𝑔𝑒
=
𝐴𝐷𝐶 𝑅𝑒𝑎𝑑𝑖𝑛𝑔
𝐴𝑛𝑎𝑙𝑜𝑔 𝑉𝑜𝑙𝑡𝑎𝑔𝑒 𝑀𝑒𝑎𝑠𝑢𝑟𝑒𝑑
• 1023
5
=
𝑥
2.5
=> 𝑥 = 511.5 ≈ 512
• If the analog voltage is 2.12V what will the ADC report as a value?
• 1023
5
=
𝑥
2.12
=> 𝑥 = 433.752 ≈ 434
Registers Used for ADC
• ADMUX- ADC Multiplexer Selection Register
• ADCSRA- ADC Control and Status Register A
• ADCL & ADCH- ADC Data Registers
ADMUX
(ADC Multiplexer Selection Register)
• Bit 0 – MUX0
• Bit 1 – MUX1
• Bit 2 – MUX2
• Bit 3 – MUX 3
• Bit 4 – Reserved
• Bit 5 – ADLAR
• Bit 6 – REFS0
• Bit 7 – REFS1
• Bits 7:6 – REFS1:0 – Reference Selection Bits – These bits are used to
choose the reference voltage. The following combinations are used.
• Bits 3:0 – MUX3:0 - Analog Channel Selection Bits: To select ADC0 – ADC5
channels, we use the combination of MUX0 – MUX3 bits.
• Bit 5 – ADLAR – ADC Left Adjust Result – Make it ‘1’ to Left Adjust the ADC
Result. We will discuss about this a bit later.
ADCSRA
(ADC Control and Status Register A)
• Bit 0 – ADPS0
• Bit 1 – ADPS1
• Bit 2 – ADPS2
• Bit 3 – ADIE
• Bit 4 – ADIF
• Bit 5 – ADFR
• Bit 6 – ADSC
• Bit 7 - ADEN
• Bits 2:0 – ADPS2:0: ADC Prescaler Select Bits – The ADC used in Atmega8
supports 250 KHz sampling rate. But, the MCU has 1 MHz or, 4 MHz or, 12
MHz operating frequency that is far more higher than 250 KHz. So, we
have to set prescale rate to reduce the main MCU frequency.
• If the MCU operating frequency = 8 MHz then, setting 111 means the
8 𝑀𝐻𝑧
frequency for ADC will be = = 62.5 KHz < 250 KHz
128
• Bit 7 – ADEN: ADC Enable - Writing this bit to one enables the ADC. By
writing it to zero, the ADC is turned off. Turning the ADC off while a
conversion is in progress, will terminate this conversion
• Bit 6 – ADSC: ADC Start Conversion - Write this bit to one to start each
conversion.
ADCL & ADCH
(ADC Data Register)
• If ADLAR = 1, the 8 – bit of ADCH will be used, rest 2 – bit will be used from
the ADCL taking the most significant 2 – bits.
Now, It’s Initialization Time
• Reference Selection
• Prescale Selection
• Enabling ADC
void adc_init(void)
{
ADMUX |= (1 << REFS1) | (1 << REFS0); // Internal reference 2.56V is used as reference voltage.
}
Then, Read The ADC
• Channel Selection
• Start Conversion
• Read Data
uint16_t adc_read(void)
{
ADMUX |= (1 << MUX0);// To select ADC1 as channel set value 0001
ADCSRA |= (1 << ADSC); // Start Conversion
// whenever ADSC will be set, ADC conversion will start. Whenever the
// conversion will end the ADSC will automatically clear. So, we have to check
// when the conversation is going to end using a loop.
while(ADCSRA & (1 << ADSC))
{
}
return ADCW; // 10–bit ADCL and ADCH merges to ADCW
}
int main(void)
{
DDRB |= (1 << DDB0); //Set data Direction
uint16_t adc_value = 0;//Initialize the variable
adc_init();//Initialize ADC.
while(1)
{
adc_value = adc_read();
if(adc_value < 100)
{
PORTB = 0b00000000;
}
else
{
PORTB = 0b00000001;
}
}
return 0;
}
Interrupt
What Is Interrupt?
• Bit 7 – I: Global Interrupt Enable - The Global Interrupt Enable bit must be
set for the interrupts to be enabled.
MCUCR
(MCU Control Register)
• Bit 0 – ISC00
• Bit 1 – ISC01
• Bit 2 – ISC10
• Bit 3 – ISC11
• Bit 1, 0 – ISC01, ISC00: Interrupt Sense Control 0 Bit 1 and Bit 0 – This
two bits are used for the interrupt sense control of INT0.
• Different combination of ISC01 and ISC00 is selected to define the Interrupt
Sense Control.
• Bit 3, 2 – ISC11, ISC10: Interrupt Sense Control 1 Bit 1 and Bit 0– This two
bits are used for the interrupt sense control of INT0.
• Different combination of ISC11 and ISC10 is selected to define the Interrupt
Sense Control.
GICR
(General Interrupt Control Register)
void init_int0(void);
void init_int0()
{
// To enable Global Interrupt.
sei();
// To enable INT0.
GICR |= (1 << INT0);
}
Code 2
ISR(INT0_vect)
{
int i;
PORTC = 0x00;
_delay_ms(25);
}
}
Code 3
int main(void)
{
int count;
DDRB = 0xFF;
DDRC = 0xFF;
init_int0();
while(1)
{
for(count = 0; count <= 7; count++)
{
PORTB = (1 << count);
_delay_ms(10);
}