16F88 ADC AYARLARI NASIL OLMALI.

Başlatan greatgonzo, 18 Mart 2012, 18:11:27

greatgonzo

Arkadaşlar 16F88 adc si ile bir sorunum var fakat hatamı bulamadım. Acaba sizin gözünüze takılan birşey varmı. Zira proteus ADC çeviriminin erken başladığı yada 2 çevirim arasında yeterli zaman olmadığına dair hata veriyor. Ayrıca osccon ayarını simüle edemediğine dairde bir hata alıyorum.Bununla ilgili olabilirmi. Başka programlarda osccon hatasına ragmen  sorun yok.

@ DEVICE PIC16F88
@ DEVICE PIC16F88, WDT_ON
@ DEVICE PIC16F88, PWRT_ON
@ DEVICE PIC16F88, PROTECT_OFF
@ DEVICE PIC16F88, MCLR_OFF
@ DEVICE PIC16F88, INTRC_OSC_NOCLKOUT
@ DEVICE PIC16F88, LVP_OFF
@ DEVICE PIC16F88, BOD_ON
@ DEVICE PIC16F88, FCMEN_OFF
@ DEVICE PIC16F88, IESO_OFF
@ DEVICE PIC16F88, CCPMX_OFF
@ DEVICE PIC16F88, DEBUG_OFF
@ DEVICE PIC16F88, WRT_OFF
@ DEVICE PIC16F88, CPD_OFF

DEFINE OSC 4

DEFINE ADC_BITS 10
DEFINE ADC_CLOCK 2
DEFINE ADC_SAMPLEUS 50

OPTION_REG.7=0
OSCCON=%01100110

CMCON=7

TRISA=%00000001
TRISB=%00000000
PORTA=0
PORTB=0

ANSEL=%00000001   'rb0 anolog giriş
ADCON0=%11000101
ADCON1=%10000000

MSJ VAR word

BASLA:
ADCIN 0,msj
KNT:   IF ADCON0.2=1  THEN KNT
GOTO BASLA
END


ete

OSCCON=%01101100 şeklinde olursa 4 Mhz 'e eşitlenmiş olur.

ANSEL=%00000001 şeklindeki komut PORTA.0 pinini ADC girişi olarak ayarlar
ADCON1 = %10000000   şeklinde yalnızca ADCON1 registerine bu değeri veriniz.
ADCON0'a değer vermeyiniz.

KNT:   IF ADCON0.2=1  THEN KNT  satırına gerek yok bunu basic ayarlıyor kendisi zaten.
Onun yerine 100 us lik bir gecikme koymanız yeterli .

Hepsi bu kadar
Ete

greatgonzo

ETE hocam yardımınız için teşekkür ederim. Adc gayet iyi çslışıyor. Proteus çevrim süresinin 1.6us den az olduğunu muhtemelen saat frekansının yanlış olduğunu söylüyor. Hem 4 hemde 8 mhz denedim. DEFINE ADC_CLOCK 3 satırındaki değeri 0 dan 3 e kadar değiştirdim. Acaba derslerinizde gösterdiğiniz bu hesabı yanlışmı anladım yoksa proteustamı bir problem var. OSCCON registerini simüle edemediğine dair hep hata veriyor . Bundan kaynaklanıyor olabilirmi. 16F88 in tüm simülasyonlarında bu hatayı veriyor ama hepsi sıhatli çalışıyor. Hiç böyle bir şey tecrübe ettiniz mi. Vakit ayırdığınız için teşekkür ederim.

Hattuşa

Alıntı yapılan: greatgonzo - 18 Mart 2012, 23:12:11
ETE hocam yardımınız için teşekkür ederim. Adc gayet iyi çslışıyor. Proteus çevrim süresinin 1.6us den az olduğunu muhtemelen saat frekansının yanlış olduğunu söylüyor. Hem 4 hemde 8 mhz denedim. DEFINE ADC_CLOCK 3 satırındaki değeri 0 dan 3 e kadar değiştirdim. Acaba derslerinizde gösterdiğiniz bu hesabı yanlışmı anladım yoksa proteustamı bir problem var. OSCCON registerini simüle edemediğine dair hep hata veriyor . Bundan kaynaklanıyor olabilirmi. 16F88 in tüm simülasyonlarında bu hatayı veriyor ama hepsi sıhatli çalışıyor. Hiç böyle bir şey tecrübe ettiniz mi. Vakit ayırdığınız için teşekkür ederim.
s.a.
arkadaşım isisde adc çevrim süresini hatalı verir, ayrıca sizin adc okuma süresini 1,6uS olarak görmeniz hatalı zira gerçekte siz bu işlemci ile 20uS altına inmeniz imkansız 20uS civarında bir okuma süreniz olur ve bu okuma süresini kristaliniz dolayısıyla işlemci hızınız etki eder. ama şu var isisde siz sağlıklı ölçüm alıyorsanız aşağı-yukarı gerçekte de alırsınız isise güvenmeyin hata versin sorun yok.

ete

Proteus un bazı versiyonlarında bu sorun meydana geliyor maalesef. Bence programın bir kusuru bu.
Yeni versiyonlarda görmedim. Yeni derken 7.9 sp1 ve 7.10 sp0 versiyonlarıdüzgün çalışıyor.
Bunlardan birini yüklemeye çalışın.

Bu hatayı aldığım zaman ben genelde RC (galiba CLOK=3 olanı idi) seçiyordum.
ADCO0 registerine değer verirsenizde bu hatayı alırsınız. Çünki define komutları ile ayarlanan değerleri ADCON0 ayarlamaktadır. Normalde define ile ayarladığınız değerleri Adcon0 registerine değer vererek bozmaya çalışıyordunuz.
Sorun bunlardan da kaynaklanır.
Ya define komutundan  DEFINE ADC_CLOCK 2   satırını kapatacak ve sonra ADCON0 registerinin 6 ve 7 nolu bitlerine değer vererek bunu seçmeniz gerekir. Bu şekilde yapınca hata ortadan kalkıyor idi. Deneyin isterseniz.

Dediğim define satırını kapatın yada silin ve ADCON0 registerine aşağıdaki değeri verin.
ADCON0=%01000000
Ayrıca birde şunu deneyebilirsiniz
ADCON0=%11000000
Sonucu bildirirsiniz.

Ete

greatgonzo

ETE hocam  ver pro-TR arkadaşım yardımlarınız için teşekkür ederim. Rehberliğinizde birkaç deneme yaptım. Zamanla ilgili hatayı kesti. "ADCON0=%11000000" da "ADCON0=%01000000" olarakta problem yok şu anda. Sanırım dahili osilatör olması biraz daha esnek olmasına yardımcı oluyor. "DEFINE ADC_CLOCK 2" satırı 2 yada 3 değeri acık yada kapalı hiç farketmedi heralde adcon 0 değerini sonradan verince msc son verilen komutu baz alıyor. Hatta adcon0 ve adcon1 değerlerini "DEFINE ADC_CLOCK 2" satırını kapatınca dahi sadece osccon satırından hata aldım ki onu hep veriyor. Sadece ölçüm sonucu 0-65xxx olarak bölümlendi. Sonuc olarak sizinde altını çizdiğiniz gibi proteusta bir hata olmalı. Sanırım en sağlıklısı gerçekte denemek olacak :-) Vakit ayırdığınız için çok teşekkür ederim.

Hattuşa

slm ete hocam;
2 konuda sizin bilginize müracaat edecektim.
1. 16f88 in datasheetinde
Alıntı YapIRCF<2:0>: Internal RC Oscillator Frequency Select bits
000 = 31.25 kHz
001 = 125 kHz
010 = 250 kHz
011 = 500 kHz
100 = 1 MHz
101 = 2 MHz
110 = 4 MHz
111 = 8 MHz

yazmaktadır. yani bu işlemcinin içerisinde dahili 8MHZ kristal mi bağlı ve bizim harici kristal bağlamamıza gerek varmı?
OSCCON =%01110000 registerini bu şekilde set etmekle bu iş tamam olur mu?

2. olarakta adc çevrimlerinde adc çevriminin süresinin bitimini beklemek için belirli miktarda bekletme yapmak gerekiyor, bir diğer teknik ise "While ADCON0.2 ==0  :Wend" komutu, yalnız adcon0 dan anladığım ve isisin simülede bu noktada takılma nedeni bizim komutu yanlış belirtmemiz olabilir mi? zira;
Alıntı YapGO/DONE: A/D Conversion Status bit
If ADON = 1:
1 = A/D conversion in progress (setting this bit starts the A/D conversion)
0 = A/D conversion not in progress (this bit is automatically cleared by hardware when the A/D
conversion is complete)

açıklamasında 1 olduğu sürece çevrim devam ediyor demektir ki biz 2. teknikte "While ADCON0.2 ==1  :Wend" olarak kullanmamız gerekir diye düşünüyorum.

ayrıca hocam isisde şimdi farkettim. isisde biz tanımlama kısmında;
Alıntı YapANSEL =%0011111
ADCON0 =%01000001
ADCON1 =%10000000

bu adcon0.2 yi 1 yaptığımızda isis hata mesajı veriyor, isisin hata mesajını almamak ve doğru işlem için adcon0.2 yi 0 ile set etmemiz gerekiyor diye düşünüyorum.

son olarak hocam şu isisin bizi çıldırtan TAD süresi hatası için TAD hesaplamalarının yapılışını birisi tarif etse bu kısmıda doğru yapsak güzel olurdu, yoksa benim gibi acemiler "Declare Adin_Delay =50 ' Allow 50us sample time" 50'uS luk süreyi ezbere koyuyor.elbette ki datasheette açıklama ve hesaplaması mevcut inanın yabancı dil özürlülüğü yüzünden konuya hakim olamıyoruz.

ete

BU işlemcide 8 seçenekli dahili OSC bulunmaktadır. Bunlardan hangisini seçeceğin OSCCON registeri ile yapılmaktadır.
Ancak öncelikle sigorta ayarlarında Dahili OSC seçili olacak ama dahiliden hangisini seçeceğine ise OSCCON registeri karar verecektir.
Data sheet den OSCCON registerine bakarsan;
Bit-7: her zaman sıfır olmaktadır. %0
Bit-6-4:111 ise 8 Mhz seçilmiş olacaktır %0111
bit-3  :0 ise INTRC yani secondary clk ile çalışmaktadır , %01110
bit-2  : 1 frekans stabil diyoruz , %011101
bit-1-0:00 vererek osc yi Fosc<2:0> bitleri tayin ediuor diyoruz , %01110100
O halde OSCCON=%01110100 değerini vererek 8 Mhz dahili OSC yi seçmiş oluruz.

ADC okumalarında Basic çevrim süresinin bitimini kendisi otomatik takip eder.
Bunun için ayrıca bir gecikme koymaya gerek yok. Bunu bende eskiden gecikme koyarak yada ADCON0.2 registerinin sıfır olmasını bekleyerek yapıyordum ama sonradan PBP manualinde bu işi basic in otomatik yaptığını öğrenince artık herhangi bir bekleme yada kontrol yapmıyorum.  Zaman zaman bu konuda hatalar yapılıyor. belki bende yapmışımdır. Doğru işlem ADON biti=1 ise GO/DONE bitinin sıfır olmasını beklemek tir.  Yani;
IF ADCON0.0=1  THEN
  WHILE ADCON0.2=1:wend
ENDIF
şeklinde olmalıdır.
Bir adc çevrim işlemi ni ASM de yapmış olsak şu şekilde yapmamız gerekirdi.
- ANSEL registerinden ilgili ADC pinini Analog yap
- ADC için Ref voltajı seçimini ADCON1 registeri 5-4 bitlerinden ayarla
- ADC giriş kanalını ADCON0 registeri 5-3 bitlerinden seç
- ADCON0 registerinden Çevrim CLK kaynağını seç
- ADC modülü (ADCON0.0=1) aktive et.
- Gerekiyor ise ADC kesmesini aç.
- Bu aşamada dahili kondansatörün şarj olması için acquistation zamanı kadar bekle
- Çevrimi başlat yani ADCON0.2=1 yap
- ADCON0.2 biti sıfır oluncaya kadar bekle
- Kesme açık ise bu bit sıfır olunca otomatik kesme oluşacaktır.
- Bu aşamada ADRESL ve ADRESH regşsterlerinden sonucu alıp kendi değişkenlerine aktar.
Hepsi bu kadar. Dikkat edilirse bekleme ADC modülü aktive ettikten sonra şarj süresi kadar olmalıdır. Fazlası gerekrsiz azı ise kondansatörün yeterince şarj olamamasına sebep olacaktır. Bu nedenle işe Basic açısından bakınca bize gerekli olan işlemci frekansına bağlı olarak CLK kaynağını seçmek ve Define komutları ile gerekli kondansatör şarj süresini (acquistation time) doğru vermek olacaktır.
İsis hata veriyor sa yada takılıyor ise bu seçimler genelde yanlış olduğundandır.

ADCON0.2=1 verdiğiniz zaman isis normalde hata vermez. Ancak hata veriyor ise bunun sebebi henüz kanal seçimi , CLK seçimi, Ref Voltajı seçimi yapılmadığındandır. Bunlar seçili olmadan ADC modülü nasıl açacak yada ne için açacak? tabiiki bu komut hataya sebep olur. Bu dediklerimi yaptıktan sonra ADCON0.2=1 dersen hata vermez. Yukarıda ADC çevirm işini maddeler halinde sıraladım. Bu maddelere uygun komutları Basic de vererek ADCIN komutunu kullanmadan ADC okuması yapabilirsiniz ki ben defalarca yaptım. ADCIN komutu bu işleri otomatik olarak yapmaktadır hepsi bu.

Acquistation time hesabı Data sheet de gösterilmektedir. Ancak hesabı yapmaya gerek duymuyorum. Zira oarada hesap yapılıp sonunda sana bir süre veriliyor. Data sheet EQUATION 12-1: ACQUISITION TIME  tablosunda bu hesap yapılmış ve sonunda süre 19,72us olarak verilmiştir.
ADC modül aktive edildikten sonra kondansatör şarj süresi olarak bu sürenin kullanılması zorunludur. Bu süreyi 100us almak yada 50us almak bence anlamsız oluyor. Doğrusu 20us almaktır.

ADC çevrim CLK kaynağı seçiminde ise İşlemci frekansı esas alınır. Yine data sheet de Tablo 12-1 de muhtelif işlemci frekanslarına göre nasıl yapılacağı gösterilmiştir.

Ete

Hattuşa

bilgiler için tşk ederim hocam  8)

Powered by EzPortal