Birçok modelde iki adet olan ADC birimi bu seride de 10 bit çözünürlüğe sahip. Eskilerle tüm özellikleri aynı değil. Olay sistemi dışında sonuçları belirli aralıklarla sınırlayabildiğimiz çerçeve modu var.
ADC
ADC birimine analog girişler (AINx) ve dahili girişler bağlanabilir. Referans voltajı VDD, VREFA ve INT REF seçilebilir. ADC biriminde ölçümün nasıl yapacağı örnekleme sayısı, gecikmesi gibi ayarlamalar yapılabilir. Sonuçların toplanarak verilmesi gibi seçenekler sunar. Bu ayarlamaları yaptığımız registerleri açıklayarak ilerlemek daha doğru olacak.
CTRLA registerinde bulunan ENABLE ile ADC birimi çalışmaya başlar. Bu bit "0" ise birim enerji harcamaz ve sayacı sıfırlanır. FREERUN ile ilk ölçüm komutu sonrası sürekli olarak çevrim devam eder. RESSEL ile birimin 10-8 bit arası çözünürlük seçimi yapılır.CTRLB registerinde bulunan SAMPNUM ile sonuçların toplanarak yazılması sağlanabilir.CTRLC de bulunan PRESC sistem saatinin bölme oranını ayarlayarak çalışma frekansını belirleriz. ADC birimi bu seride 50kHz ile 1.5MHz arası frekansta çalışmaya uygundur. REFSEL ile referans kaynak seçimi yapılır. SAMPCAP referans voltajına bağlı olarak seçim yapılır. 1V üstünde "1" yapılmalıdır.CTRLD INTDLY ile ADC birimi başlatılırken oluşacak gecikme ayarlanır. ASDV ile ardışık çevrimler arası gecikme değerleri değişken olacak şekilde ayarların. Bu bit "1" yapıldığında SAMDLY birer birer artar. Bu artış 0x00 ile 0x0F arasında sürekli devam eder. Bu sabit frekanslı örneklemeyi önleyerek sinyalden rastgele örnekler almaya yarar. SAMPDLY ile örnekleme arasındaki gecikme belirlenir.Bir ADC çevrimini gösteren bu şemada başlatma ve örnekleme gecikmesini görebiliriz.Uygulama
İlk olarak ADC birimini kullanmak için gerekli yapılandırmayı yapıyorum. Yapacağım iki uygulamadan biri her çevrimde yoklama yöntemiyle çevrimin bitmesini bekleyecek. Diğerinde ise ölçmeye olay sisteminden buton sinyali ile başlayacak ve kesme sonunda okuma yapılacak.
/*
* attiny1614_adc.c
*
* Created: 27.03.2024 16:57:28
* Author : haluk
*/
#include <avr/io.h>
#include <stdio.h>
#include "tiny1_uart.h"
#include <util/delay.h>
uint16_t adc=0;
char sonuc[10];
int main(void){
CPU_CCP=CCP_IOREG_gc;
CLKCTRL_MCLKCTRLB=(0<<CLKCTRL_PEN_bp);//20mhz
uart_basla(Bd115200);
ADC0.CTRLA|=ADC_RESSEL_10BIT_gc;// adc 10 bit
ADC0.CTRLB|=ADC_SAMPNUM_ACC1_gc;//örnekleme sayısı 2
ADC0.CTRLC|=ADC_REFSEL_VDDREF_gc|ADC_PRESC_DIV32_gc|ADC_SAMPCAP_bm;//referans vdd, prescaler 32 625kHz
ADC0.CTRLD|=ADC_INITDLY_DLY16_gc|ADC_SAMPDLY_3_bm;//başlatma gecikmesi 16, örnekleme gecikmesi 3
ADC0.SAMPCTRL|=ADC_SAMPLEN_2_bm;//örnekleme uzunluğu 2
ADC0.MUXPOS|=ADC_MUXPOS_AIN1_gc;//adc pin seçimi adco ain1 pa1
//ADC0.CALIB|=ADC_DUTYCYC_DUTY50_gc;//1.5MHz üstünde
ADC0.CTRLA|=ADC_ENABLE_bm;//adc0 enable
ADC0.COMMAND=ADC_STCONV_bm;//ölçüm başlatma boş ölçüm
while (1) {
ADC0.COMMAND=ADC_STCONV_bm;//ölçüm başlatma
while (!(ADC0.INTFLAGS&ADC_RESRDY_bm));//sonuç bayrağı bekle
ADC0.INTFLAGS|=ADC_RESRDY_bm;//bayrak temizlendi
adc=ADC0.RES;//sonuç okundu
sprintf(sonuc,"adc: %u\n",adc);
uart_dizi(sonuc);
_delay_ms(100);
}
}
/*
* attiny1614_adc_int.c
*
* Created: 27.03.2024 17:25:12
* Author : haluk
*/
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdio.h>
#include "tiny1_uart.h"
#include <util/delay.h>
volatile uint16_t adc=0;
volatile uint8_t flag=0;
char sonuc[10];
ISR(ADC0_RESRDY_vect){
ADC0.INTFLAGS|=ADC_RESRDY_bm;//bayrak temizlendi
adc=ADC0.RES;
flag=1;
}
int main(void){
CPU_CCP=CCP_IOREG_gc;
CLKCTRL_MCLKCTRLB=(0<<CLKCTRL_PEN_bp);//20mhz
uart_basla(Bd115200);
PORTB.DIRCLR=PIN7_bm;//pb7 giriş butona basıldıkça okuma yapar
PORTB.PIN7CTRL=PORT_PULLUPEN_bm;//pull up
EVSYS.ASYNCCH1=EVSYS_ASYNCCH1_PORTB_PIN7_gc;
EVSYS.ASYNCUSER1=EVSYS_ASYNCUSER1_ASYNCCH1_gc;
ADC0.CTRLA|=ADC_RESSEL_10BIT_gc;// adc 10 bit
ADC0.CTRLB|=ADC_SAMPNUM_ACC1_gc;//örnekleme sayısı 2
ADC0.CTRLC|=ADC_REFSEL_VDDREF_gc|ADC_PRESC_DIV32_gc|ADC_SAMPCAP_bm;//referans vdd, prescaler 32 625kHz
ADC0.CTRLD|=ADC_INITDLY_DLY16_gc|ADC_SAMPDLY_3_bm;//başlatma gecikmesi 16, örnekleme gecikmesi 3
ADC0.SAMPCTRL|=ADC_SAMPLEN_2_bm;//örnekleme uzunluğu 2
ADC0.MUXPOS|=ADC_MUXPOS_AIN1_gc;//adc pin seçimi adco ain1 pa1
ADC0.EVCTRL=ADC_STARTEI_bm;//event sistem başlatma
ADC0.INTCTRL|=ADC_RESRDY_bm;
ADC0.CTRLA|=ADC_ENABLE_bm;//adc0 enable
sei();
while (1) {
if(flag==1){
flag=0;
sprintf(sonuc,"adc: %u\n",adc);
uart_dizi(sonuc);
}
}
}
Hiç yorum yok:
Yorum Gönder