Picproje Elektronik Sitesi

DERLEYİCİLER => CCS C => Konuyu başlatan: eren.guven - 09 Aralık 2014, 19:57:53

Başlık: İki pic arasında Rs232 ile float veri gönderip alma hakkında yardım!
Gönderen: eren.guven - 09 Aralık 2014, 19:57:53
Merhaba arkadaşlar,

Bu soru hakkında daha önce açılan başlıklar var fakat ben bir sonuç göremedim. Yapan oldu yaptım demiş ve bırakmış örnek kodları paylaşmamış.


Benim sorum şöyle. Sıcaklık nem gibi bir float data bilgisini bir picten  diğer bir pice atıcam. 

printf("%f ", bilgi) komutu ile bilgi float verisini gönderebiliyorum.  Fakat bu bilgiyi alacak komutlar benim bildiğim iki tane char datası için getc() ,  string ifadeler için ise gets(), Bu gönderdiğim datayı nasıl alıp lcd'ye yükleyeceğim. 4-5 gündür uğraşıyorum  bir çözüm bulamadım.
Örnek olarak bilgi=20.3 verisini nasıl bir picten diğer bir pice atabilirim. Yardımcı olursanız çok sevinirim. Saygılar.

Başlık: Ynt: İki pic arasında Rs232 ile float veri gönderip alma hakkında yardım!
Gönderen: ismailhtc - 10 Aralık 2014, 18:23:55
gönderen picten float değerini  integere çevirip göndersen, alıcı devresindende integer değerini alıp floata çevirsen olmaz mı?

mesela 20.3 değerini 10 ile çarp 203 olur. bununu alıcı picte 10'a böl 20.3 elde etmiş olursun.

yani sorunu yanlış anlamadıysam böyle yapılabilir derim.
Başlık: Ynt: İki pic arasında Rs232 ile float veri gönderip alma hakkında yardım!
Gönderen: Salih - 10 Aralık 2014, 19:57:12
Bu konuda forumda çok net bir çözüm olmadığı için kendimin hazırladığı
ve denediği programları aşağıya veriyorum.
Denemek isteyenler için proteus dosyasınıda veriyorum.

Verici devresi.


#Include  <16F877.h>
#Fuses XT
#OPT 1
#Use Delay(clock=8000000)
#use rs232(baud=9600, xmit=PIN_C6,rcv=PIN_C7,errors)

float s1=145.0;
int8 *a1;
int8 x1,x2,x3,x4;

Void Main()
{
   Setup_psp(PSP_DISABLED);
   Setup_spi(SPI_SS_DISABLED);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T1_DISABLED,0,1);   
   Setup_adc_ports(NO_ANALOGS);
   Setup_adc(ADC_OFF);
   Setup_CCP1(CCP_OFF);
   Setup_CCP2(CCP_OFF);   
   Port_B_Pullups(True);   
   Delay_ms(10);
   
      While(True)
      {       
        if (input(Pin_B0))
           {
               s1 = s1 + 1.25;
               a1  = &s1;
               x1 = *a1;a1++;
               x2 = *a1;a1++;
               x3 = *a1;a1++;
               x4 = *a1;
               putc(x1);// Float sayıyı 4 bayta ayırdıktan sonra gönderiyoruz.
               putc(x2);
               putc(x3);
               putc(x4);
               while(input(Pin_B0));
           }             
      }
}


Alıcı devresi


#Include  <16F877.h>
#Fuses XT
#OPT 1
#Use Delay(clock=8000000)
#use rs232(baud=9600, xmit=PIN_C6,rcv=PIN_C7,errors)
#include <Lcd.c>

float s1=0.0;
int8 *a1;
int8 x1,x2,x3,x4;

Void Main()
{
   Setup_psp(PSP_DISABLED);
   Setup_spi(SPI_SS_DISABLED);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T1_DISABLED,0,1);   
   Setup_adc_ports(NO_ANALOGS);
   Setup_adc(ADC_OFF);
   Setup_CCP1(CCP_OFF);
   Setup_CCP2(CCP_OFF);   
   Port_B_Pullups(True);
   Lcd_init();
   Delay_ms(10);
   
      While(True)
      {       
               x1 = getc();
               x2 = getc();
               x3 = getc();
               x4 = getc();
       
                 a1  = &s1;
               *a1 = x1;a1++;
               *a1 = x2;a1++;
               *a1 = x3;a1++;
               *a1 = x4;
                     
         printf(lcd_putc,"\fs1=%.5f",s1);
      }
}


deneme programı

https://dl.dropboxusercontent.com/u/20087162/Pic_Program/Pointerler.pdsprj (https://dl.dropboxusercontent.com/u/20087162/Pic_Program/Pointerler.pdsprj)
Başlık: Ynt: İki pic arasında Rs232 ile float veri gönderip alma hakkında yardım!
Gönderen: eren.guven - 11 Aralık 2014, 16:55:10
Gönderdiğiniz kod çalışmıyor. Link formatını da açıkcası anlayamadım. başka yardımcı olabileceğiniz bir yol var ise çok sevinirim.

Make8 komutuyla bu işlemi yapmaya çalıştım. Örneğin göndermek istediğim sayı 45.8, ama aldığım sayı 1202. Gönderme yöntemi şöyle:

double n=45.8;
int16  a;
int8 b ;
int8 c ;

while(1){
  // if(!input(pin_a0) && input(pin_a1) ){
    putc('R');
    delay_ms(50);
    putc('T');
     delay_ms(50);
     a=10*n ;
     b=make8(a,1);
     c=make8(a,0); 
   
   printf("%u",b);
    delay_ms(50);
   printf("%u",c);

   
   delay_ms(1000);

Başlık: Ynt: İki pic arasında Rs232 ile float veri gönderip alma hakkında yardım!
Gönderen: Gökhan BEKEN - 12 Aralık 2014, 23:24:41
Alıntı yapılan: ismailhtc - 10 Aralık 2014, 18:23:55
gönderen picten float değerini  integere çevirip göndersen, alıcı devresindende integer değerini alıp floata çevirsen olmaz mı?

mesela 20.3 değerini 10 ile çarp 203 olur. bununu alıcı picte 10'a böl 20.3 elde etmiş olursun.

yani sorunu yanlış anlamadıysam böyle yapılabilir derim.
8 bitlik bir değişkene bu yöntem ile maksimum 25,5 değerini yazabilirsiniz, çünkü 255'i aşarsa 0'a dönecektir.
Eğer 30,5 sayısını 10 ile çarparsanız 305 olur, bunu 8 bitlik bir değişkene atarsanız 105 elde edersiniz. Bu hiç istenmeyen bir durumdur.

Yöntemler:
Sayıyı ya string olarak gönderip sonuna \r ekleyin, ya da sayıyı 3 byte halinde gönderin, sayının başına bir paket başlangıcı koyun bu bir özel karakter olsun mesela '~' yani tilda veya '$' yani dolar olsun. 2.byte ise sayının tam kısmı olsun. 3. byte ise virgüllü kısım olsun.
Örneğin 26,8 sayısı göndermek için,
gonderilecek[3]={'$',26,8}
yapın.

Alırken ise $ karakterini kontrol edeceksiniz, bu karakteri gördüğünüz zaman peşinden gelen 2 byte'ın ilk byte'ı tam, ikincisini yazmadan önce virgül yazacaksınız.
Başlık: Ynt: İki pic arasında Rs232 ile float veri gönderip alma hakkında yardım!
Gönderen: musti463 - 13 Aralık 2014, 00:04:16
denemelerini proteus da yapıyorsan. Yapma. Devresini breadboard üzerine kur öyle dene çünkü ISIS de sıkıntı oluyor.
Başlık: Ynt: İki pic arasında Rs232 ile float veri gönderip alma hakkında yardım!
Gönderen: Salih - 13 Aralık 2014, 12:08:48
Boşuna vakit kaybetme. Kendi yazıp denediğim programları gönderdim. Proteus 8.1 ver. çalışan deneme devresinide gönderdim.
Öncelikle protues 8.1 programını kur ve gönderdiğim devreyi çalıştır. Çalıştığını göreceksin.
Başlık: Ynt: İki pic arasında Rs232 ile float veri gönderip alma hakkında yardım!
Gönderen: eren.guven - 13 Aralık 2014, 14:40:00
Alıntı yapılan: meftun - 12 Aralık 2014, 23:24:41
8 bitlik bir değişkene bu yöntem ile maksimum 25,5 değerini yazabilirsiniz, çünkü 255'i aşarsa 0'a dönecektir.
Eğer 30,5 sayısını 10 ile çarparsanız 305 olur, bunu 8 bitlik bir değişkene atarsanız 105 elde edersiniz. Bu hiç istenmeyen bir durumdur.

Yöntemler:
Sayıyı ya string olarak gönderip sonuna \r ekleyin, ya da sayıyı 3 byte halinde gönderin, sayının başına bir paket başlangıcı koyun bu bir özel karakter olsun mesela '~' yani tilda veya '$' yani dolar olsun. 2.byte ise sayının tam kısmı olsun. 3. byte ise virgüllü kısım olsun.
Örneğin 26,8 sayısı göndermek için,
gonderilecek[3]={'$',26,8}
yapın.

Alırken ise $ karakterini kontrol edeceksiniz, bu karakteri gördüğünüz zaman peşinden gelen 2 byte'ın ilk byte'ı tam, ikincisini yazmadan önce virgül yazacaksınız.

Merhaba,

float sayıyı printf ile gönderip string olarak gets komutu olarak almayı denemiştim. printf komutunda \r ile gönderilmesi gerektiğini okumuştum. O kadar çok şey denedim ki bu yöntemi de denemiştim ama olmamıştı. En son okulda hoca string ile kesin alırsın dedi veriyi gönderip enter gelmesini bekler dedi \r'nin oradaki işi enter yani satır başı yapmak. Bende bunun üzerine yoğunlaşıp en basit komutlar üzerinde demeler yaptım.

Veriyi gets(); komutu ile aldım.  Meğersem çok basit bir olaymış rf haberleşme rs232'yi kullanmak. Fakat proteus insanı çıldırtabiliyor.

Rf ile uğraşacaklara benim bazı önerilerim var.En azından sıfırdan bakacaklara. Bilen zaten 10 dakikada yapar.

Yeni başlayacak olan arkadaşlar ilk önce veriyi doğru mu gönderiyoruz onu kontrol etmemiz lazım. "RS232 Seri İletişim Uygulaması" adı altında google'da aratın. Oradan hazır proteus dosyası da olan bir uygulama var. Orada 16f877 vericisine göndereğiniz  komutu yükleyin. Bakalım yüklediğiniz doğru gözükecek mi? Özellikle string olarak almak istiyorsanız  hep alt alta yazması lazım verileri.

Daha sonra baud oranı önemli. Benim devrede 600 ile veri atıyor. 300 veya 9600 yapıyorum çalışmıyor.  Sonra mesela delay_ms(); ile komuta gecikmeler ekledim. Herhalde bazı yerlere o gecikmenin gelmemesi lazım(yada delaydan değil ben  öyle sandım) .Bazı yerlerde de tabiki delay_ms(); gerekli.

En son olarak da ccs-c compiler'ın bir garipliği var.Onuda belirtmek isterim. genelde alıcı ve verici dosyasını aynı aynda açtığımda ve compile ettiğimde üzerinde çalıştığımız C kaynak dosyası değişirken hex dosyası değişmiyor. Yani tarihlere saate bakarak compile edip etmediğimizi proteusta dosyayı pic'e yüklerken kontrol etmekte fayda var. Belki sırf bu yüzden çalışan kodu compiler etmediği için önceleri çalışmadı sanmış olabilirim.

Ben internette herkesin bildiği kodları hazır olan lm35 sensörünü 16f877a'a okuyup rs232 ile 16f628a'a atıp oradan da lcd'ye yazdıran bir örnek yaptım. Çok da güzel çalıştı.Komutları aşağıda paylaşıyorum.

Göndericide;

unsigned long int bilgi; // İşaretsiz 16 bitlik tam sayı tipinde değişken tanımlanıyor
float voltaj,sicaklik; // ondalıklı tipte değişkenler tanıtılıyor
.
.
.
.
while(1){
putc('Y);
    delay_ms(50);
    putc('Z');
    delay_ms(50);
   
    bilgi=read_adc(); // ADC sonucu okunuyor ve bilgi değişkeni
    voltaj=(0.0048828125*bilgi)*1000; // Dijitale çevirme işlemine uğrayan sinyalin mV olarak gerilimi hesaplanıyor
    sicaklik=(voltaj/10); // Her 10mV'ta 1 derece artma
   
    printf( "%f\r",sicaklik);
}

Alıcıda ise ;

int a;
char x[10];
.
.
.
while(1){
   
   if(getc()=='Y'){
      a=getc();
   }
      if(a=='Z'){
         
   gets(x);
   lcd_send_byte(0,0x01);
   printf(lcd_putc,"sicaklik= %s ",x);
   delay_ms(50);
  }

-------------------------------------------------------


Herkese teşekkür ederim arkadaşlar umarım yardımcı olmuştur.

Başlık: Ynt: İki pic arasında Rs232 ile float veri gönderip alma hakkında yardım!
Gönderen: Salih - 13 Aralık 2014, 15:57:34
@eren.guven,
bence kulağını tersten tutmuşsun ve işi uzatmışsın.
Benim yaptığım çözüm daha optimaldır.
Ama yinede sen bilirsin.
Başlık: Ynt: İki pic arasında Rs232 ile float veri gönderip alma hakkında yardım!
Gönderen: eren.guven - 14 Aralık 2014, 18:28:01
Alıntı yapılan: salih - 13 Aralık 2014, 15:57:34
@eren.guven,
bence kulağını tersten tutmuşsun ve işi uzatmışsın.
Benim yaptığım çözüm daha optimaldır.
Ama yinede sen bilirsin.

Hocam ben sizin gönderdiğiniz programı çalıştıramadım. Gönderdiğiniz dosya .pdsprj uzantılı  bunu proteusta açamadım. Kodları alıp kullandım oda çalışmadı gönderilen veri anlamsız oluyor.
Başlık: Ynt: İki pic arasında Rs232 ile float veri gönderip alma hakkında yardım!
Gönderen: Salih - 14 Aralık 2014, 21:36:11
Alıntı yapılan: eren.guven - 14 Aralık 2014, 18:28:01
Hocam ben sizin gönderdiğiniz programı çalıştıramadım. Gönderdiğiniz dosya .pdsprj uzantılı  bunu proteusta açamadım. Kodları alıp kullandım oda çalışmadı gönderilen veri anlamsız oluyor.

Proteus 8.1 versiyonu dosyasıdır. Onun için gerekli versiyonu kurarsan deneyebilirsin. Belki gözünden kaçmıştır.
Alıcı ve verici PIC leri Çalışma frekansı 8 Mhz olarak ayarlıydı.
Başlık: Ynt: İki pic arasında Rs232 ile float veri gönderip alma hakkında yardım!
Gönderen: Gökhan BEKEN - 14 Aralık 2014, 21:40:07
Benim dediğim yöntemi bir çok projemde kullanıyorum hiç sorun yaşamadım. Mesela paket başlangıcı olarak 2 karakter kullanmış olsaydık,
Gönderici 57,4 sayısını göndermek istiyorsa
unsigned char tamKisim=57;
unsigned char ondalikliKisim=4;
SendUart("&~");
SendUart(tamKisim);
SendUart(ondalikliKisim);

alıcı tarafından kesme içerisinde şöyle birşey yazmamız gerekirdi:



unsigned char eskiVeri = 0; //global
unsigned char yeniVeri = 0;
unsigned char tamKisim = 0;
unsigned char ondalikliKisim = 0;
void UartInterrupt(void){ //kesme fonksiyonu
                sp->Read(veri, 0, 1); //gelen 1byte'lık veriyi alıyoruz
                eskiVeri = yeniVeri; //bir önceki veriyi kaydediyoruz.
        yeniVeri = veri[0];
                if (yeniVeri == '~' && eskiVeri == '&')//paket başlangıcı kontrol ediliyor
{
                        unsigned char asilVeri[2];
sp->Read(asilVeri, 0, 2); //paketin içeriği alınıyor

tamKisim = asilVeri[0];
ondalikliKisim = asilVeri[1];

sp->DiscardInBuffer(); //buffer'i temizle
}
}
Başlık: Ynt: İki pic arasında Rs232 ile float veri gönderip alma hakkında yardım!
Gönderen: Salih - 14 Aralık 2014, 21:48:54
@meftun,
benim verdiğim örnek de olduğu gibi float sayıyı baytlarına ayırıp
göndermek daha kolay ve optimal değilmi?
Başlık: Ynt: İki pic arasında Rs232 ile float veri gönderip alma hakkında yardım!
Gönderen: Gökhan BEKEN - 14 Aralık 2014, 22:10:36
@salih hocam zaten aynı yöntem ama ufak farklar var.
Sizin yöntem sağlık çalışmaz çünkü paket başlangıcı olarak ayırtedici birşey kullanmamışsınız. Sürekli sayı gönderdiğinizde sayıların sıralaması karışır.
Bunun dışında bir eksiklik daha var, bu işleri interrupt içerisinde yapmak şart olmasa da gereklidir. Ana fonksiyon içerisinde başka işler yapılacaksa kesme en iyisi.
Başlık: Ynt: İki pic arasında Rs232 ile float veri gönderip alma hakkında yardım!
Gönderen: Salih - 14 Aralık 2014, 22:16:40
Alıntı yapılan: meftun - 14 Aralık 2014, 22:10:36
@salih hocam zaten aynı yöntem ama ufak farklar var.
Sizin yöntem sağlık çalışmaz çünkü paket başlangıcı olarak ayırtedici birşey kullanmamışsınız. Sürekli sayı gönderdiğinizde sayıların sıralaması karışır.
Bunun dışında bir eksiklik daha var, bu işleri interrupt içerisinde yapmak şart olmasa da gereklidir. Ana fonksiyon içerisinde başka işler yapılacaksa kesme en iyisi.

Sana katılıyorum. Bende uygulamalarım da data paketi ve haberleşme kesmesi kullanırım.
Ben sadece float sayıyı baytlarına ayırma ve basit bir deneme devresi ile denemeyi amaçladım.
Başlık: Ynt: İki pic arasında Rs232 ile float veri gönderip alma hakkında yardım!
Gönderen: fatal16 - 20 Aralık 2014, 18:42:55
@meftun senin yaptığın mantıkta yapmaya çalıştım olmadı en son bende şu şekilde yaptım

Verici
      A=A*100;
      data[0]=((long int) A)%256;
      data[1]=((long int) A)/256;
      putc(data[0]);
      putc(data[1]);



Alıcı
   data[0]=getc();
   data[1]=getc();
   A=(data[0]+256*data[1]);


bu şekilde alıcıda istediğim sayıyı alıyorum.
Ancak 100'e böldüğümde virgülden sonraki kısmı atıyor.
senin yazdığın kodu ccs'ye uyarlaman mümkün mü?
Başlık: Ynt: İki pic arasında Rs232 ile float veri gönderip alma hakkında yardım!
Gönderen: Gökhan BEKEN - 21 Aralık 2014, 00:07:20
@fatal16 ben alıcı kısmını c# ta yapıp denedim bir çok projemde. Bu mantık kesme mantığı olduğu için her platformda aynıdır.
Tek değişen kısım burası: sp->Read(veri, 0, 1); //gelen 1byte'lık veriyi alıyoruz
Bu kısım platforma göre değişiklik göterir, gelen en son veriyi alma işini ccs c'ye göre yazın
Şu kısıma gerek yok c# diline özgü: sp->DiscardInBuffer(); //buffer'i temizle
ha bir de şu kısım platforma göre değişir: void UartInterrupt(void) //kesme fonksiyonu


Bunun dışında global değişkenlere dikkat edin, fonksiyonun dışında tanımlanan değişkenleri siz de fonksiyonun dışında tanımlayın.
Yani: eskiVeri,yeniVeri,tamKisim,ondalikliKisim değişkenleri global olacak
Şu değişkenlere 2 byte halinde geliyor ama bunları birleştirip tek bir sayıya çevireceksiniz. LCD'ye string olarak yazacaksanız çevirmenize gerek yok.

tamKisim = asilVeri[0];
ondalikliKisim = asilVeri[1];

Şunu yapmanız yeterli olur
char lcdYaz[16];
sprintf(lcdYaz,"sayi: %d,&d",tamKisim,ondalikliKisim );
edit: sprintf(lcdYaz,"sayi: %d,%d",tamKisim,ondalikliKisim );

Kısaca ccs c'ye uyarlamanız gayet mümkün.
Başlık: Ynt: İki pic arasında Rs232 ile float veri gönderip alma hakkında yardım!
Gönderen: fatal16 - 22 Aralık 2014, 14:04:23
herkese tesekkurler

gerbayın yaptıgı mantıkla yaptım çalıştı bu sefer :)

Başlık: Ynt: İki pic arasında Rs232 ile float veri gönderip alma hakkında yardım!
Gönderen: agent54 - 28 Şubat 2017, 23:10:46
Arkadaşlar hepinizin yarışlarını okudum lakin örneğin bir portundan gelen 8 bitlik veriyi rs232 den başka bir pic e gönderip onuda d portuna bağlı olan ledleri yakacağım yani 8 bit input 8 bit output iki tarafta da aynısı olacak ve karşılıklı uzak io yapmak istiyorum ama bir türlü input_b(x) alıp aktaramadim. Birde transreceiver olarak kullanmak için farklı bir algoritma kullanmak gerekirmi