adc kesme çalışmıyor

Başlatan raskolnikov1975, 04 Ocak 2015, 13:02:21

raskolnikov1975

16F688 kullanıyorum çoğu şeyi denedim ama adc kesmesini bir türlü çalıştıramadım yardımcı olursanız sevinirim.
programı şöyle yazdım nerede hata var datasheetde heryere baktım ama gözden kaçırdığım ne olabilir.


@ DEVICE pic16F688
@ DEVICE pic16F688, WDT_ON
@ DEVICE pic16F688, PWRT_ON
@ DEVICE pic16F688, PROTECT_OFF
@ DEVICE pic16F688, MCLR_OFF
@ DEVICE pic16F688, INTRC_OSC_NOCLKOUT
DEFINE  OSC 4                 'Dahili osilatör kullanılacak
DEFINE ADC_BITS 8 'adc bit
DEFINE ADC_CLOCK 3 'ADC clock (rc = 3)
DEFINE ADC_SAMPLEUS 50 'ADC örnekleme zamanı

INTCON=%11000000 'Kesmeler  aktif
OPTION_REG=%10000000 'dahili  Pull up dirençleri iptal edildi
PIE1.6=1      'ADC İNTERRUPT AÇIK datasheet SF18
OSCCON=%01110100 'OSİLATÖR  KONFİG
ANSEL=%000000011 'ANALOG GİRİŞİ SEÇ
CMCON0=7 '  komparatör pinleri iptal hepsi giris çıkıs
ADCON0=%00000001
ADCON1=255

TRISA=%00000011     'portb0 ve 1 giriş
TRISC=0             'PORTC ÇIKIŞ

symbol SES1=PORTC.0
symbol SES2=PORTC.1
SYMBOL LED1=PORTC.2
SYMBOL LED2=PORTC.3
SYMBOL MOT1=PORTC.4
SYMBOL MOT2=PORTC.5
PORTC=0

A VAR WORD                  ''SES İÇİN SÜRE
B VAR WORD
B=400                       'EN AZ ÖLÜ ZAMAN 400MSN OLDUĞUNDAN A 400 ALTI OLAMAMALI
ADCIN 0,A                   'BAŞLANGIÇ İÇİN ÖLÜ ZAMAN

A=(A*10)+B
                 
PORTC=0

ON INTERRUPT GOTO KESME ;KESME OLUŞTUĞUNDA DALLAN

BASLA:

PAUSE a 'sol taraf için program başlar
LED1=1
MOT1=1
freqout SES1,350,194  '350 MSN SÜRESİNCE 194HZ
SES1=0
LED1=0
MOT1=0

PAUSE a  'sağ taraf için program başlar
LED2=1
MOT2=1
freqout SES2,350,194
SES2=0
LED2=0
MOT2=0

goto BASLA


DISABLE
KESME:
ADCIN 0,A
A=(A*10)+B
PIR1.6=0    'DATASHEET SF19
RESUME
ENABLE
END

ete

Data sheetleri yeterince incelmiyorsunuz sorun burada. Data sheet 69 sayfada , 8.2.5 adc conversion procedure yani adc çevirim prosedürü başlığı altında şunları yazmışlar,
-önce ilgili pini analog kullanacak şekilde giriş olarak ayarla
- adc konfigürasyonunu yap yani, adc clk seçimi, kanal seçimi, ref voltaj seçimi ve format seçimini yapıp adc modülü aktif hale getir diyor. Hemen hepsi adcon0 ve adcon1 registerlerinden yPılıyor bu işlemler. En sonda da adcon0 registeri sıfır nolu biti high yapılarak adc modülü aktif hale getirilmelidir,
- global kesmeler , peripheral kesmeler ve PIE1 registerinin ADIE biti set edilerek kesme aktif hale getirilir. Hemen PIR1 registerin ADIF biti sıfırlanır (öncede oluşmuş kesmeleri kaldırmak için)
- sonra data sheet 73. Sayfada gösterilen acquistation time olarak 5us beklenir.
- sonra adcon0.1 biti set edilerek çevirme işlemi başlatılır.
İşte bu aşamadan sonra çevirme tamamlanır tamalanmaz kesme oluşur ve program kesme etiketine atlar. Orada kesme bayrağı sıfırlanıp adc değeri, adresH ve adresL registerlerinden okunur.
Kesmeden çıkılır.
Ete


raskolnikov1975

ete hocam dediklerinizi yaptım ve register ayarlarını tektek ayarladım farklı ayarladım olmadı çalıştıramadım olay basit tek led yanıp sönme süresi ayarlanacak fakat adc interrupt kullanılacak nedense 877 de birçok defa yaptığım kesme burada olmuyor.

Hattuşa

slm ete hocam bir luzumsuzluk yapıp adc kesmesi ile ilgili bir deneme yapmak istedim, isis şemasını oluşturup aşağıdaki kodu yazdım. simülede adc kesmesi 1 defa oluşup adc değerini ekrana basıyorum ama potla oynayıp adc değerini değiştirmek istediğimde bir sonuç alamıyorum, acaba neyi atladım koda bir bakabilirmisiniz? isis şema ektedir.
;-------------------------------------------------------------------------------
;**** Added by Fuse Configurator ****
; Use the Fuse Configurator plug-in to change these settings

Device = 16F876A

Config FOSC_XT, WDTE_OFF, PWRTE_OFF, BOREN_OFF, LVP_OFF, CPD_OFF, WRT_OFF, DEBUG_OFF, CP_OFF

;**** End of Fuse Configurator Settings ****
;-------------------------------------------------------------------------------
Xtal 4
TRISA =%00000001
TRISB =%00000000
TRISC =%00000000
PORTA =0
PORTB =0
PORTC =0
CMCON =7
Declare LCD_DTPin PORTC.4  ' LCD Data Pin   
Declare LCD_RSPin PORTC.2  ' LCD RS Pin
Declare LCD_ENPin PORTC.3  ' LCD EN Pin
Declare LCD_Lines 2        ' LCD Satır
Declare LCD_Interface 4    ' LCD Data Pin Sayısı 4
Cls
DelayMS 100
OPTION_REG.7 =1 'portb pulluplar kapalı
Symbol ADIF =PIR1.6    'adc kesme bayrağı
Symbol ADIE =PIE1.6    'adckesmesi
Symbol GIE  =INTCON.7 'kesme aktif
Symbol PEIE =INTCON.6  'çevresel kesme
GIE =1
ADIF =0
ADIE =1
PEIE =1
GIE =0

ADCON0 =%00000101
ADCON1 =%10001110  '1 kanal seçili

Dim AdC As Word
Dim BaK As Bit
BaK =0

Print At 1,1,"ADC KESME DENEME"
Print At 2,1,"ADC="
DelayMS 100
GIE =1
On_Hardware_Interrupt GoTo KeSMe
BASLA:
If BaK =1 Then
   BaK =0
   Print At 2,5,Dec AdC," "
   DelayMS 10
   EndIf
GoTo BASLA
   

KeSMe:
Context Save
PORTC.0 =1
AdC.HighByte =ADRESH
AdC.LowByte =ADRESL
BaK =1
ADIF =0      'adc bayrak temizlendi
PORTC.0 =0
Context Restore

End

ete

#4
Ana program bölümünde;
- önce ADCON0.0 biti HIGH yapılarak adc modülü aktif hale getirilecek.
- Sonra 20us bekle
- Sonra ADCON0,1 nolu biti HIGH yapılacak işte bu bit kesmeyi harekete geçirecek ve bu bit sıfır olunca otomatik kesme oluşacaktır.
Kesme içinde ADCON.0 biti yeniden LOW yapılmalıdır.
Ete

Hattuşa

@ete hocam dediğiniz gibi yaptım çalıştı, ancak bu seferde isis "ADC conversion started before "wait" time has expired following previous conversion or channel change" hatasını sürekli veriyor, birde hocam sizin söylediğiniz GO/DONE biti değil mi? 18F serilerinde  ADCON0.1 nolu biti, 16F serilerinde GO/DONE adcon0.2 biti kullanıyor değilmi?. (amacım eksiğinizi bulmak değil hocam acaba kaçırdığım başka bişey mi var onun için belirttim.
hocam şu isis hatası ne demek istedi acaba?

ete

Tespiti doğru soruyu işlemci bazında sormadığn için bende genel anlamda cevaplamıştım. İlgili bitler işlemciden işlemciye değişmektedir. Söz konusu hata için işlemcinin acquistation süresine bakmak gerekir.

Ete

Hattuşa

@ete hocam uzun zamandır bu ADC kesmesi nedir vs diye kafama takmıştım ya şimdi biraz anlamaya başladım. herneyse
şimdi isis hata vermiyor dediğiniz gibi çevrim süresinden kaynaklı sorunmuş ana döngünün başına 20uS luk gecikme koyunca isis hatayı kesti. sayenizde bir konuyu daha az-çok öğrenmiş olduk. tşk ederim.

BASLA:
DelayUS 20
ADCON0.0 =1
DelayUS 20
ADCON0.2 =1
If BaK =1 Then
   BaK =0
   Print At 2,5,Dec AdC," "
   DelayMS 10
   EndIf
GoTo BASLA
   

KeSMe:
Context Save
ADCON0.2 =0
ADCON0.0 =0
PORTC.0 =1
AdC.HighByte =ADRESH
AdC.LowByte =ADRESL

BaK =1
ADIF =0      'adc bayrak temizlendi


PORTC.0 =0
Context Restore

Hattuşa

#8
@ete hocam
bir değişken dizini şu şekilde yazamıyorum.
AdC[x].HighByte =ADRESH
AdC[x].LowByte =ADRESL




bana "invalid cast for this type of variable" hatası veriyor. bunu başka nasıl yazabilirim.

for x=0 to 9
dene.HighByte =ADRESH
dene.LowByte =ADRESL
AdC[x] =dene
next


diye oluyor ama daha farklı nasıl olabilir.

ete

Bildiğim başka yolu yok.
Ete

Powered by EzPortal