fonksiyona parametre olarak pin numarasi nasil verebilirim?

Başlatan sigmoid, 06 Temmuz 2010, 10:20:51

sigmoid

butonoku(RB1)
butonoku(RA4)

şeklinde fonksiyonu çağirmak istiyorum. yalniz fonksiyonu tanimlarken pinlerin türünü ne olarak tanimlamaliyim?

teşekkürler.

fatihinanc

C99 da  _Bool diye bir anahtar kelime var. fakat ben hiç kullanmadım. Eğer ram alanından tasarruf edeyim diyorsanız boolean da 1byte yer kaplar. fonksiyona parametre olarak göndermektense

while(pin)
fonksiyon();


şöyle bir kod da aynı işevi görür sanırım.
Kainat dediğimiz kitap, yazıldığı dil ve harfler öğrenilmedikçe anlaşılamaz.  (Galileo Galilei)

serdararikan

hitech manualde bittest,bitset ve bitclear fonksiyoları var bunları kullanabilirsin.

sigmoid

yazmaya çaliştiğim fonksiyon ile parametre olarak verilen butonu 10 kere kontrol ettikten sonra basili kabul etmek. fonksiyon olark yazamadiğimdan şu anki projlerimde hep kopyala yapiştir yapmak zorunda kaliyorum.


JKramer

Alıntı yapılan: abdullaho - 06 Temmuz 2010, 10:20:51
butonoku(RB1)
butonoku(RA4)

şeklinde fonksiyonu çağirmak istiyorum. yalniz fonksiyonu tanimlarken pinlerin türünü ne olarak tanimlamaliyim?

teşekkürler.
Header dosyasında pinler
#bit RA0=5.0

şeklinde mi tanımlanmış? Yani bir pini okurken
if(RA0)

ile mi okuyorsunuz? 8 bit'lik integer şeklinde tanımlarsanız olması gerekiyor.

CLR

Alıntı yapılan: abdullaho - 06 Temmuz 2010, 10:20:51
butonoku(RB1)
butonoku(RA4)

şeklinde fonksiyonu çağirmak istiyorum. yalniz fonksiyonu tanimlarken pinlerin türünü ne olarak tanimlamaliyim?

teşekkürler.

Merhaba

Binbir çeşit yöntemi var, mesela port pinleri için sıralı olarak numara verirsin veya pin numarasını parametre olarak girersin 

u8
butonoku(u8 portnum){
      u8  butondurumu;

      switch(portnum){
           case 0:  if(RB0)    butondurumu|=1;   break;
           case 1:  if(RB1)    butondurumu|=2;   break;
           case 2:  if(RB3)    butondurumu|=4;   break;
           case 3:  if(RA0)    butondurumu|=8;   break;
          ..........
      }
       return butondurumu;
}





Knowledge and Experience are Power

sigmoid

@eemkutay

bu yöntem aklima geldi ama kodu çok şişiririr.

orhanc

i'm doing nothing... Giddy Up  http://www.drorhan.com

CLR

Alıntı yapılan: abdullaho - 06 Temmuz 2010, 15:23:30
@eemkutay

bu yöntem aklima geldi ama kodu çok şişiririr.

@abdullaho

Kodu çok şişirir dediğine göre asm'de biliyorsundur ve  laf olsun diye söylememişsindir muhakkak.  Bende asm'de bildiğim için soruyorum, kodu şişiren kısmını asm ile açıklar mısın? 
Knowledge and Experience are Power

Klein

Pointer kullanarak portu parametre olarak geçebilirsin.  ama pini parametre geçmek okadar kolay olmayabilir.  IAR derleyicide SFR (portlar ve özel alanlar) unsigned char volatile __data13  şeklinde tanımlanıyor. Eğer hi-tech  farklı şekilde tanımlıyor ise o şekilde düzeltmek gerek.
void port_pointer(unsigned char volatile __data13 *source , unsigned char val){
   *source = val;
}

void port_pointer_test(void){
    port_pointer(&p2,165);
}


@eemktay  önerdiğin çözüm kodu gerçeten şişirir.
Çünkü
Portu bu şekilde parametre olarak geçme ihtiyacı şuradan geliyor. Ben fonksiyonu bir kez yazayım,  hangi portu kullanacağımı fonksiyonu çağırırken belirleyeyim. 
Bu durmda:
Benim kullandığım işlemcinin 10 tane portu var. bu da 80 tane pin eder.
düşün ki
bu şekilde çalışacak bir tane  24c02 fonksiyonum , bir tane ds1307 fonksiyonum , ve benzeri birkaç tane foksiyonum olsun.
24c02 için de 1 tane clock , bir tane write , bir tane read , bir tane de ack. fonksiyonum var. ds1307 için de hemen hemen aynı sayıda fonksiyon var.  sadece ikisini bile kullanmak istesem  4x2x10x8 tane case ifadesine ihtiyacım olur.   

Önerdiğin çözüm  belli bir programda yaşadığın küçük bir sorunun çözümü olabilir. ancak  bu tip parametrik bir fonksiyon için çözüm olmaz.

acemi2010

Merhaba
Eğer alt program olarak kullanılmak isteniyorsa dendiği gibi fonksiyon değişkenini unsigned char olarak tanımlamak gerekir ki, bunu denetleyecek case'lerin programı şişirmesine engel olunamaz.
Diğer bir alternatif (bence !...) Header File'da #define'lı bir fonksiyon tanımlamak en uygunu olacaktır.
Örnek verecek olursak Hi-Tech'in kendi Sample dosyasındaki DelayUS(x) fonksiyonunun tanımlandığı gibi, #define butonoku(x) gibi bir fonksiyon tanımlanabilir.
#define	DelayUs(x)	{ unsigned char _dcnt; \
			  _dcnt = (x)/((12MHZ)/(XTAL_FREQ))|1; \
			  while(--_dcnt != 0) \
				  continue; }

Sanırım bunun bir altprogram olmadığını belirtmeme gerek yok.

saygılarımla
timuçin

sigmoid

bit türünde tanimladiğimda fonksiyon parametresi olarak yazamadim. global tanimlamak lazim. dahada kötüsü bit türünü pointer olarak tanimlayip alt programa göndermeme izin vermedi.

istediğimi yapmak için dediğiniz gibi bir define fonksiyonu yazacağim.

SpeedyX

Şöyle birşey yazmıştım, PIC için sadece FIOxPIN ler porta-b-c olacak ve pin numaralarını (1<<No) şeklinde tanımlamak gerekir yada fonksiyon başında shift yaptırırsınız.

unsigned char CheckPin(unsigned char PORT,unsigned int PIN, unsigned int CutterCounter)
{
	unsigned int no=0,yes=0;
	unsigned int res=0;
	while(--CutterCounter)
	{
		switch(PORT)
		{
			case 0 : res = FIO0PIN & PIN; break;
			case 1 : res = FIO1PIN & PIN; break;
			case 2 : res = FIO2PIN & PIN; break;
			case 3 : res = FIO3PIN & PIN; break;
			case 4 : res = FIO4PIN & PIN; break;
		}
		if(res)
			yes++;
		else
			no++;
	}
	return (no<yes)?1:0;
}

Birde bazı derleyiciler 4-5 case den fazla monoton artan case varsa onları goto tablosuna dönüştürüp derliyorlar, bunu da unutmamak lazım.

CLR

Alıntı yapılan: Klein - 06 Temmuz 2010, 17:38:20
Pointer kullanarak portu parametre olarak geçebilirsin.  ama pini parametre geçmek okadar kolay olmayabilir.  IAR derleyicide SFR (portlar ve özel alanlar) unsigned char volatile __data13  şeklinde tanımlanıyor. Eğer hi-tech  farklı şekilde tanımlıyor ise o şekilde düzeltmek gerek.
void port_pointer(unsigned char volatile __data13 *source , unsigned char val){
   *source = val;
}

void port_pointer_test(void){
    port_pointer(&p2,165);
}


@eemktay  önerdiğin çözüm kodu gerçeten şişirir.
Çünkü
Portu bu şekilde parametre olarak geçme ihtiyacı şuradan geliyor. Ben fonksiyonu bir kez yazayım,  hangi portu kullanacağımı fonksiyonu çağırırken belirleyeyim. 
Bu durmda:
Benim kullandığım işlemcinin 10 tane portu var. bu da 80 tane pin eder.
düşün ki
bu şekilde çalışacak bir tane  24c02 fonksiyonum , bir tane ds1307 fonksiyonum , ve benzeri birkaç tane foksiyonum olsun.
24c02 için de 1 tane clock , bir tane write , bir tane read , bir tane de ack. fonksiyonum var. ds1307 için de hemen hemen aynı sayıda fonksiyon var.  sadece ikisini bile kullanmak istesem  4x2x10x8 tane case ifadesine ihtiyacım olur.   

Önerdiğin çözüm  belli bir programda yaşadığın küçük bir sorunun çözümü olabilir. ancak  bu tip parametrik bir fonksiyon için çözüm olmaz.

@Klein,

3-4 port pininden okuma yapacakken, 10porta ve  birden 80 port pinine çıkardınız bunun içinde switch case önermişim bir durum oluşturdunuz.
Port pini pointer olarak atanabilir ama bazı 8 bit ve 16bit işlemcilerde veya daha başka deyişle working registerleri sayısı 1'den fazla olan işlemcilerde yapılıyor.(örnek PIC24/30/33'te) Çünkü bir working register port adresini tutarken diğeri pin numarasını tutabiliyor.  Tek working register olan işlemcilerde ve 32bit işlemcilerde böyle bir durum yok, 32bit olanlarda zaten en az 8bit erişimi var.

PIC16 ve 18de tek working register var dolayısıyla C'de neyle gösterirsen göster bunun için derleyici background'unda C'de switch case mantığı yani asm'de  BTFSS veya BTFSC komutlanı kullanacak. Çünkü pin numarasını tutacak ve üzerinde işlem yapabilecek asm komutu ve registeri yok. C komut oluşturacak değil.

Diyelimki senin dediğin gibi port adresini pointer olarak girse, sonuçta hangi pini okuyacaksa onuda parametre olarak girmesi gerekiyor. Onun için switch case yapacak. Yani yine aynı durum. Asm komutları izin vermiyor C nasıl versin.

Verdiğin örnekte port adresini girmişsin ve porta veri atmışsın , byte işlemi yapmışsın, bit işlemi değil yani çözüm değil.







 

Knowledge and Experience are Power

sigmoid

@SpeedyX
çok sağol. bende senin verdiğin koddaki gibi birşeyler yapmaya çalişiyordum. bana güzel fikir verdin.

@eemktay
fikir için sağol. şu anda ilk olarak buton okumaya çalişsamda Kleanin dediği fonksiyonlarida yazacağim. işte o zaman switch case ile kodun içinden çikamam.

@Klean
sağol. ileride yapmayi düşündüğüm durumlarida açiklayarak derdime derman olmuşsun.

define makrosu yazmaya çaliştim fakat derleme sirasinda hata verdi. define macrosunda herhalde return komutu kullanilmiyor. return komutu kullanmadiğimda derleyebiliyorum.