Picproje Elektronik Sitesi

DERLEYİCİLER => CCS C => Konuyu başlatan: OnderGrmz - 01 Aralık 2014, 16:01:53

Başlık: Spi ile PIC'ler Arası Haberleşmede Sorun
Gönderen: OnderGrmz - 01 Aralık 2014, 16:01:53
Merhabalar;
2 tane PIC'i Spi üzerinden haberleştirip bilgi alış verişi yapmak istiyorum. Bu konuda birkaç sorum olacaktı.
İlk olarak PIC'leri kendi aralarında haberleştirip gönderilen bilgi alındıysa alıcı tarafında led yakmayı düşündüm. Ama Spi Debugger'dan baktığımda bilginin gönderildiğini ama led'in yanmadığını gördüm. Sonra bunu teyit etmek için görsel arayüz elemanı olarak Virtual terminal ekledim. Burada şunu anladım aşağıda Slave için verdiğim koddaki şu satırlar yapmak istediğim işi görmüyor.

if(okunan = 0x05)
        {       
       
       output_high(pin_b6);
       delay_ms(250);
       output_low(pin_b6);
       delay_ms(250);
       spi_write(bilgi);        // Belirtilen adrese yazdırılacak veri gönderiliyor
       delay_ms(5);            // Gecikme veriliyor
     
     }

Açıkçası if döngüsünün içinde hexadesimal bir sayı kullanılır mı bilmiyorum. Ama yukarıdaki kodu yazınca bilgi gelse dahi bu satırı yazınca if deyiminin içine girmiyor.

Master
/******************************************************
PIC8F4680 ile Donanımsal SPI İletişimi Uygulaması
*******************************************************/

#include <18f4680.h>     // Kullanılacak denetleyicinin başlık dosyası tanıtılıyor.
#fuses HS,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,NOPUT,NOWRT,NODEBUG,NOCPD // Denetleyici konfigürasyon ayarları
#use delay(clock=20000000)   // Gecikme fonksiyonu için kullanılan osilatör frekansı belirtiliyor



#define cs PIN_C2    // CS ifadesi PIN_C2 pini yerine atanıyor

int8 okuma_istek=0x05,okunan_deger;  // int8 tipinde değişkenler tanımlanıyor



#int_ssp // SPI iletişiminde yazma veya okuma yapıldığında meydana gelen kesme
void SPI_kesmesi()
{
   output_high(pin_b7); // RB7'ya bağlı LED yansın
   delay_ms(100);       // Gecikme veriliyor
   output_low(pin_b7);  // RB7'ya bağlı LED sönsün
   
}


/******************* ANA PROGRAM FONKSİYONU *************************/
void main ()
{
   setup_psp(PSP_DISABLED);        // PSP birimi devre dışı
   setup_timer_1(T1_DISABLED);     // T1 zamanlayıcısı devre dışı
   setup_timer_2(T2_DISABLED,0,1); // T2 zamanlayıcısı devre dışı
   setup_adc_ports(NO_ANALOGS);    // ANALOG giriş yok
   setup_adc(ADC_OFF);             // ADC birimi devre dışı
   setup_CCP1(CCP_OFF);            // CCP1 birimi devre dışı
   setup_CCP2(CCP_OFF);            // CCP2 birimi devre dışı
   
   
   setup_spi(spi_master| spi_L_to_H | spi_clk_div_4);  // SPI iletişim ayarları belirtiliyor
   
   enable_interrupts(int_ssp);   // SPI kesmesi aktif yapılıyor
   enable_interrupts(GLOBAL);    // Aktif edilen tüm kesmelere izin ver 

 
   output_high(cs); // Harici EEPROM CS ucu lojik-1 yapılıyor

   while(1) // Sonsuz Döngü
   {
   
     if(input(pin_b5)==1)
     { 
         while(input(pin_b5));               
         output_low(cs);         // Entegre seçiliyor
         spi_write(okuma_istek);
         delay_ms(5);
         okunan_deger=spi_read();
         delay_ms(5);
         output_high(cs);
         
     }   
      if(okunan_deger==0x10)
         {
            output_high(pin_b6);
            delay_ms(250);
            output_low(pin_b6);
            delay_ms(50);         
         }   
  }
     
 
}



Slave
/******************************************************
PIC8F4680 ile Donanımsal SPI İletişimi Uygulaması
*******************************************************/

#include <18f4680.h>     // Kullanılacak denetleyicinin başlık dosyası tanıtılıyor.
#fuses XT,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,NOPUT,NOWRT,NODEBUG,NOCPD // Denetleyici konfigürasyon ayarları
#use delay(clock=4000000)   // Gecikme fonksiyonu için kullanılan osilatör frekansı belirtiliyor

#use rs232 (baud=9600, xmit=pin_C6, rcv=pin_C7, parity=N, stop=1) // RS232 iletişim ayarları belirtiliyor
  // Dikkat: Nedense Rs232 iletişiminde #use delay(clock=20000000) ' de sıkıntı çıkıyor !!!
  // Yazdırılmak istenen değerler ekrana gelmiyor.
#include <input.c>   // input.c dosyası programa ekleniyor
#include <stdlib.h>  // stdlib.h dosyası programa ekleniyor

#define cs PIN_C2    // CS ifadesi PIN_C2 pini yerine atanıyor

int8 bilgi=0x10,okunan;  // int8 tipinde değişkenler tanımlanıyor
char islem;


#int_ssp // SPI iletişiminde yazma veya okuma yapıldığında meydana gelen kesme
void SPI_kesmesi()
{
  okunan=spi_read();
  output_high(pin_b7); // RB7'ya bağlı LED yansın
   delay_ms(100);       // Gecikme veriliyor
   output_low(pin_b7);  // RB7'ya bağlı LED sönsün
   
}


/******************* ANA PROGRAM FONKSİYONU *************************/
void main ()
{
   setup_psp(PSP_DISABLED);        // PSP birimi devre dışı
   setup_timer_1(T1_DISABLED);     // T1 zamanlayıcısı devre dışı
   setup_timer_2(T2_DISABLED,0,1); // T2 zamanlayıcısı devre dışı
   setup_adc_ports(NO_ANALOGS);    // ANALOG giriş yok
   setup_adc(ADC_OFF);             // ADC birimi devre dışı
   setup_CCP1(CCP_OFF);            // CCP1 birimi devre dışı
   setup_CCP2(CCP_OFF);            // CCP2 birimi devre dışı
   

   
   
   
   setup_spi(spi_slave| spi_L_to_H | spi_ss_disabled);  // SPI iletişim ayarları belirtiliyor
   
   enable_interrupts(int_ssp);   // SPI kesmesi aktif yapılıyor
   enable_interrupts(GLOBAL);    // Aktif edilen tüm kesmelere izin ver 

 

 
   while(1) // Sonsuz Döngü
   { 
       if(spi_data_is_in()==1)// Bilgi gelip gelmediği kontrol ediliyor !!!
       {
       printf("\n\r\Bilgi alindi !!!");
       printf("\n\r\Alinan Deger=0x%02X",okunan );
       if(okunan = 0x05)
        {       
       
       output_high(pin_b6);
       delay_ms(250);
       output_low(pin_b6);
       delay_ms(250);
       spi_write(bilgi);        // Belirtilen adrese yazdırılacak veri gönderiliyor
       delay_ms(5);            // Gecikme veriliyor
     
     }
       
       }
     

       
       
             

 
      }
     
 
   }

Birde devrede RB5 butonuna basılınca devreyi çalıştırdığımda 0x2F bilgisi ortaya çıkıyor. Bunun ne olduğunu anlayamadım. Ayrıca Butona 2-3 kez basınca Virtual Terminale bilgi alındı verisi geliyor.
[IMG]http://i62.tinypic.com/2iagc4x.png[/img]
Yardımcı olursanız sevinirim.
Saygılarımla ...
Başlık: Ynt: Spi ile PIC'ler Arası Haberleşmede Sorun
Gönderen: Salih - 01 Aralık 2014, 19:51:40
Master programında da slave de olduğu gibi okuma işlemini spi kesmesinde niye yapmadın?

okunan=spi_read();
Başlık: Ynt: Spi ile PIC'ler Arası Haberleşmede Sorun
Gönderen: OnderGrmz - 01 Aralık 2014, 20:00:59
Alıntı yapılan: salih - 01 Aralık 2014, 19:51:40
Master programında da slave de olduğu gibi okuma işlemini spi kesmesinde niye yapmadın?

okunan=spi_read();

Hocam sizin söylediğiniz gibi yapınca da değişen bir şey olmadı. Atladığım bir durum var sanırım.
Slave'de
setup_spi(spi_slave| spi_L_to_H | spi_ss_disabled);
bu kod satırını kullanınca Slave select veya Chip slect ( SS/CS ) pinini devre dışı bırakıyoruz. Peki Master'dan çıkan CS pinini bu koşullar altında nereye bağlamamız gerekiyor ?
Ben bunu Slave'de PIN_C2 üzerine bağladım. Ama programı yazarken hiç kullanmadım bu pini.

Ayrıca Slave denetleyiciden Master'a bilgi göndermek istediğimizde clock sinyali nasıl oluşacak? Onu ayrıca tanımlamak gerekiyor mu?
Başlık: Ynt: Spi ile PIC'ler Arası Haberleşmede Sorun
Gönderen: Pyrodigy - 01 Aralık 2014, 21:43:01
SPI haberleşmede master ve slave aynı clock 'u paylaşır ve gönderilen ve alınan bilgi aynı komut saykı ile yapılır. Yani spi bilgi gönderirken işlenen sürede sen alım da yapmış alıyorsun. SPI haberleşmesi hakkında daha fazla kaynak döküman ve kaynak kod incelemeni öneririm.
Örnek kodlarında ( setup kısmında hata yapmadığını ve benim c bilmediğimi farz edersek ) 

spi_write(TX_bilgi);
// Gecikme YOK !!
RX_bilgi = spi_oku();

Sadece Gönderim yapmak istediğin ve Alım bilgisine ihtiyacın olmasa veya Sadece alım yaptığın ve Gönderim bilgisine ihtiyacın olmadığı durumlarda bile aynı formülü kullanmak zorundasın.
Başlık: Ynt: Spi ile PIC'ler Arası Haberleşmede Sorun
Gönderen: vitruvius - 01 Aralık 2014, 22:38:59
Alıntı yapılan: OnderGrmz - 01 Aralık 2014, 16:01:53
...Burada şunu anladım aşağıda Slave için verdiğim koddaki şu satırlar yapmak istediğim işi görmüyor.

if(okunan = 0x05)
{
     ...
}


Şurası gözden kaçmış sanırım.

if(okunan == 0x05)

olmalı.
Başlık: Ynt: Spi ile PIC'ler Arası Haberleşmede Sorun
Gönderen: Pyrodigy - 01 Aralık 2014, 22:58:48
Dandik c bilgim ile spi bilgi akışını anlatmaya çalışmak istersem şöyle bir kod çıkar, bilmem c ci hocalar ne der bu işe ?

Master Yazmak için

spi_write(TX_bilgi);
RX_dummy_data=spi_read();


Slave Okumak için

spi_write(TX_dummy_data);
RX_bilgi=spi_read();
Başlık: Ynt: Spi ile PIC'ler Arası Haberleşmede Sorun
Gönderen: OnderGrmz - 01 Aralık 2014, 23:23:31
Merhabalar;
Alıntı yapılan: vitruvius - 01 Aralık 2014, 22:38:59
Şurası gözden kaçmış sanırım.
if(okunan == 0x05)
Kodu yukarıdaki şekilde değiştirdim. Master'dan gönderdiğim bilgiyi Slave'den alabildim ve Slave bilgiyi aldığında
if(okunan == 0x05)
        {     
           spi_write(bilgi);   
        }

satırıyla bilgiyi aldığına dair mesajı Master'a gönderdi. Fakat bunu yaparken her butona bastığımda göndermiyor. Bazen Master'dan gönderdiğim bilgi Slave'den Master'a tekrar gönderiliyor. Yani kısacası ben her butona bastığımda Slave bilgiyi aldım mesajı göndermesi gerekirken 2 kere butona bastığımda bilgi alındı mesajı gönderiyor.
kodların düzenlenmiş hali ve simülasyon görüntüsü aşağıdadır.

Master:

#include <18f4680.h>     // Kullanılacak denetleyicinin başlık dosyası tanıtılıyor.
#fuses HS,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,NOPUT,NOWRT,NODEBUG,NOCPD // Denetleyici konfigürasyon ayarları
#use delay(clock=20000000)   // Gecikme fonksiyonu için kullanılan osilatör frekansı belirtiliyor
#define cs PIN_C2    // CS ifadesi PIN_C2 pini yerine atanıyor
int8 okuma_istek=0x05,okunan_deger;  // int8 tipinde değişkenler tanımlanıyor

#int_ssp // SPI iletişiminde yazma veya okuma yapıldığında meydana gelen kesme
void SPI_kesmesi()

}

/******************* ANA PROGRAM FONKSİYONU *************************/
void main ()
{
   setup_psp(PSP_DISABLED);        // PSP birimi devre dışı
   setup_timer_1(T1_DISABLED);     // T1 zamanlayıcısı devre dışı
   setup_timer_2(T2_DISABLED,0,1); // T2 zamanlayıcısı devre dışı
   setup_adc_ports(NO_ANALOGS);    // ANALOG giriş yok
   setup_adc(ADC_OFF);             // ADC birimi devre dışı
   setup_CCP1(CCP_OFF);            // CCP1 birimi devre dışı
   setup_CCP2(CCP_OFF);            // CCP2 birimi devre dışı
   
   setup_spi(spi_master| spi_L_to_H | spi_clk_div_4);  // SPI iletişim ayarları belirtiliyor
   
   enable_interrupts(int_ssp);   // SPI kesmesi aktif yapılıyor
   enable_interrupts(GLOBAL);    // Aktif edilen tüm kesmelere izin ver 
   output_high(cs); // Harici EEPROM CS ucu lojik-1 yapılıyor

   while(1) // Sonsuz Döngü
   {
   
     if(input(pin_b5)==1)
     { 
         while(input(pin_b5));               
         output_low(cs); // Entegre seçiliyor
         spi_write(okuma_istek);
         okunan_deger=spi_read();         
         output_high(cs);   
     }       
  } 
}


Slave:

#include <18f4680.h>     // Kullanılacak denetleyicinin başlık dosyası tanıtılıyor.
#fuses XT,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,NOPUT,NOWRT,NODEBUG,NOCPD // Denetleyici konfigürasyon ayarları
#use delay(clock=4000000)   // Gecikme fonksiyonu için kullanılan osilatör frekansı belirtiliyor

#use rs232 (baud=9600, xmit=pin_C6, rcv=pin_C7, parity=N, stop=1)

#include <input.c>   // input.c dosyası programa ekleniyor
#include <stdlib.h>  // stdlib.h dosyası programa ekleniyor
#define cs PIN_C2    // CS ifadesi PIN_C2 pini yerine atanıyor

int8 bilgi=0x10,okunan;  // int8 tipinde değişkenler tanımlanıyor
char islem;

#int_ssp // SPI iletişiminde yazma veya okuma yapıldığında meydana gelen kesme
void SPI_kesmesi()
{     
       okunan=spi_read();
       if(okunan == 0x05)
        {     
            spi_write(bilgi);        // Belirtilen adrese yazdırılacak veri gönderiliyor   
          }
}

/******************* ANA PROGRAM FONKSİYONU *************************/
void main ()
{
   setup_psp(PSP_DISABLED);        // PSP birimi devre dışı
   setup_timer_1(T1_DISABLED);     // T1 zamanlayıcısı devre dışı
   setup_timer_2(T2_DISABLED,0,1); // T2 zamanlayıcısı devre dışı
   setup_adc_ports(NO_ANALOGS);    // ANALOG giriş yok
   setup_adc(ADC_OFF);             // ADC birimi devre dışı
   setup_CCP1(CCP_OFF);            // CCP1 birimi devre dışı
   setup_CCP2(CCP_OFF);            // CCP2 birimi devre dışı
   setup_spi(spi_slave| spi_L_to_H | spi_ss_disabled);  // SPI iletişim ayarları belirtiliyor
   enable_interrupts(int_ssp);   // SPI kesmesi aktif yapılıyor
   enable_interrupts(GLOBAL);    // Aktif edilen tüm kesmelere izin ver 

   while(1) // Sonsuz Döngü
   { 
           
      }
}


Spi Debugger Ekran Alıntısı: ( Baştaki 0x2F neden Slave'den gönderiliyor onu da anlamış değilim ?)
[IMG]http://i62.tinypic.com/9940b6.png[/img]
Başlık: Ynt: Spi ile PIC'ler Arası Haberleşmede Sorun
Gönderen: Pyrodigy - 02 Aralık 2014, 10:44:38
Yazdığım formüle tekrar gözden geçirmeni öneririm ve ayrıca spi ın çalışma manıtığını tekrar okumalısın. SPI haberleşmede en fazla yapılan hata asenkron haberleşme zannedilmesidir. Halbuki SPI senkron haberleşir.
Tekrar üzerine basarak söylüyorum. Master veri gönderirken aynı zmanda alır ! Slave veri alırken aynı zamanda gönderir ! Bu verileri ister al kullan ister değerlendir o senin bileceğin iş ama mutlaka slave alırken data gönderir master da eğer istemiyorsa bile veriyi alır !!!!!!!
İşte o yüzden slave den anlamsız veri gönderildiğini görürsün.
SPI buffer ı olarak SSPBUF mı kullanıyorsun ? Evet ise slave master a örneğin 0xff göndert, sonra master alıp atsın ama mutlaka kodlarında ve özellikle kesme kullanıyorsan alım yap sonra sil at.
Not: Verdiğim kod örneğinde Dummy_Data demişim o dummy_datalar işe yaramayan ama mutlaka alınması / gönderilmesi gereken datadır.
Ayrıca buton için 20 ila 50 ms lik gecikme koy yoksa ark oluşur aynı datalar 2-3 defa gider gelir.

mesaj birleştirme:: 02 Aralık 2014, 10:55:31

Bir diğer önemli konu ise;
SPI da haberleşme Master ' ın clock' u üzerinden gerçekleşir. Master ve slave aynı clock üzerinden data alış verişi yaptığı için clock larıda aynı olmalı.
Kodlarında Master da 20MHZ Slave de 40MHz gördüm. Bunları değiştir aynı frekansı kullan yani ikiside ya 20 MHZ veya 40MHz olsun.
Başlık: Ynt: Spi ile PIC'ler Arası Haberleşmede Sorun
Gönderen: OnderGrmz - 03 Aralık 2014, 22:14:10
Alıntı yapılan: Pyrodigy - 02 Aralık 2014, 10:44:38
Ayrıca buton için 20 ila 50 ms lik gecikme koy yoksa ark oluşur aynı datalar 2-3 defa gider gelir.
Ekledim hocam.

Alıntı yapılan: Pyrodigy - 01 Aralık 2014, 22:58:48

Master Yazmak için

spi_write(TX_bilgi);
RX_dummy_data=spi_read();

Slave Okumak için

spi_write(TX_dummy_data);
RX_bilgi=spi_read();

Tekrar üzerine basarak söylüyorum. Master veri gönderirken aynı zamanda alır ! Slave veri alırken aynı zamanda gönderir ! Bu verileri ister al kullan ister değerlendir o senin bileceğin iş ama mutlaka slave alırken data gönderir master da eğer istemiyorsa bile veriyi alır !!!!!!!
İşte o yüzden slave den anlamsız veri gönderildiğini görürsün.
Not: Verdiğim kod örneğinde Dummy_Data demişim o dummy_datalar işe yaramayan ama mutlaka alınması / gönderilmesi gereken datadır.

Bu bilgilere dayanarak kodları şu şekilde düzenledim ve sistem tam istediğim gibi çalıştı  :D
Master:

int8 okuma_istek=0x05,okunan_deger,master_tx_gereksiz=0x55;
while(1) // Sonsuz Döngü
   {   
     if(input(pin_b5)==1)
     {   
         delay_ms(20);
         while(input(pin_b5));               

         output_low(cs); // Entegre seçiliyor
         spi_write(okuma_istek);//Bilgi yazmak için gerekli kodlar yazılıyor
         output_high(cs);
         delay_ms(50);

        output_low(50);
        okunan_deger=spi_read();
        spi_write(master_tx_gereksiz);//Bilgi almak için gerekli kodlar yazılıyor     
         output_high(cs);
  }       
  }


Slave:

int8 bilgi=0x10,okunan,slave_tx_gereksiz=0x12;
void SPI_kesmesi()
{     
       okunan=spi_read();
       spi_write(slave_tx_gereksiz);     
}
while(1) // Sonsuz Döngü
{           
        if(okunan == 0x05)
    {       
       printf("\n\r\Bilgi alindi !!!");
       printf("\n\r\Alinan Deger=0x%02X",okunan );
       spi_write(bilgi);      // Belirtilen adrese yazdırılacak veri gönderiliyor
    }
}


Buda Spi Debugger ve Virtual Terminal Görüntüsü:
[IMG]http://i58.tinypic.com/2ufwzsn.png[/img]
Başlık: Ynt: Spi ile PIC'ler Arası Haberleşmede Sorun
Gönderen: Pyrodigy - 04 Aralık 2014, 00:49:22
Hayırlı olsun. Çalışan Kodlarını paylaşman güzel bir davranış.
Başlık: Ynt: Spi ile PIC'ler Arası Haberleşmede Sorun
Gönderen: OnderGrmz - 04 Aralık 2014, 01:25:43
Alıntı yapılan: Pyrodigy - 04 Aralık 2014, 00:49:22
Hayırlı olsun. Çalışan Kodlarını paylaşman güzel bir davranış.
Yardımlarınız için teşekkür ederim hocam. Aynı durumlar ile karşılaşan arkadaşlara faydalı olması temennimizdir.
Alıntı yapılan: Pyrodigy - 02 Aralık 2014, 10:44:38
Bir diğer önemli konu ise;
SPI da haberleşme Master ' ın clock' u üzerinden gerçekleşir. Master ve slave aynı clock üzerinden data alış verişi yaptığı için clock larıda aynı olmalı.
Kodlarında Master da 20MHZ Slave de 40MHz gördüm. Bunları değiştir aynı frekansı kullan yani ikiside ya 20 MHZ veya 40MHz olsun.
Hocam aslında Master ve Slave'de 20 MHz'lik bir kristal kullanmayı düşünüyorum. Proteus'ta kurduğum Slave devre için yazdığım kodda kristali 20 MHz yapınca devredeki Virtual Terminal saçmalamaya başlıyor.

Aynen şu şekilde:
[IMG]http://i62.tinypic.com/33atod4.png[/img]

Bu devreyi kurduğumda RS232 ile bilgisayara bağlasam acaba Proteusta olduğu gibi saçmalar mı ?
Birde bu devreyi kurunca muhakkak beklenmedik problemler ortaya çıkıcak. Spi Debugger gibi gönderdiğim bilginin doğru gidip gitmediğini görüntüleyebilmek için gerçek zamanda kullanabileceğim bir aygıt var mı ?
Başlık: Ynt: Spi ile PIC'ler Arası Haberleşmede Sorun
Gönderen: RaMu - 04 Aralık 2014, 08:31:04
Kodu derlerken 20MHz seçiyorsun
daha sonra
isis üzerinde pic in üzerine çift tıklayıp frequency seçeneğini 20MHz e alıyorsun.

Böyle mi yapıyorsun?
Sadece isisde veya sadece kodda değiştirmen yetmez, ikisinide aynı yapmalısın.
Virtual terminal in uygun bir baudrate de olmasıda önemli.
Başlık: Ynt: Spi ile PIC'ler Arası Haberleşmede Sorun
Gönderen: Pyrodigy - 04 Aralık 2014, 09:39:06
Alıntı yapılan: OnderGrmz - 04 Aralık 2014, 01:25:43
Yardımlarınız için teşekkür ederim hocam. Aynı durumlar ile karşılaşan arkadaşlara faydalı olması temennimizdir.Hocam aslında Master ve Slave'de 20 MHz'lik bir kristal kullanmayı düşünüyorum. Proteus'ta kurduğum Slave devre için yazdığım kodda kristali 20 MHz yapınca devredeki Virtual Terminal saçmalamaya başlıyor.

Aynen şu şekilde:
[IMG]http://i62.tinypic.com/33atod4.png[/img]

Şemayı bir gönder bakalım

Alıntı yapılan: OnderGrmz - 04 Aralık 2014, 01:25:43

Bu devreyi kurduğumda RS232 ile bilgisayara bağlasam acaba Proteusta olduğu gibi saçmalar mı ?
Birde bu devreyi kurunca muhakkak beklenmedik problemler ortaya çıkıcak. Spi Debugger gibi gönderdiğim bilginin doğru gidip gitmediğini görüntüleyebilmek için gerçek zamanda kullanabileceğim bir aygıt var mı ?


Microchip in debuggerleri var PICkit in virtual debuggeri var ama SPI varmı hatırlamıyorum.
Başlık: Ynt: Spi ile PIC'ler Arası Haberleşmede Sorun
Gönderen: OnderGrmz - 04 Aralık 2014, 11:54:29
Alıntı yapılan: Pyrodigy - 04 Aralık 2014, 09:39:06
Şemayı bir gönder bakalım.
Hocam şu anda bilgisayarım yanımda değil.
Alıntı yapılan: RaMu - 04 Aralık 2014, 08:31:04
Kodu derlerken 20MHz seçiyorsun
daha sonra
isis üzerinde pic in üzerine çift tıklayıp frequency seçeneğini 20MHz e alıyorsun.
Böyle mi yapıyorsun?
Sadece isisde veya sadece kodda değiştirmen yetmez, ikisinide aynı yapmalısın.
İkisini de yapıyorum hocam. Yine kontrol eder buradan paylaşırım.   
Alıntı yapılan: RaMu - 04 Aralık 2014, 08:31:04
Virtual terminal in uygun bir baudrate de olmasıda önemli.
Virtual Terminal'in baudrate kısmına dikkat etmemiştim. Ona da bakacağım.
Başlık: Ynt: Spi ile PIC'ler Arası Haberleşmede Sorun
Gönderen: OnderGrmz - 05 Aralık 2014, 00:00:50
Alıntı yapılan: RaMu - 04 Aralık 2014, 08:31:04
Kodu derlerken 20MHz seçiyorsun
daha sonra
isis üzerinde pic in üzerine çift tıklayıp frequency seçeneğini 20MHz e alıyorsun.
Böyle mi yapıyorsun?
Sadece isisde veya sadece kodda değiştirmen yetmez, ikisinide aynı yapmalısın.
Hocam şimdi baktım da ben sadece kristal ile kodların frekansını değiştirmişim  :D
Entegreye tıklayıp oradan kristal frekansını değiştirince hiçbir sorun kalmadı.
Başlık: Ynt: Spi ile PIC'ler Arası Haberleşmede Sorun
Gönderen: OnderGrmz - 07 Aralık 2014, 22:52:33
Merhabalar;
Spi ile haberleşme yaparken bir duruma rastladım. int8 değişken türünde birkaç tane değerim olması gerekiyor. Bu değerleri tanımladıktan sonra Spi'dan bilgi göndermeye çalıştım. Ancak normalde çalışan kodların yanlış çalıştığını gördüm. İnt8 türündeki değişkenlerin sayısı 10 olduğunda Spi iletişiminde gönderdiğim kodlar karşıya doğru bir şekilde gitmiyor. Bunların birbirleriyle ilgisini pek anlayamadım. Değişkenin değerine bağlı bir durum değil bu. Yani değişken sayısı 10'un altında olduğu sürece problem çıkmıyor. Değişken sayısı 10'un üzerine çıkınca gönderilen ve alınan bilgiler sapıtıyor. Bir anlam veremedim bu duruma. Daha önce böyle bir durumla karşılaşan var mı ?
Master:

#include <18f4680.h>     // Kullanılacak denetleyicinin başlık dosyası tanıtılıyor.
//#include <motor kontrol.c>
#fuses HS,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,NOPUT,NOWRT,NODEBUG,NOCPD // Denetleyici konfigürasyon ayarları

#use delay(clock=20000000)   // Gecikme fonksiyonu için kullanılan osilatör frekansı belirtiliyor
#define cs PIN_C2    // CS ifadesi PIN_C2 pini yerine atanıyor

int8 okuma_istek=0x05,okunan_deger,master_tx_gereksiz=0x35;  // int8 tipinde değişkenler tanımlanıyor
int8 ileri=0x50,geri=0x51,saga=0x52,sola=0x53;
int8 ileri_sag=0x54,ileri_sol=0x55;                            // Değişken sayısı 9 sıkıntı yok !!!
//int8 geri_sag=0x56,geri_sol=0x57;

void oku();
void yaz(int8 a);

#int_ssp // SPI iletişiminde yazma veya okuma yapıldığında meydana gelen kesme
void SPI_kesmesi()


}

void main ()
{
   setup_psp(PSP_DISABLED);        // PSP birimi devre dışı
   setup_timer_1(T1_DISABLED);     // T1 zamanlayıcısı devre dışı
   setup_timer_2(T2_DISABLED,0,1); // T2 zamanlayıcısı devre dışı
   setup_adc_ports(NO_ANALOGS);    // ANALOG giriş yok
   setup_adc(ADC_OFF);             // ADC birimi devre dışı
   setup_CCP1(CCP_OFF);            // CCP1 birimi devre dışı
   setup_CCP2(CCP_OFF);            // CCP2 birimi devre dışı
 
   setup_spi(spi_master| spi_L_to_H | spi_clk_div_4);  // SPI iletişim ayarları belirtiliyor
   
   enable_interrupts(int_ssp);   // SPI kesmesi aktif yapılıyor
   enable_interrupts(GLOBAL);    // Aktif edilen tüm kesmelere izin ver 

   output_high(cs); // Harici EEPROM CS ucu lojik-1 yapılıyor

   while(1) // Sonsuz Döngü
   {
       if(input(pin_b5)==1)
       {
         delay_ms(50);
         while(input(pin_b5));
         yaz(okuma_istek);
         oku();
       }         
  }       
}

void oku()
{
   okunan_deger=spi_read();
   spi_write(master_tx_gereksiz);//Bilgi almak için gerekli kodlar yazılıyor
}

void yaz (int8 a)
{
   output_low(cs);  // Entegre seçiliyor
   spi_write(a); //Bilgi yazmak için gerekli kodlar yazılıyor
   output_high(cs);
}





Slave:


#include <18f4680.h>     // Kullanılacak denetleyicinin başlık dosyası tanıtılıyor.
#fuses HS,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,NOPUT,NOWRT,NODEBUG,NOCPD // Denetleyici konfigürasyon ayarları
#use delay(clock=20000000)   // Gecikme fonksiyonu için kullanılan osilatör frekansı belirtiliyor

#use rs232 (baud=9600, xmit=pin_C6, rcv=pin_C7, parity=N, stop=1) // RS232 iletişim ayarları belirtiliyor
 
#include <input.c>   // input.c dosyası programa ekleniyor
#include <stdlib.h>  // stdlib.h dosyası programa ekleniyor

int8 bilgi_istek=0x05,bilgi=0x10,okunan,slave_tx_gereksiz=0x12;  // int8 tipinde değişkenler tanımlanıyor


#int_ssp // SPI iletişiminde yazma veya okuma yapıldığında meydana gelen kesme
void SPI_kesmesi()
{     
       okunan=spi_read();
       spi_write(slave_tx_gereksiz);
       printf("\n\r\Bilgi alindi !!!");
       printf("\n\r\Alinan Deger=0x%02X",okunan );
}


/******************* ANA PROGRAM FONKSİYONU *************************/
void main ()
{
   setup_psp(PSP_DISABLED);        // PSP birimi devre dışı
   setup_timer_1(T1_DISABLED);     // T1 zamanlayıcısı devre dışı
   setup_timer_2(T2_DISABLED,0,1); // T2 zamanlayıcısı devre dışı
   setup_adc_ports(NO_ANALOGS);    // ANALOG giriş yok
   setup_adc(ADC_OFF);             // ADC birimi devre dışı
   setup_CCP1(CCP_OFF);            // CCP1 birimi devre dışı
   setup_CCP2(CCP_OFF);            // CCP2 birimi devre dışı
   
   setup_spi(spi_slave| spi_L_to_H | spi_ss_disabled);  // SPI iletişim ayarları belirtiliyor
   
   enable_interrupts(int_ssp);   // SPI kesmesi aktif yapılıyor
   enable_interrupts(GLOBAL);    // Aktif edilen tüm kesmelere izin ver   

   while(1) // Sonsuz Döngü

     if(okunan == 0x05)
    {         
       spi_write(bilgi);      // Belirtilen adrese yazdırılacak veri gönderiliyor
    }         
     
}




Ekran Alıntısı:
[IMG]http://i62.tinypic.com/2pynuok.png[/img]

Kodlarda sadece şu kısmı değiştirince


int8 okuma_istek=0x05,okunan_deger,master_tx_gereksiz=0x35;  // int8 tipinde değişkenler tanımlanıyor
int8 ileri=0x50,geri=0x51,saga=0x52,sola=0x53;
int8 ileri_sag=0x54,ileri_sol=0x55;                            // 10 ve üstü değişken sıkıntı yaratıyor !!!
int8 geri_sag=0x56,geri_sol=0x57;


Aşağıdaki gibi bir durum oluşuyor.
[IMG]http://i57.tinypic.com/2i6jij9.png[/img]

Burada iki önemli nokta var bence Spi Debugger'dan bakarsak Slave cihaza göndermek istediğimiz 0x05 bilgisi gönderilmiş olarak görünüyor.
Ama Virtual Terminal'e bakarsak 0x05 bilgisi değilde 0x9A bilgisi gönderilmiş olarak görünüyor. Slave kodlarındaki şu satırdan Virtual Terminal'in doğru gösterdiği sonucu çıkıyor.

if(okunan == 0x05)
    {       
       
       spi_write(bilgi);      // Belirtilen adrese yazdırılacak veri gönderiliyor
    }

Eğer Slave'e gelen veri 0x05 olsaydı Master cihaza 0x10 bilgisi gönderilmesi gerekiyordu. Yardımlarınızı bekliyorum.
Saygılarımla ...
Başlık: Ynt: Spi ile PIC'ler Arası Haberleşmede Sorun
Gönderen: OnderGrmz - 15 Mayıs 2015, 01:51:02
Merhabalar;
Konu biraz eski ama bu konunun üzerine ilave olarak birkaç şey sormak istiyorum.
(http://upload.wikimedia.org/wikipedia/commons/f/fc/SPI_three_slaves.svg)
Spi haberleşmesinde 2 tane slave 1 tane master kullanmak istiyorum.
Slave cihazlarından bir tanesi pic ve SS pini mevcut değil. 2. slave cihazın ise SS pini mevcut. Ben 2. slave cihaza SS pinini lojik 0 yaparak bilgi gönderdiğimde dolayısıyla slave pic'te bilgiyi alıyor ve spi haberleşme protokolü gereği aynı anda MISO üzerinden birde bilgi gönderiyor. Hal böyle olunca master cihaza giden bilgiler karışıyor ve sistem patlıyor.
Sistemi ayrı ayrı denediğimde hiçbir sıkıntı yok. Master cihaz ile 2. slave, master cihaz ile slave pic ayrı ayrı iken gayet güzel çalışıyorlar.
Not: Ayrıca sistemi test ederken şunu da denedim. Slave pic in MISO pininin bağlantısını kopardığımda Master ile 2. slave gayet düzgün çalışıyor, aynı zamanda slave pic e bilgi gönderebiliyorum.
Bu problemin üstesinden nasıl gelebilirim ?
Saygılarımla ...

Başlık: Ynt: Spi ile PIC'ler Arası Haberleşmede Sorun
Gönderen: z - 15 Mayıs 2015, 02:34:15
Master cihaza da kodları sen yazıyorsan sorun yok.

SS dediğin pinleri yazılımla sen harekete geçirirsin. Slave PIC'in herhangi bir pinini bu amaçla kullanırsın. Pic bu pini low görünce SPI rutinleri çalışacak şekilde düzenlersin.

Eğer bahse konu pic yazılımına müdahale edemiyorsan SCK,MOSI MISO hatlarına three state buffer vs koyarsın. SS pini bu bufferın enable ucu olur. SS low olmazsa three state buffer master ile pic bağlantısını kopartır low olduğunda bağlantıyı sağlar.

2. çözüm tamamen elektronik çözüm. İlk çözüm ise yazılımsal çözüm.
Başlık: Ynt: Spi ile PIC'ler Arası Haberleşmede Sorun
Gönderen: OnderGrmz - 15 Mayıs 2015, 04:25:09
Alıntı yapılan: z - 15 Mayıs 2015, 02:34:15
SCK,MOSI MISO hatlarına three state buffer vs koyarsın. SS pini bu bufferın enable ucu olur. SS low olmazsa three state buffer master ile pic bağlantısını kopartır low olduğunda bağlantıyı sağlar.

2. çözüm tamamen elektronik çözüm. İlk çözüm ise yazılımsal çözüm.

Hocam baskı devresini yaptığım için şu anda 2. çözüm pek uygun görünmüyor. Yazılımsal olarak halletmeye çalışacağım.
Alıntı yapılan: z - 15 Mayıs 2015, 02:34:15
Master cihaza da kodları sen yazıyorsan sorun yok.
SS dediğin pinleri yazılımla sen harekete geçirirsin. Slave PIC'in herhangi bir pinini bu amaçla kullanırsın. Pic bu pini low görünce SPI rutinleri çalışacak şekilde düzenlersin.

Master da yazılımı ben yazıyorum hocam. Sizin dediğiniz gibi bir şeyi yapmayı denedim.

Slave Pic Şema:
[IMG]http://i59.tinypic.com/24eaqh3.png[/img]

Slave Pic Kodları:

#int_ext2
void dis_kesme()
{  disable_interrupts(INT_EXT2);
   output_toggle(pin_b7);
   delay_ms(5);

//!   if(spi_data_is_in()==1)
//!   {
//!      okunan=spi_read();
//!      output_toggle(pin_b6);
//!   }
   enable_interrupts(INT_EXT2);
}
void main ()
{
//setup_spi(spi_slave| spi_H_to_L|spi_xmit_l_to_h |spi_ss_disabled);
ext_int_edge(L_TO_H);
enable_interrupts(INT_EXT2);
enable_interrupts(GLOBAL);    // Aktif edilen tüm kesmelere izin ver

}

Slave pic seçmek için harici kesme 2 bacağını kullanıyorum.
Master da Slave pice veri göndereceğim zaman harici kesme bacağını 0 V'a çekiyorum. İşim bitince tekrar lojik 1 yapıyorum.

Slave pic de ise harici kesme oluştuysa spi dan bilgi oku diyorum. Fakat önce de belirttiğim gibi ben
setup_spi(spi_slave| spi_H_to_L|spi_xmit_l_to_h |spi_ss_disabled);
satırını yazdığım anda pic gelen verileri değerlendirmeye başlıyor ve MISO pininden çıkış veriyor.

Bunu aşmak için ne yapmam lazım pek kestiremedim. Eğer yazılımsal çözümünü bulamazsam sizin dediğiniz gibi donanımsal bir çözüme bakacağım.
Başlık: Ynt: Spi ile PIC'ler Arası Haberleşmede Sorun
Gönderen: z - 15 Mayıs 2015, 05:40:03
SPI rutinlerini sen yazmış olsaydı iş kolaydı.

Gene  de SPI donanımı enable eden bir register vardır. Doğrudan bu registere ulaşırsın ve bir 1 bite bakar.
Başlık: Ynt: Spi ile PIC'ler Arası Haberleşmede Sorun
Gönderen: OnderGrmz - 15 Mayıs 2015, 08:46:53
Alıntı yapılan: z - 15 Mayıs 2015, 05:40:03
SPI rutinlerini sen yazmış olsaydı iş kolaydı.
Gene  de SPI donanımı enable eden bir register vardır. Doğrudan bu registere ulaşırsın ve bir 1 bite bakar.

Haklısınız hocam kullandığım denetleyicinin başlık dosyasına ve IDE'nin setup_spi fonksiyonu ile ilgili index ine baktım.  İçeride Spi birimini pasif yapan bir komut bulamadım. Bir kere ayarladıktan sonra pasif yapamıyorum.

Dediğiniz gibi registerların aldığı değerleri inceleyerek yola devam etmek lazım.
#include <18f4550.h>

////////////////////////////////////////////////////////////////// SPI
// SPI Functions: SETUP_SPI, SPI_WRITE, SPI_READ, SPI_DATA_IN
// Constants used in SETUP_SPI() are:
#define SPI_MASTER       0x20
#define SPI_SLAVE        0x24
#define SPI_L_TO_H       0
#define SPI_H_TO_L       0x10
#define SPI_CLK_DIV_4    0
#define SPI_CLK_DIV_16   1
#define SPI_CLK_DIV_64   2
#define SPI_CLK_T2       3
#define SPI_SS_DISABLED  1

#define SPI_SAMPLE_AT_END 0x8000
#define SPI_XMIT_L_TO_H  0x4000

//////////////////////////////////////////////////////////////////

Başlık: Ynt: Spi ile PIC'ler Arası Haberleşmede Sorun
Gönderen: z - 15 Mayıs 2015, 09:56:56
SSPEN: Master Synchronous Serial Port Enable bit
1 = Enables serial port and configures SCK, SDO, SDI and SS as serial port pins(2)
0 = Disables serial port and configures these pins as I/O port pins(2)

http://ww1.microchip.com/downloads/en/DeviceDoc/39632e.pdf (http://ww1.microchip.com/downloads/en/DeviceDoc/39632e.pdf) Sayfa 199

SPI disable yapmak için SSPCON1 registerini okuyup  0xDF ile andleyip geri yazmayı deneyebilirsin.
Enable etmek için gene SSPCON1 registerini okuyup 0x20 ile orlayıp geri yazmayı deneyebilisin.

Başlık: Ynt: Spi ile PIC'ler Arası Haberleşmede Sorun
Gönderen: skara1214 - 15 Mayıs 2015, 11:08:40
a5 slave select pini
Başlık: Ynt: Spi ile PIC'ler Arası Haberleşmede Sorun
Gönderen: OnderGrmz - 16 Mayıs 2015, 03:15:36
z hocam SSPCON1 register ına bakınca aklımda bir şeyler canlanmaya başladı.
Birde skara1214 hocam söylediğinde haklı.

datasheet te (http://ww1.microchip.com/downloads/en/DeviceDoc/39632e.pdf) 204. sayfadaki
19.3.7 SLAVE SELECT SYNCHRONIZATION
başlığa bakarsak pic slave modunda çalışırken SS (Ra5 ) pini yetkilendirilirse picin spi haberleşmesini başlatan pin olduğu yazıyor.

Yine datasheet te (http://ww1.microchip.com/downloads/en/DeviceDoc/39632e.pdf) 199. sayfaya dönüp bakarsak
gerekli ayarlar aşağıdaki gibi olmalı.

setup_spi(); fonksiyonu SSPCON1 ve SSPSTAT kaydedicilerine spi için gerekli olan parametreleri gönderiyor.

[IMG]http://i62.tinypic.com/2dt8wab.png[/img]

Master tarafında gönderici sistemimde ayarlar aşağıdaki gibi
CPOL=0;
CPHA=0;
slave picte ise
CKP=0;
CKE=1;
değerlerine tekabül ediyor.
CKE değerini SSPSTAT: MSSP STATUS REGISTER (SPI MODE) kaydedicisinin 6. biti kontrol ediyor.
bit 6 CKE: SPI Clock Select bit(1)
1 = Transmit occurs on transition from active to Idle clock state
0 = Transmit occurs on transition from Idle to active clock state
0x40 yazılmalı
#define SPI_XMIT_L_TO_H  0x4000

SSPCON1:
bit 5 SSPEN: Master Synchronous Serial Port Enable bit spi'ı aktif hale getirmek için 0x20 yazmak gerekiyor.

bit 3-0 SSPM3:SSPM0: Master Synchronous Serial Port Mode Select bits
0101 = SPI Slave mode, clock = SCK pin, SS pin control disabled, SS can be used as I/O pin(3)
0100 = SPI Slave mode, clock = SCK pin, SS pin control enabled(3)

SS pinini kullanıp slave olarak çalıştırmak istersek 0x04 bilgisi yazılmalı
#define SPI_SLAVE        0x24 // Spi birimini ve SS pinini aktif edecek bilgi mevcut



bit 4 CKP: Clock Polarity Select bit
1 = Idle state for clock is a high level
0 = Idle state for clock is a low level

Clock sinyalinin boştayken lojik 0 olması gerektiğini belirtmek için ise 0x00 yazmamız lazım.

#define SPI_L_TO_H       0     // Saat darbesi polaritesi belirtiliyor


Bunların hepsinin birleştirirsek
setup_spi(spi_slave| spi_L_to_H|SPI_XMIT_L_TO_H);  // SPI iletişim ayarları belirtiliyor 
yazmamız gerekiyor.

Ayrıca SS pinin (Ra5) bağlantısını yaptım. Böylelikle Slave pic in gereksiz yere MISO hattını boşuna meşgul etmesi problemini çözdüm.

Şu anda ise farklı bir problem oluştu. :D
Slave pic e gelen bilgiyi okuduğumda tüm spi hattı kilitleniyor.

okuma işlemini tarama ile veya kesme ile yapmayı denedim yinede kilitleniyor. Buna anlam veremedim. Biraz uzun soluklu oldu, kusura bakmayın :D


#int_ssp
void spi_kesmesi()
{
   disable_interrupts(int_ssp);
   output_toggle(pin_b7);
   delay_ms(50);
   okunan=spi_read();


   enable_interrupts(int_ssp);
}

// yada

if(spi_data_is_in()==1)
   {
       okunan=spi_read();
       output_toggle(pin_b7);
       delay_ms(50);
   }
Başlık: Ynt: Spi ile PIC'ler Arası Haberleşmede Sorun
Gönderen: OnderGrmz - 16 Mayıs 2015, 13:53:14
Öncelikle z ve skara1214 hocam sizlere teşekkürlerimi sunarım.
Dün gece fark edemediğim bir nokta varmış. Ben kodlarımı farklı bir pic için yazmıştım. Uyarlarken alt fonksiyonlara bakmayı unutmuşum. Alt fonksiyonlardan bir tanesine alınan veriye göre işlem yapılıyordu. İşlem yapılan pin ise SCK pini  :D
Bu nedenle okunan=spi_read(); fonksiyonu ile okunan bilgi doğru olduğunda SCK pini lojik 0'a çekiliyormuş. Bunu şimdi fark ettim.
Dün gece de belirttiğim gibi
setup_spi(spi_slave| spi_L_to_H|SPI_XMIT_L_TO_H);  // SPI iletişim ayarları belirtiliyor
satırı problemi çözdü.
Saygılarımla...