ATmega328P ADC Interrupt

Merhaba Arkadaşlar ,

Arduino olarak bildiğimiz Atmege328P MCU ile adc kesmeleri inceledim. Bu yazımda ADC (analog to digital convertor) interrupt rutini nasıl çalışır örnek bir kod ile size göstereceğim.

English explanation ;

Hi guys I am gonna explain Atmega328p adc interrupt routine. Explanations are Turkish but these are not important. You can only care about datasheet of Atmega328p and you can follow up my Arduino Code. All comments are English you can understand all of them quickly. Happy Coding 🙂


Arduino bize 6 tane analog input saglamakta. Biz bu pinlerin biraz daha derinine inip Atmel in bize bu adc kanallarıyla nasıl bir özellik sağladıgını inceleyeceğiz. Öncelikle elimizde hazır olması için Atmega328p datasheet ve user manueli açalım.

İndirmek için bu linkleri kullanabilirisiniz.

http://www.atmel.com/Images/doc8161.pdf

Arduino ADC zamanı hesaplaması,

Arduino nun üzerinde bulunan 6 adet adc pininden az önce bahsetmiştik. Bu pinler yavas bir adc conversion sağmalakta. Nasıl mı ? 1 adc value için mcu 13 cycle saymakta. Bizim yapacağimız işlem için cok da önemli değil. Presecaler değeri default olarak 128 geliyor. Buda demek oluyor ki MCU clock değerimizi kullanarak ADC mizi çalıştırıyoruz.

Arduino 16MHZ hızın kostugunu datasheetten görebiliyoruz ki bu zaten bizim kafamızda artık default olarak oturmus durumda 🙂 (16000/128 ) khz yada 125 khz yani 13 cycles yaklasık 104 micro saniyeye denk geliyor ki bu da bir adc değeri için harcadıgımız zaman.

// Testing interrupt-based analog reading

// ATMega328p

volatile int readFlag;

volatile int analogVal;

void setup(){

  

  // clear ADLAR in ADMUX (0x7C) to right-adjust the result
  // ADCL will contain lower 8 bits, ADCH upper 2 (in last two bits)

  ADMUX &= B11011111;

  

  // Set REFS1..0 in ADMUX (0x7C) to change reference voltage to the
  // proper source (01)

  ADMUX |= B01000000;

  

  // Clear MUX3..0 in ADMUX (0x7C) in preparation for setting the analog
  // input

  ADMUX &= B11110000;

  

  // Set MUX3..0 in ADMUX (0x7C) to read from AD8 (Internal temp)
  // Do not set above 15! You will overrun other parts of ADMUX. A full
  // list of possible inputs is available in Table 24-4 of the ATMega328
  // datasheet

  ADMUX |= 8;

  // ADMUX |= B00001000; // Binary equivalent

  

  // Set ADEN in ADCSRA (0x7A) to enable the ADC.
  // Note, this instruction takes 12 ADC clocks to execute

  ADCSRA |= B10000000;

  

  //Set ADATE in ADCSRA (0x7A) to enable auto-triggering.

  ADCSRA |= B00100000;

  

  // Clear ADTS2..0 in ADCSRB (0x7B) to set trigger mode to free running.
  // This means that as soon as an ADC has finished, the next will be
  // immediately started.

  ADCSRB &= B11111000;

  

  // Set the Prescaler to 128 (16000KHz/128 = 125KHz)
  // Above 200KHz 10-bit results are not reliable.

  ADCSRA |= B00000111;

  

  // Set ADIE in ADCSRA (0x7A) to enable the ADC interrupt.
  // Without this, the internal interrupt will not trigger.

  ADCSRA |= B00001000;

  

  // Enable global interrupts
  // AVR macro included in <avr/interrupts.h>, which the Arduino IDE
  // supplies by default.

  sei();

  

  // Kick off the first ADC

  readFlag = 0;

  // Set ADSC in ADCSRA (0x7A) to start the ADC conversion

  ADCSRA |=B01000000;

}

// Processor loop

void loop(){

  // Check to see if the value has been updated

  if (readFlag == 1){

    

    // Perform whatever updating needed

    

    readFlag = 0;

  }

  

  // Whatever else you would normally have running in loop().

  

}

// Interrupt service routine for the ADC completion

ISR(ADC_vect){

  // Done reading

  readFlag = 1;

  

  // Must read low first

  analogVal = ADCL | (ADCH << 8);

  

  // Not needed because free-running mode is enabled.
  // Set ADSC in ADCSRA (0x7A) to start another ADC conversion

  // ADCSRA |= B01000000;

}

Her bir registerı define olarak eklemeyi unutmayınız !!!

Şimdi de bit bit nasıl bu işlemi yaptık bi göz atalım.

  ADCSRA |= B00001000;

yada

ADCSRA |= (1 << ADIE); 


Yazabilirsiniz. 


Sözlü olarak söylenecek pek bişi yok arkadaşlar sizlerde datasheet içerisinden ADC interrupt kısmını okuyup örnek kod ile birlikte uygulamasını yapabilirsiniz. 


Hepinize iyi çalışmalar. 

Yorum bırakın