16F88 de cisim algılama-yardım

Başlatan emre1512, 22 Ekim 2012, 19:43:53

emre1512

Arkadaşlar PIC16F88 kullanarak sensör cisim gördüğünde LED'i yakmak istiyorum.Şu şekild bir yazılım yaptım ama sanırım sensörü doğru kullanamıyorum.Sensör Sharp GP2Y0A21

LIST P=16F88, R=DEC
 INCLUDE "P16F88.inc"
 __CONFIG _CONFIG1, _XT_OSC & _WDT_OFF & _PWRTE_ON & _BODEN_OFF & _CP_OFF 

		CBLOCK H'20'
        SAYAC1
        SAYAC2
        IS
        BEK
        NUM
        ENDC

		MOVLW B'00000010'
		MOVWF ANSEL
		MOVLW H'07'
       MOVWF CMCON 

		BSF			STATUS,RP0
		MOVLW 		B'11111111'
		MOVWF		TRISA
		MOVLW 		B'00000000'
		MOVWF 		TRISB
		BCF			STATUS,RP0
	
     MOVLW B'00000000' ; LED LER SÖNÜK
     MOVWF PORTB

	TEST_ET  ; BU KISIMDA SENSORUN ÖNÜNDE CISIM VARMI ONU ALGILAMAYA CALISIYORUM AMA BECEREMEDIM
	    BTFSS       PORTA,1 
        GOTO        TEST_ET
	
		MOVLW B'00000101' ; LED YAK
		MOVWF PORTB

	        
		END

Tagli

Sensör analog çıkış veriyor. Bunu BTFSS gibi komutlarla okuyamazsın. ADC modülünü kullanarak dönüşüm yapman ve elde edeceğin sayıya göre davranman gerekir.
Gökçe Tağlıoğlu

emre1512

#2
Bildiğim kadarıyla 16f88 de dahili ADC var.Peki bu dediğinizi nasıl yapabilirim.Örnek bir kod gösterebilirmisiniz acaba.Teşekkürler

Tagli

Aslında datasheet'te oldukça açık olarak anlatılmış. Forumda ararsan da örnek bulabilirsin eminim. Özetlemek gerekirse, Öncelikle birkaç ayar yapman gerekiyor. Hangi pinleri analog olarak kullanacağını seçmelisin ki vermiş olduğun kodda bunu yapmışsın zaten: ANSEL register'ı bu işe yarıyor. Daha sonra dönüşüm clock'unu ayarlaman gerekiyor. Bu ayar PIC'in hızına göçre seçilmeli. Bunun gibi bir iki ayarı daha yaptıktan sonra dönüşüm yapacağın kanalı seçip bir süre beklemeli (kabaca 20 us kadar) ve ADCON0'ın GO/DONE bitini 1 yaparak dönüşümü başlatmalısın. Dönüşüm bitince bu bit kendi kendine 0 olur. O zaman ADRESH ve ADRESL register'larından 10 bitlik sonucu okuyabilirsin.
Gökçe Tağlıoğlu

emre1512

#4
Hocam dediğiniz gibi datasheet'e biraz daha baktım.Birçok yeri daha iyi anladım fakat bir yerde takıldım.Bu dönüşüm clock'unu neye göre ayarlamam gerekiyor.Ben 4MHz'lik bir kristal kullanıyorum.

ADCS<1:0> bitlerini neye göre ayarlamalıyım.Mesela bu bitleri 00 yapınca Fosc/2 oluyor diyor.

Bir de,20 us lik beklemeyi nasıl yapabilirim

Tagli

Datasheet'te yazdığına göre, TAD 1.6 - 6.4 us aralığında mümkün olan en düşük değeri alacak şekilde bölme oranı ayarlanmalı imiş. Tablo 12-1 bu konuda fikir vermiş. Senin kristal 4 MHz olduğundan, bunu içine alacak en küçük değeri seçmen uygun olur. Yani 8'e bölmelisin.

20 us'lik bekleme ADCON0'da kanal seçildikten sonra GO/DONE'ı 1 yapmadan önce olmalı. Bu süreye Denklem 12-1'e bakarak ulaştım. Aslında süre birkaç değişkene bağlı, ama kabaca 20 us alınsa olur bence. Bu bekleme bazı PIC modellerinde eğer ayarlanmışsa otomatik olarak yapılıyor (GO/DONE'ın 1 olması ile), ama gördüğüm kadarıyla PIC16F88'de bu özellik yok, bu sebeple kendin bir bekleme eklemek zorundasın. Herhangi bir bekleme kodu olur, mesela arka arkaya 20 tane nop yazmak gibi (bu çok çirkin görünür elbette). İnternette bu işi yapan hazır kod üreticiler bulabilirsin. Ben zamanında bunu kullanıyordum. Başkaları da vardır mutlaka.
Gökçe Tağlıoğlu

emre1512

Cevabınız için teşekkür ederim.Verdiğiniz linki kullanarak şu şekilde bir kod elde ettim.Kod basit olmasına rağmen pek anlayamdım  :-[

cblock
	d1
	endc

			;19 cycles
	movlw	0x06
	movwf	d1
Delay_0
	decfsz	d1, f
	goto	Delay_0

			;1 cycle
	nop


Son olarak dediğiniz değişikleri uygulayıp birazdan kodumu tekrar buraya yapıştıracağım.Yanlış olduğunu düşündüğünüz kısımları belirtirseniz sevinirm.

Tagli

Kod aslında hiçbir iş yapmayan boş bir döngüden ibaret. Ama öyle yazılmış ki boş dönmesi 20 us sürüyor.
Gökçe Tağlıoğlu

emre1512

#8
Hocam kodumun son hali aşağıdaki şekilde.Birde dönüşüm bittikten sonra ADRESH VE ADRESL registerlarındaki sonuca göre LED yakmam gerekiyor.Mesela ADRESL nin içeriği bell bir sayıdan büyükse LED'ler yansın istiyorum.2 ayrı registerda tutulan sayıyı nasıl başka bir sayıyla karşılaştırabilirim acaba?

LIST P=16F88, R=DEC
 INCLUDE "P16F88.inc"
 __CONFIG _XT_OSC & _WDT_OFF & _PWRTE_ON & _CP_OFF 

		CBLOCK H'20'
        SAYAC1
        SAYAC2
        IS
        BEK
        NUM
	    D1
        ENDC

		BSF		STATUS,RP0
		MOVLW 		B'11111111'
		MOVWF		TRISA
		MOVLW 		B'00000000'
		MOVWF 		TRISB
		BCF		STATUS,RP0

		MOVLW B'00000010' ; ANALOG GIRISLER AYARLANDI
        MOVWF ANSEL
        MOVLW H'07'
        MOVWF CMCON 
 
		BSF ADCON1,6 ; A/D CLOCK BOLUCU DEVRE DISI BIRAKILDI
		MOVLW B'01001001'
		MOVWF ADCON0 ; KANAL SECİLDİ,DONUSUM CLOCK'U AYARLANDI,MODUL ACILDI

		MOVLW	0x06  ;20us BEKLENDI
   	MOVWF	D1
	DELAY
    	DECFSZ	D1, f
    	GOTO	DELAY
	    NOP
		
		BSF ADCON0,2 ; ADCON0'IN GO/DONE BİTİ SET EDILDI

	AD_TEST
		BTFSC ADCON0,2 ; GO/DONE BİTİ 0 İSE DÖNÜSÜM BİTMİS DEMEKTİR
		GOTO AD_TEST

	; BU KISIMDA KARSILATIRMA YAPILACAK
	; KARSILASTIRMANIN SONUCUNA GORE LED'LER YAKILCAK VEYA SÖNÜK KALACAK
		MOVLW B'00000101' ;
		MOVWF PORTB


		END


Kod niye renksiz oldu yav?

Tagli

Ayar bitlerini tek tek kontrol etmedim ama genel mantığı doğru gözüküyor. Gözüme çarpan bir hata, ANSEL ve CMCON atamalarını bank0'dayken yapmış olman. Bunlar da TRIS'ler gibi bank1'de. O kısmı düzeltmen gerekiyor.

Karşılaştırma işi verinin boyutuna, işaretli veya işaretsiz oluşuna ve dizlimine göre (endianness) değişir. Deneyim kazanman açısından bu tür kodları senin düşünüp (veya araştırıp) yazman gerekir, bu sebeple bu konunun ayrıntısına girmeyeceğim (aslında işin içine ondalıklı sayılar girmezse pek de bir ayrıntısı yok, ki o kısmını ben de bilmiyorum zaten). Ancak işi kolay yoldan halletmek istiyorsan ADCON1'in ADFM bitine bakabilirsin. Bu bit 0 iken (ki varsayılan değeri de bu) sonuç sola dayalı oluyor. Bu durumda küçük 2 biti feda ederek, sadece ADRESH'yı kullanabilir ve 8 bit çözünürlüğünde sonuç elde edebilirsin. Yani ADRESL'ye ihtiyacın kalmaz.

Şimdi bir hata daha gözüme çarptı: "A/D CLOCK BOLUCU DEVRE DISI BIRAKILDI" demişsin ama komut bsf kalmış. Onun bcf olması gerekiyor.
Gökçe Tağlıoğlu

emre1512

#10
Teşekkürler dediğiniz değişikleri yapacağım.

Daha birçok hatayla karşılaşacağımdan eminim umarım bu konuya arada bir bakmaya devam edersiniz,zira sizden başka yardım eden olmadı,teşekkürler

mesaj birleştirme:: 24 Ekim 2012, 21:18:38

Hocam yazılımımı aşağıdaki gibi düzelttim.Tahmin ettiğim gibi çalışmıyor :D Kurduğum devreyle ilgili bazı sorunlarımda var.Örneğin 12V/5V regülatör olarak 7805 entegresi kullandım ama entegre el deymeyecek kadar çok ısınıyor.Acaba fazla akımmı çekiyor PIC?Daha önceden bu 7805 entegresini çizgi izleyen robotta sorunsuzca kullanmıştım halbuki

Bu kodum:

LIST P=16F88
 INCLUDE "P16F88.inc"
 __CONFIG _CONFIG1, _XT_OSC & _WDT_OFF & _PWRTE_ON & _CP_OFF 

		CBLOCK H'20'
        SAYAC1
        SAYAC2
        IS
        BEK
        NUM
		D1
        ENDC

		BSF	  STATUS,RP0
		MOVLW B'11111111'
		MOVWF TRISA
		MOVLW B'00000000'
		MOVWF TRISB
		MOVLW B'00000010' 		; ANALOG GIRISLER AYARLANDI
        MOVWF ANSEL
        MOVLW H'07'
        MOVWF CMCON 
		BCF	  STATUS,RP0

	BASLA
		BCF ADCON1,6 			; A/D CLOCK BOLUCU DEVRE DISI BIRAKILDI
		BCF ADCON1,7 			; 8 BİTLİK DEGERI KULLANABİLİRİZ
		MOVLW B'01001001'
		MOVWF ADCON0			; KANAL SECILDI,DONUSUM CLOCK'U AYARLANDI,MODUL ACILDI
	
		MOVLW	0x06  			; 20us BEKLENDI
   		MOVWF	D1
	DELAY
    	DECFSZ	D1, f
    	GOTO	DELAY
	    NOP
		
		BSF ADCON0,2 			; ADCON0'IN GO/DONE BITI SET EDILDI

	AD_TEST
		BTFSC ADCON0,2 			; GO/DONE BITI 0 İSE DONUSUM BITMIS DEMEKTIR
		GOTO AD_TEST

		MOVF ADRESH,0 			; CISIM YAKINMI UZAKMI KONTROLU
		SUBLW B'01111111'
		BTFSS STATUS,0
		GOTO BASLA
		MOVLW B'00000101' 
		MOVWF PORTB

		END


Buda kurduğum devre:


frat

7805'e kaç V veriyorsun acaba? 7805'in de bir çok modeli mevcut. Düşük güçlü modelse fazla ısınabilir.
7805 yerine LM2575 yada 2576 entegrelerini tavsiye edebilirim.
DataCNC ve Robotus Mühendislik Kurucusu // https://www.robotus.net & https://www.datacnc.com

emre1512

7805'un girişine 12V veriyorum.LM2575'i çok fazla övüyorlar.Ama benim anlamadığım bir önceki robot projemde sorunsuz çalışan bir entegre bu sefer neden yanıyor?

Tagli

Devrede kısa devre olabilir. 7805'in çıkışlarını bir kontrol et, kısa devre varsa çıkışta muhtemelen belirgin bir düşüş göreceksin. Ayrıca, 7805'ler piyasada çakması (bazen patates baskı da diyoruz) en çok bulunan entegrelerden. Yani komple bozuk olabilir veya çok kalitesiz olduğu için ısınıyor olabilir.

Bence ilk yapılması gereken, PIC'in basit bir LED yakıp söndürme programını çalıştırıp çalıştıramadığını test etmek olmalı. Böyle bir program çalışmıyorsa zaten sorunu donanımda veya config biti ayarlarında aramak gerekir. ASM ile kod yazmayalı baya oldu, o yüzden config ayarları formatını unutmuşum. Ancak ayarlarda LVP_OFF gibi bir ifade olmayışı dikkatimi çekti. Daha önce bu sebeple sorun yaşandığını forumda birçok kez gördüm (hatta birkaç kez de kendim yaşadım). Sanırım varsayılan olarak açık olan bu seçeneğin kapatılması gerekiyor yoksa RB3 bacağı I/O amaçlı kullanılamadığı gibi bu bacakta oluşacak 5 volt seviyesi (ki açıkta kalan bir bacakta bu durum etraftaki parazitle durup dururken oluşabilir) PIC'i programlama moduna sokacağından çalışmasını engelleyebilir.

Onun dışında programda bir hata göremedim ama bu konuda çok iddialı değilim, çünkü ASM ile kod yazarlen hatalar kolaylıkla gözden kaçabiliyor.
Gökçe Tağlıoğlu

emre1512

PIC'i deneyemedim çünkü deneyebilmek için +5V gerekiyor,bunuda sağlayamıyorum.7805 i tek başına kurup çıkışını ölçebiliyorum,tam +5V veriyor ve hiç ısınmıyor.Ancak PIC'i bağlayınca hemen ısınıyor.Ölçmeye vakit bulamadan bataryayı çıkarmak zorunda kalıyorum,malzemeler yanmasın diye.Bu neden olabilirki?