değişkeni farklı pinlerle kontrol etme?

Başlatan omereliusuk, 22 Kasım 2011, 01:49:53

omereliusuk

konu başlığının net olmadığının farkındayım. çözdüm ama;

short a,b,c,d,e,f,g,h;
int8 kontrol;
a=input(pin_c0);b=input(pin_c1);c=input(pin_e0);d=input(pin_e1);e=input(pin_e2);f=0;g=0;h=0;
kontrol=((A<<7)|(b<<6)|(c<<5)|(d<<4)|(e<<3)|(f<<2)|(g<<1)|h);

kontrol=((input(pin_c0)<<7)|(input(pin_c1)<<6)|(input(pin_e0)<<5)|(input(pin_e1)<<4)|(input(pin_e2)<<3)|(0<<2)|(0<<1)|0);
printf(lcd_putc,"  %3d",kontrol);

bunun daha kolay bir yöntemi var mı? ki mutlaka vardır. amaç öğrenmek.

JKramer

Aşağıdaki gibi bir makro hem yazım kolaylığı sağlar hem de üretilen kod miktarını azaltır:
#include <16F877.H> 
 #fuses XT, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP 
 #use delay(clock = 4000000) 
 #use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS) 

 // This macro reads the value of the following 
 // pins and packs the result into a single byte. 
 // RA0,RA1,RA4,RB2,RB5,RB7,RC0,RC5 

 #define read_spare_bits(x) \ 
 x = 0; \                  
 if(input(PIN_A0)) bit_set(x, 0); \ 
 if(input(PIN_A1)) bit_set(x, 1); \ 
 if(input(PIN_A4)) bit_set(x, 2); \ 
 if(input(PIN_B2)) bit_set(x, 3); \ 
 if(input(PIN_B5)) bit_set(x, 4); \ 
 if(input(PIN_B7)) bit_set(x, 5); \ 
 if(input(PIN_C0)) bit_set(x, 6); \ 
 if(input(PIN_C5)) bit_set(x, 7); 


 //================================== 
 void main() 
 { 
 int8 result; 

 while(1) 
   { 
    // Read the value of the spare bits and put 
    // it into the 'result' variable. 
    read_spare_bits(result); 

    printf("Result = %X \n\r", result); 

    delay_ms(500); 
   } 

 }


http://www.ccsinfo.com/forum/viewtopic.php?t=18949

Sizin örneğinizdeki gibi ilk üç bit sürekli sıfır olacaksa makroyu şöyle kısaltabilirsiniz:
#define read_spare_bits(x) \
	x = 0; \
	if(input(PIN_E2)) bit_set(x, 3); \
	if(input(PIN_E1)) bit_set(x, 4); \
	if(input(PIN_E0)) bit_set(x, 5); \
	if(input(PIN_C1)) bit_set(x, 6); \
	if(input(PIN_C0)) bit_set(x, 7);


Bu şekilde üretilen kod:
.................... 		read_spare_bits(kontrol); 
0093:  CLRF   kontrol
0094:  BTFSC  PORTE.2
0095:  BSF    20.3
0096:  BTFSC  PORTE.1
0097:  BSF    20.4
0098:  BTFSC  PORTE.0
0099:  BSF    20.5
009A:  BTFSC  PORTC.1
009B:  BSF    20.6
009C:  BTFSC  PORTC.0
009D:  BSF    20.7


Sizin ürettiğiniz kod ise şöyle:
....................    	kontrol=((input(pin_c0)<<7)|(input(pin_c1)<<6)|(input(pin_e0)<<5)|(input(pin_e1)<<4)|(input(pin_e2)<<3)|(0<<2)|(0<<1)|0); 
0062:  MOVLW  00
0063:  BTFSC  PORTC.0
0064:  MOVLW  01
0065:  MOVWF  @77
0066:  CLRF   @@21
0067:  BTFSC  @77.0
0068:  BSF    21.7
0069:  MOVLW  00
006A:  BTFSC  PORTC.1
006B:  MOVLW  01
006C:  MOVWF  @77
006D:  SWAPF  @77,F
006E:  RLF    @77,F
006F:  RLF    @77,F
0070:  MOVLW  C0
0071:  ANDWF  @77,F
0072:  MOVF   @77,W
0073:  IORWF  @@21,F
0074:  MOVLW  00
0075:  BTFSC  PORTE.0
0076:  MOVLW  01
0077:  MOVWF  @77
0078:  SWAPF  @77,F
0079:  RLF    @77,F
007A:  MOVLW  E0
007B:  ANDWF  @77,F
007C:  MOVF   @77,W
007D:  IORWF  @@21,F
007E:  MOVLW  00
007F:  BTFSC  PORTE.1
0080:  MOVLW  01
0081:  MOVWF  @77
0082:  SWAPF  @77,F
0083:  MOVLW  F0
0084:  ANDWF  @77,F
0085:  MOVF   @77,W
0086:  IORWF  @@21,F
0087:  MOVLW  00
0088:  BTFSC  PORTE.2
0089:  MOVLW  01
008A:  MOVWF  @77
008B:  RLF    @77,F
008C:  RLF    @77,F
008D:  RLF    @77,F
008E:  MOVLW  F8
008F:  ANDWF  @77,F
0090:  MOVF   @77,W
0091:  IORWF  @@21,W
0092:  MOVWF  kontrol

omereliusuk

#2
int kontrol; 
int kontrol; 
 if(input(PIN_c0)) {bit_set(kontrol, 0);}else {bit_clear(kontrol, 0);} \ 
 if(input(PIN_c1)) {bit_set(kontrol, 1);}else {bit_clear(kontrol, 1);} \ 
 if(input(PIN_e0)) {bit_set(kontrol, 2);}else {bit_clear(kontrol, 2);} \ 
 if(input(PIN_e1)) {bit_set(kontrol, 3);}else {bit_clear(kontrol, 3);} \ 
 if(input(PIN_e2)) {bit_set(kontrol, 4);}else {bit_clear(kontrol, 4);} \ 
 bit_clear(kontrol,5);bit_clear(kontrol,6);bit_clear(kontrol,7);
 
hocam sanki sizin yazdığınız kodlara bunları da eklemek gerekiyor gibi. çünkü değerler bir kere 1 olduğu zaman tekrar sıfıra dönme gibi bir durum yok gibi geliyor. 
bir de şu ürettiğim kodları nerede görebilirim.

JKramer

Ben sizin durumunuzda ilk üç bit her zaman sıfır olacak diye anladığım için o satırları kaldırmıştım. Eğer başka pin'lerden okuyacaksanız tabii ki eklemek gerekiyor.

Üretilen kodları .lst uzantılı dosyadan görebilirsiniz.

omereliusuk

#4
int kontrol;
(input(PIN_c0))?(bit_set(kontrol, 0)):(bit_clear(kontrol, 0));//10 kod üretiyor.
 if(input(PIN_c1)) {bit_set(kontrol, 1);}                                //5 kod üretiyor. else de 5 kod üretiyor. toplam yine 10 kod üretiyor.
      else {bit_clear(kontrol, 1);} \
 if(input(PIN_e0)) bit_set(kontrol, 2);                                    //5 kod üretiyor. değili de 5 kod üretiyor. toplam yine 10 kod üretiyor.
   if(!input(PIN_e0)) bit_clear(kontrol, 2); \
 if(input(PIN_e1)) bit_set(kontrol, 3);
   if(!input(PIN_e1)) bit_clear(kontrol, 3); \
 if(input(PIN_e2)) bit_set(kontrol, 4);
   if(!input(PIN_e2))bit_clear(kontrol, 4); \
 bit_clear(kontrol,5);bit_clear(kontrol,6);bit_clear(kontrol,7);
imlec(4,1);     printf(lcd_putc,"  %3d",kontrol);

hangisini yazarsan yaz 8 pin kontrol ediyorsan bu tür kodlarla kompiler  toplamda 80 satır üretiyor. benim en başta yazdığımda da 90 satır üretiyor.
en azından 10 satır kâra geçtim.
bu sizin yazdığınız kod ve en kısa olanı. acemilik...:))

SiVRiSiNEK

#include <16F877.H> 
#fuses XT, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP 
#use delay(clock = 4000000) 

#byte    KONTROL  = 0x20
#bit     KONTROL0 = KONTROL.0
#bit     KONTROL1 = KONTROL.1
#bit     KONTROL2 = KONTROL.2
#bit     KONTROL3 = KONTROL.3
#bit     KONTROL4 = KONTROL.4
#bit     KONTROL5 = KONTROL.5
#bit     KONTROL6 = KONTROL.6
#bit     KONTROL7 = KONTROL.7


// Ana Program Bloğu ///////////////////////////////////////////////////////////
void main()
{
  KONTROL0 = input(PIN_C0);
  KONTROL1 = input(PIN_C1);
  KONTROL2 = input(PIN_E0);
  KONTROL3 = input(PIN_E1);
  KONTROL4 = input(PIN_E2);
  KONTROL5 = 0;
  KONTROL6 = 0;
  KONTROL7 = 0;
}


ben olsam böyle yapardım, alışkanlık meselesi :)

omereliusuk

bu da sanki biraz proton'u andırıyor. üstelik daha az kod üretiyor.

JKramer

Makro şeklinde yazacaksınız, en başta değişkeni sıfırladığınız için giriş sıfırsa atlayacaksınız. Boşu boşuna tekrar sıfır yazmaya gerek yok. 80 satır da değil 11 satır üretiyor, ilk gönderdiğim mesajı inceleyin.

omereliusuk

#8
@jKramer
evet haklısınız. dikkat etmedim ama aynı şeyleri ben yazıyorum 80 satır kod üretiyor. siz yazıyorsunuz 11 satır. bu makroya(veya herhangi bir makro bak bu makrodur makro böyle yazılır şeklinde anlamak için) çok basit bir örnek verirseniz ben anlamadım.
0247:  CLRF   24
....................    if(input(PIN_c0)) {bit_set(kontrol, 0); 
0248:  BSF    21.0
0249:  MOVF   21,W
024A:  BSF    03.5
024B:  MOVWF  07
024C:  BCF    03.5
024D:  BTFSS  07.0
024E:  GOTO   279
024F:  BSF    24.1
....................    if(input(PIN_c1)) bit_set(kontrol, 1); 
0250:  BSF    21.1
0251:  MOVF   21,W
0252:  BSF    03.5
0253:  MOVWF  07
0254:  BCF    03.5
0255:  BTFSC  07.1
0256:  BSF    24.1

........... gidiyor. ben de olan bu 7*8=56 kod.
sizde olan
0093:  CLRF   kontrol
0094:  BTFSC  PORTE.2
0095:  BSF    20.3
0096:  BTFSC  PORTE.1
0097:  BSF    20.4
0098:  BTFSC  PORTE.0
0099:  BSF    20.5
009A:  BTFSC  PORTC.1
009B:  BSF    20.6
009C:  BTFSC  PORTC.0
009D:  BSF    20.7
11 kod

JKramer

#include "16F887.h"

#fuses INTRC_IO,NOWDT,PUT,NOMCLR,PROTECT,CPD,BROWNOUT,NOIESO,NOFCMEN,NOLVP,NODEBUG,NOWRT,BORV21

#use delay(clock=4000000)

#use fast_io(a)
#use fast_io(b)
#use fast_io(c)
#use fast_io(d)
#use fast_io(e)

#define read_spare_bits(x) \
	x = 0; \
	if(input(PIN_E2)) bit_set(x, 3); \
	if(input(PIN_E1)) bit_set(x, 4); \
	if(input(PIN_E0)) bit_set(x, 5); \
	if(input(PIN_C1)) bit_set(x, 6); \
	if(input(PIN_C0)) bit_set(x, 7)

unsigned int8 kontrol=0;

void init();

void main()
{
   init();


   for(;;)
   {
   	read_spare_bits(kontrol);
   }
}


Normalde yaptığınız #define tanımlamasıyla aynı şekilde yapıyorsunuz. Mesela:
#define LAMBA_YAK output_high(PIN_D5)


Kodunuzda LAMBA_YAK olan her yere output_high(PIN_D5) yazılmış gibi işlem görecek. Satır sonlarındaki \ işareti, alt satırdan devam edildiğini gösteriyor. İsterseniz onları kullanmayıp tek satırda da yazabilirsiniz ama okunabilirlik kaybolur.

Bir de bunu illaki makro şeklinde yazmak zorunda değilsiniz, aşağıdaki gibi ana döngüde de yazabilirsiniz:

void main()
{
   init();


   for(;;)
   {
   	kontrol = 0;
		if(input(PIN_E2)) bit_set(kontrol, 3);
		if(input(PIN_E1)) bit_set(kontrol, 4);
		if(input(PIN_E0)) bit_set(kontrol, 5);
		if(input(PIN_C1)) bit_set(kontrol, 6);
		if(input(PIN_C0)) bit_set(kontrol, 7);
//   	read_spare_bits(kontrol);
   }
}


Tabii ki böyle yaparsanız, başka port'ların başka pin'leri için her seferinde kopyala-yapıştır-değiştir yapmanız gerekir. Öteki türlü read_spare_bits(değişken) ile her yerde kullanılabilir hale gelir.

omereliusuk

#10
#define read_spare_bits(x) \
adlı bir fonksiyon mu var yoksa
atıyorum bunların yerine
#define bitleri_yonlendir(x) \
Yazsak da bu işlem olur muydu?

cevaba göre yeni bir soru veya tamam diyeceğim. bu serdar çicek'in kitabı yeterli değil gibi geliyor bana ;
özellikle tavsiye edebileceğiniz bir kitap varsa (satın alabileceğim elle tutulur, gözle görülür) çok makbule geçer.

JKramer

İstediğiniz adı verebilirsiniz :). Kitap konusunda bilgim yok maalesef.

omereliusuk

çok teşekkürler.
en kısa yöntem sizin dediğniz gibi makro...