I2c Arka arkaya veri yollama,

Başlatan ademtosun58, 21 Nisan 2017, 14:02:59

ademtosun58

Merhaba arkadaslar iki pic ile bir ı2c ile haberleşme yapıyorum.Master cihazdan bir veri yolladıgımda slave cihazdan led ile yolladıgım değeri görüyorum.Ama arka arkaya iki farklı veri yollayamıyorum nasıl bir şey yapmam lazım yardımcı olursanız sevinirim.


void main()
{
    
    unsigned short d1=5;

    nRBPU = 0;
    TRISB = 0xFF;
    TRISD = 0x00;
    PORTD = 0x00;
    I2C_Master_Init(100000);
    while(1)
    {
  
  
        I2C_Master_Start();
        I2C_Master_Write(0x40);
         I2C_Master_Write(d1);   
        I2C_Master_Stop();
        }
}
       

ademtosun58

32 byte lık bir veri yollayıp lcd ye print edicem nasıl yapabilirim.

Kabil ATICI

I2C_Master_Write(d1);  veri gönderme satırı burası... sen programını buna göre yapabilirsin

I2C_Master_Start();
I2C_Master_Write(0x40);
...
I2C_Master_Write(d1);
I2C_Master_Write(d2);
I2C_Master_Write(d3);
I2C_Master_Write(d4);
I2C_Master_Write(d5);
...
I2C_Master_Stop();

şeklinde veri gönderebilirsin.
Alıcı tarafındaki veri akışı kontrolu sana ait...
ambar7

ademtosun58

Alıntı yapılan: Kabil ATICI - 21 Nisan 2017, 17:22:17
I2C_Master_Write(d1);  veri gönderme satırı burası... sen programını buna göre yapabilirsin

I2C_Master_Start();
I2C_Master_Write(0x40);
...
I2C_Master_Write(d1);
I2C_Master_Write(d2);
I2C_Master_Write(d3);
I2C_Master_Write(d4);
I2C_Master_Write(d5);
...
I2C_Master_Stop();

şeklinde veri gönderebilirsin.
Alıcı tarafındaki veri akışı kontrolu sana ait...



üstad alıcı tarafında ise tek byte için böyle bir şey yapıyorym ama bir türlü diger taraftan gel d1,d2,d3 gibi bilgileri aynı anda alamıyorum ne yapsam istedigim bilgiyi alamıyorum.Buraya nasıl bir düzenleme yapmam gerekir.

short z;
 short d;

 int count=0;
 unsigned int inputflag=0;
void interrupt I2C_Slave_Read()
{ 
    if(SSPIF == 1)
    {
       SSPCONbits.CKP = 0;
       
       if ((SSPCONbits.SSPOV) || (SSPCONbits.WCOL))
       {
             z = SSPBUF;            // Read the previous value to clear the buffer
             SSPCONbits.SSPOV = 0; // Clear the overflow flag
             SSPCONbits.WCOL = 0;   // Clear the collision bit
             SSPCONbits.CKP = 1;
       }

      if(!SSPSTATbits.D_nA && !SSPSTATbits.R_nW) 
       {
         z = SSPBUF;  //Adres bilgisini al
           while(!BF);
           d=SSPBUF;// data bilgisini al
      
       
           SSPCONbits.CKP = 1;
           inputflag=1;
           
         
       }
      /* else if(!SSPSTATbits.D_nA && SSPSTATbits.R_nW)
       {
           z = SSPBUF;
           BF = 0;
           SSPBUF = PORTB ;
           SSPCONbits.CKP = 1;
           while(SSPSTATbits.BF);
       }*/        
       SSPIF = 0;
    }
  
}

void I2C_Slave_Init(short address)
{
    SSPSTAT = 0x80;
    SSPADD = address;
    SSPCON = 0x36;
    SSPCON2 = 0x01;
    TRISC3 = 1;
    TRISC4 = 1;
    GIE = 1;
    PEIE = 1;
    SSPIF = 0;
    SSPIE = 1;
}

void main()
{
     char t[20];
    nRBPU = 0;
    TRISB = 0xFF;;
    TRISD = 0x00;
    PORTD = 0x00;
    InitLCD();
    I2C_Slave_Init(0x40);
    while(1){
        if(inputflag)
        {
           ClearLCDScreen();
            char t[20];
            sprintf(t,"%d",d);  
            WriteCommandToLCD(0xC0);
            WriteStringToLCD(t);
              __delay_ms(200); ;
        }
    }
  
}

JOKERAS

I2C protokolünü iyice araştırın,nasıl çalıştığını öğrenirseniz işi daha kolay çözersiniz.


I2C Slave kullanmak için Slave'e bir adres belirlemeniz gerek.
Kodunuzda böyle bir adres bilgisi yok,ha siz tek bir slave kullanıyorsanız sorun olmaz ama
yinede Slave cihaza bir adres verin.I2C Adresleme mantığıyla çalışır.
Bunu yapmazsanız, I2C yolunda olabilecek her tıngırtı,gürültü patırtı data olarak kabul görür.


Slave cihazlar her Byte datadan sonra  ACK ile Master'a cevap verir.
Kodunuzda böyle bir ifadede yok.


Slew Rate kontrolü o da yok,Clock Strech işlemi yapar.
Yani derki..
"Master efendi,senin veya başka bir masterin biraz önce gönderdiği datayı henüz basmadım,hala uğraşıyorum
biz zahmet bekle!Zaten dataları basarsam sana ACK ile cevap veririm" der.
Bu şekilde I2C Clock'unu High'da tutar.
Siz Donanımsal I2C yapıyorsunuz,Donanımı düzgün kurmak gerekir.


Slaveİnit fonksiyonunda ki Global interrupt GIE ve PEIE bitlerini en sona alın.
İlgili işlemcinin Pdf'ni ve protokolün çalışma yapısını güzelce inceleyin derim.










ademtosun58

Alıntı yapılan: JOKERAS - 22 Nisan 2017, 14:55:43
I2C protokolünü iyice araştırın,nasıl çalıştığını öğrenirseniz işi daha kolay çözersiniz.


I2C Slave kullanmak için Slave'e bir adres belirlemeniz gerek.
Kodunuzda böyle bir adres bilgisi yok,ha siz tek bir slave kullanıyorsanız sorun olmaz ama
yinede Slave cihaza bir adres verin.I2C Adresleme mantığıyla çalışır.
Bunu yapmazsanız, I2C yolunda olabilecek her tıngırtı,gürültü patırtı data olarak kabul görür.


Slave cihazlar her Byte datadan sonra  ACK ile Master'a cevap verir.
Kodunuzda böyle bir ifadede yok.


Slew Rate kontrolü o da yok,Clock Strech işlemi yapar.
Yani derki..
"Master efendi,senin veya başka bir masterin biraz önce gönderdiği datayı henüz basmadım,hala uğraşıyorum
biz zahmet bekle!Zaten dataları basarsam sana ACK ile cevap veririm" der.
Bu şekilde I2C Clock'unu High'da tutar.
Siz Donanımsal I2C yapıyorsunuz,Donanımı düzgün kurmak gerekir.


Slaveİnit fonksiyonunda ki Global interrupt GIE ve PEIE bitlerini en sona alın.
İlgili işlemcinin Pdf'ni ve protokolün çalışma yapısını güzelce inceleyin derim.


iyi günler

I2c_slave_read(adress)  orada adresi belirliyorum
slew rate kontrolu de var SSPSTAT=0x80 ; olarak belirli ;

şu an similasyonda debug yapınca master bilgiyi yolluyor ama slave cihazda tek byte n basıyor slave cihazın okumasıda şu sekilde,


     if(!SSPSTATbits.D_nA && !SSPSTATbits.R_nW) 
       { 
          z = SSPBUF; //adres
          while(!BF);
           d=SSPBUF;//data
         
    
        //  PORTD =d;
           SSPCONbits.CKP = 1;
           inputflag=1;
           
       }