Haberler:

Eposta uyarılarını yanıtlamayınız ( ! ) https://bit.ly/2J7yi0d

Ana Menü

hi-tech C delay sorunu

Başlatan jackal183, 25 Mart 2011, 17:48:35

jackal183

arkadaşlar merhaba, ben bir program yazmaya çalışıyorum 6 adet servo motor kontrolü ile ilgili. programın akışında alt fonksiyona üç değişken gönderiyorum. 1. hangi servo, 2. hangi yöne(+90,-90), 3. sü açı değeri.
bu fonksiyonda aldığım değişkenleri bazı işlemlere sokarak ne kadar Delay verileceğini hesaplıyorum. DelayUs(değişken) şeklinde yazdığımda bu işlemi gerçekleştirmiyor yani çok farklı ve çok daha uzun(10 kattan daha fazla ) bir delay işlemi gerçekleşiyor. ancak fonksiyona değişken yazmazsam yani DelayUs(150); yazarsam 150 us lik delay yapıyor. acaba diyorum benim hesaplamalarımda mı bir sorun var, bunun için de hesapladığım değeri direk LCD'ye yazdırıyorum hesap doğru. bu neden olabilir. kodları da ekliyorum bakmak isteyen olursa.
#include <htc.h>
#include "delay.h"
#include "lcd.h"


#define Servo0 RD0 // master servo 
#define Servo1 RD1 // joint11
#define Servo2 RD2 // joint2
#define Servo3 RD3 // joint3
#define Servo4 RD4 // tong
#define Servo5 RD5

int i;
int time=0,division=0,difference=0;
int delayTime=0,delayDivision=0, delayDifference=0;


void initialPos(void)
{
	PORTD=0xFF;
	DelayUs(250);DelayUs(250);DelayUs(250);DelayUs(250);
	DelayUs(250);DelayUs(250);
	PORTD=0x00;
	DelayMs(18);
	DelayUs(250);DelayUs(250);
}


void servoExecute(char servo, char direction, char angle)
{
	time=angle*5;
	division=time/250;
	difference=time%250;
	delayTime=500-time;
	delayDivision=delayTime/250;
	delayDifference=delayTime%250;
	Servo0=1;
	DelayUs(250);DelayUs(250);DelayUs(250);DelayUs(250);
	if(direction){
		DelayUs(250);DelayUs(250);
		DelayUs(division*250);DelayUs(difference);
		Servo0=0;
		DelayMs(18);
		DelayUs(delayDivision*250);DelayUs(delayDifference);
	}else{
		Servo0=0;
		DelayUs(division*250);DelayUs(difference);
		DelayMs(18);DelayUs(250);DelayUs(250);
		DelayUs(delayDivision*250);DelayUs(delayDifference);
	}

}
void main(void)
{
	TRISB=0x00;
	TRISD=0x00; 	
	PORTD=0x00; 	
	ADCON1=0x07;		
	TRISC=0x00;
	
	DelayUs(250);DelayUs(250);DelayUs(250);DelayUs(250);
	initialPos();
	DelayUs(250);DelayUs(250);DelayUs(250);DelayUs(250);
	
	lcd_init();

	while(1) 
	{	
		servoExecute(0,1,30);
		
		lcd_gotoxy(1,1);
		veri_yolla(division+48);
		lcd_gotoxy(2,1);
		veri_yolla(difference/100+48);
		veri_yolla((difference%100)/10+48);
		veri_yolla(difference%10+48);

	
	}
	
	
}

eseneren

#define Xtal_FREQ 20MHZ
Bu şekilde bir tanımlama eksikliğinden olabilir..
Seçim yapmak için durum hakkında bilgi sahibi olmak zorunda değilsin, sonucuna hazır olmak için durum hakkında kaygılanırsın.  http://bit.ly/gixfTk

jackal183

şimdiye kadar hiç böyle tanımlama yapmamıştım hep çalışmıştı kodlarım ama deneyeyim

jackal183

bir değişiklik olmadı kardeş

jackal183

cevap verebilecek kimse yok mu arkadaşlar, bu kod için olmasa bile en azından fikir açısından, yapacağım projede açı değerleri sürekli değişken olacak hep farklı değerler gelecek, ben de kodumu buna göre yazmalıyım, ben üstte verdiğim kod gibi birşey düşündüm ama delay fonksiyonlarının çalışmaması baltaladı açıkçası

BenC

DelayUs(Xdeğiken Türü) fonksiyonuna gönderdiğiniz değişkenin cinsi yanlış olabilir.

Diyelimki

void DelayUs(unsigned char Sure )

{
....................
...........
}

Bu fonksiyona gönderme yaparken "unsigned char" tipinde bir değişken ile gönderme yapmanız lazım.

ŞEHİT KANIYLA ALINMIŞ BU GÜZELİM VATANIN TOPRAKLARI KARIŞ KARIŞ SATILIYOR!!  VATAN HAİNİ OLMA!!

iyildirim

Hata nerededir çok da anlayamadım. Servo darbeleri üretme kısmı fazla karışık geldi bana. Hitec kullanmadığımdan DelayUs(250) ler neden tekrarlanıyor, bu fonksiyonun parametre limiti 255le mi sınırlı, çok da anlamlı gelmedi.

İşlemci nedir bilmiyorum ama servo darbeleri üretmek için işlemcinizde varsa CCP modülünü kullanmanızı öneririm. Yoksa da mümkün ise 6 kanal CCP modülü olan bir işlemci kullanmanızı.

Zaten 6 adet servo için sürekli olarak darbeler üretmek ve bunu da delay gibi fonksiyonlarla yapmak 20ms lik döngü süresinin 12ms sini bekleyerek geçirmek anlamına gelir. Ayrıca bu şekilde ki kodda ana döngü içerisinde yapılacak diğer işlemler 20ms lik döngü süresini de etkileyecektir.

CCP modülü kullanılarak sadece darbe süresi değiştiğinde darbe süresini timer değeri cinsinden bir kez set edilmesi yeterli olacaktır.

Eğer CCP modülü yoksa da bir veya iki adet timer kullanarak kesme ile bekleme yapmadan darbeleri yine üretebilirsiniz.

Bunun için örneğin; toplam 8 kesme sonucunda 20ms lik çevrim süresini tamamlamak için  timer'ı 2.5 gibi bir değere set edin.

Kesme içerisinde pini high yapıp aynı veya ikinci bir timer'ı darbe süresine set edin.

Aynı timer kullanılıyorsa ikinci kesme de pini low yapıp (2.5ms - darbe süresini) set edin, ikinci bir timer kullanırsanız buna da gerek olmayacak.

Devam eden kesmelerde diğer pinleri kontrol ederek 6 servoyu sürebilirsiniz. Ana döngünün son iki kesmesi ise 20ms döngü süresini sağlamak için boş geçilmeli..

Darbe süresini hesaplama kısmı da karışık geldi demiştim.
+- açı olarak set etmek için Orta nokta +- darbe süresi yeterli olması gerekli.

darbe_süresi_HIGH = TIMER_1_5MS + (angle* ISTENEN_CÖZÜNÜRLÜKTE_TIMER_CARPANI)
darbe_süresinin_LOW_2msden_kalanı = TIMER_2_MS -  darbe_süresi
yeterli olmalı ..

Kolay gelsin..


jackal183

yapacağım proje biraz geniş çapta bir proje sadece 6 tane servo yok, lcd var, adc var, rgb sensör var, oldukça fazla pin kullanacağım yani. 6 adet
ccp modülü olan bir pic bilmiyorum biraz baktım 18f serisinde var, ama onlar da 20 pinli, bana daha çok pin gerekli, ama yine de önerini dikkate alacağım sadece timer kullanarak da bu gecikme sürelerini ayarlayabileceğimi düşünüyorum

eseneren

-- En başa
#ifndef _XTAL_FREQ
   #define _XTAL_FREQ 20000000
#endif

Bunu ekledıkden sonra delay kutuphanesıne gerek kalmadan
__delay_ms(200);
__delay_us(200);
olarak kullanabilirsin

-- Kullandıgın delay kutuphanesını ıncelersen delay(50) gıbı bır komutla gonderdıgın deger
char olarak ele alınacaktır.500 Yazılsa bıle char tipine cast yapılacaktır.
delayBig yada big delay gıbı bır komut olacak onu kullanabilirsiniz. yada biraz editleyerek
kendi fonksiyonunu yazabilirsin.


Seçim yapmak için durum hakkında bilgi sahibi olmak zorunda değilsin, sonucuna hazır olmak için durum hakkında kaygılanırsın.  http://bit.ly/gixfTk

jackal183

Alıntı yapılan: eseneren - 26 Mart 2011, 12:02:24
-- En başa
#ifndef _XTAL_FREQ
   #define _XTAL_FREQ 20000000
#endif

Bunu ekledıkden sonra delay kutuphanesıne gerek kalmadan
__delay_ms(200);
__delay_us(200);
olarak kullanabilirsin

-- Kullandıgın delay kutuphanesını ıncelersen delay(50) gıbı bır komutla gonderdıgın deger
char olarak ele alınacaktır.500 Yazılsa bıle char tipine cast yapılacaktır.
delayBig yada big delay gıbı bır komut olacak onu kullanabilirsiniz. yada biraz editleyerek
kendi fonksiyonunu yazabilirsin.




dediğiniz gibi kütüphaneyi incelediğimde o deişkenin char olduğunu gördüm, bunun üzerine ben de char olarak tanımlama yaptım ama birşey değişmedi, bu bashettiğiniz kodu da daha sonra deneyeceğim ama bu kod zaten kütüphanenin içinde var birşey değişeceğini sanmıyorum ama yine de teşekkürler denemekten birşey kaybetmem

Erol YILMAZ

Hi-tech in içindeki delay_us fonksiyonları çin malı çalışmayan oyuncak gibi birşey,
Çalışırsa  ne ala, Düzgünlüğünü arama  ;)

Forumda Mihri arkadaşımız bunun için fonksiyonlar yazmıştı, Onlarla başarılı sonuçlar elde edebilirsiniz,
Yada siz yazın....