- fchao-Sinus-Wechselrichter AliExpress         
Ergebnis 1 bis 3 von 3

Thema: I2C Master / Slave 16F887/16F883

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    26.06.2011
    Beiträge
    14

    I2C Master / Slave 16F887/16F883

    Anzeige

    Praxistest und DIY Projekte
    Hi zusammen,

    Zur Zeit versuche ich eine Kommunikation zwischen zwei uC hin zubekommen. Da es mein erstes I2C Projekt ist, habe ich den Code aus dem Internet kopiert und an meine PIC's angepasst. Original sind die Code's für den 16F876A.

    Hier der Mastercode. [16F887]
    Code:
    // 16F887
    
    const Slave_Addy = 0x69;
    
    void send(unsigned short send_data){
      I2C1_Init(100000);
      I2C1_Start();
      I2C1_Wr(Slave_Addy);
      I2C1_Wr(send_data);
      I2C1_Stop();
    }
    
    unsigned short read(){
      unsigned short read_data;
      I2C1_Init(100000);
      I2C1_Start();
      I2C1_Wr(Slave_Addy + 1);
      read_data = I2C1_Rd(0);
      delay_ms(100);
      I2C1_Stop();
      return read_data;
    }
    
    void main(){
         ANSEL = 0;
         ANSELH = 0;
         TRISA = 0;
         PORTA = 0b00001111;
         TRISB = 0;
         PORTB = 0;
         PORTC = 255;
         
         while (1) {
         send(166);
         PORTA != PORTA;
         delay_ms(2000);
         }
         
     // Main program code place here.
     // Use sub-routine "send" to send data to slave.
     // Use "read" to read data from slave.
    Hier der Slavecode [16F883]
    Code:
    // 16F883
    
    //------------------------------------------------------------------------------
    const Addy = 0x69;                    // set I2C device address
    const Delay_Time = 250;               // port check delay
    //------------------------------------------------------------------------------
    //                      Global Processing Variables
    //------------------------------------------------------------------------------
    unsigned short j;                      // just dummy for buffer read
    unsigned short rxbuffer;               //
    unsigned short tx_data;                //
    //------------------------------------------------------------------------------
    void Init(){
      ANSEL = 0;                          // All ports set to digital
      ANSELH = 0;
      TRISA = 0;                           // Set PORTA as output
      PORTA = 0;
      TRISB = 0;                           // Set PORTB as output
      PORTB = 0;
      TRISC = 0b00011000;                        // Set PORTC as input
      PORTC = 0;
      SSPADD =  Addy;                      // Get address (7bit). Lsb is read/write flag
      SSPCON = 0x36;                       // Set to I2C slave with 7-bit address
      PIE1.SSPIE = 1;                      // enable SSP interrupts
      PIR1.SSPIF = 0;
      SSPSTAT.R_W = 0;
      SSPSTAT.BF = 1;
      SSPSTAT.D_A = 0;
      INTCON = 0xC0;                       // enable INTCON.GIE
    }
    //------------------------------------------------------------------------------
    void interrupt(){                      // I2C slave interrupt handler
      if (PIR1.SSPIF == 1){                // I2C Interrupt
        PIR1.SSPIF = 0;                    // reset SSP interrupt flag
        RB7_bit = 1;                       // Nur zum Debugen
        //transmit data to master
        if (SSPSTAT.R_W == 1){             // Read request from master
          SSPBUF = tx_data;                // Get data to send
          SSPCON.CKP = 1;                  // Release SCL line
          j = SSPBUF;
          RB6_bit = 1;                      // Nur zum Debugen
          return;
        }
        if (SSPSTAT.BF == 0){              // all done,
          j = SSPBUF;                      // Nothing in buffer so exit
          RB5_bit = 1;                     // Nur zum Debugen
          return;
        }
    
        //recieve data from master
        if (SSPSTAT.D_A == 1){             // Data [not address]
          rxbuffer = SSPBUF;               // get data
          j = SSPBUF;                      // read buffer to clear flag [address]
          RB4_bit = 1;                     // Nur zum Debugen
          return;
        }
      }
      RB3_bit = 1;                             // Nur zum Debugen
      j = SSPBUF;                              // read buffer to clear flag [address]
    }
    //------------------------------------------------------------------------------
    void main(){
      Init();
      while(1){
        PORTC   = rxbuffer;
        tx_data = 170;
        Delay_ms(Delay_Time);
        RB2_bit = 1;
      }
    }
    Nun das Problem:
    Der Master sendet den Wert "166" welche beim Slave nie wirklich ankommen. SDA bleibt nach diesem Versuch auf low.
    Beim Slave setze ich die Ausgänge vom PORTB, um zu debugen So habe ich erkannt das ein Interrupt stattfinden, jedoch scheint mir das SSPSTAT.R_W bit fehlerhaft. Dieses Bit wird als "1" gelesen, als ob der Master vom Slave lesen will...will er aber nicht.

    Habt ihr eine Idee warum es nicht funktioniert? Etwas Hilfe könnte ich gut gebrauchen

    Ps. Ich programmiere in MikroC mit dem EasyPic7 Board. Die Kommunikation zwischen Master und Eeprom funktioniert. Pull-Ups sind auch drin und Verdrahtung habe ich geprüft. Ach ja, der Slave ist mit etwa 30cm Litzen zum Board verdrahtet (Problem?)

  2. #2
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    07.11.2004
    Beiträge
    332
    Hi,
    ich hatte I2C immer in ASM für Slave-PICs programmiert. Die Sachen in C sind mir nicht so geläufig.
    Hier aber eine gute PIC Seite: http://www.sprut.de/electronic/pic/grund/i2c.htm

    Irgendwie habe ich das Gefühl, Du hast Deine Adressangabe falsch gemacht:


    const Slave_Addy = 0x69;
    void send(unsigned short send_data)
    {
    I2C1_Init(100000);
    I2C1_Start();
    I2C1_Wr(Slave_Addy); <----- Wird hier verwendet!!!!
    I2C1_Wr(send_data);
    I2C1_Stop();
    Hier ist das Bit 0 in der Addresse gesetzt und sagt aus, das es sich um einen Lese Befehl handelt.

    Prüfe Deine Adressen nochmals.

    Gruss R.
    Kaum macht man es richtig, schon funktioniert's ...

  3. #3
    Neuer Benutzer Öfters hier
    Registriert seit
    26.06.2011
    Beiträge
    14
    Hab deinen Rat befolgt und die Adresse auf den Wert 0x68 geändert (damit ist das erste Bit auf low), und siehe da, es funktioniert!
    Auch das Auslesen vom Slave hat geklappt. Schöne Sache.
    Die Seite "Sprut" ist mir bekannt, aber leider sind keine Slave Beispiele aufgeführt.

    Vielen Dank Ritchie

Ähnliche Themen

  1. Slave-Master-Slave übertragung geht nicht
    Von Dämmi im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 16
    Letzter Beitrag: 26.11.2008, 00:08
  2. I²C Master und Slave, Problem bei Master Reset
    Von ACU im Forum C - Programmierung (GCC u.a.)
    Antworten: 2
    Letzter Beitrag: 01.03.2007, 11:07
  3. I2C mit Master und Slave
    Von inschenjoer im Forum PIC Controller
    Antworten: 1
    Letzter Beitrag: 20.02.2007, 18:30
  4. LPT-Master <=> SPI <=> AVR-Slave
    Von BlueNature im Forum Elektronik
    Antworten: 2
    Letzter Beitrag: 17.04.2006, 20:38
  5. 2 x I2C Master und 1 x Slave
    Von Anubisbot im Forum Elektronik
    Antworten: 2
    Letzter Beitrag: 29.12.2005, 13:27

Stichworte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

Solar Speicher und Akkus Tests