-         

Ergebnis 1 bis 2 von 2

Thema: I2C mit Master und Slave

  1. #1

    I2C mit Master und Slave

    Anzeige

    Hallo,

    ich habe zwei PIC16F873. Einer davon soll als Master arbeiten und einer als Slave.

    Master
    Code:
    void i2c_test()
    {
      SEN = 1;               // Bus übernehmen
      while (SSPIF == 0);    // warten bis der Bus übernommen wurde
      SSPIF = 0;             // Bit zurücksetzen
    
      SSPBUF = 0b.0100.1110 & 0xFE; // an Adresse 0b.0100.1110 schreiben
      while (SSPIF == 0);    // warten bis ein ACK kommt
      SSPIF = 0;             // Bit zurücksetzen
    
      SSPBUF = 'a';          // ein 'a' schreiben
      while (SSPIF == 0);    // warten bis ein ACK kommt
      SSPIF = 0;             // Bit zurücksetzen
    
      PEN = 1;               // Bus wieder freigeben
      while (SSPIF == 0);    // warten bis der Bus freigegeben wurde
      SSPIF = 0;             // Bit zurücksetzen
    }
    
    void main(void)
    {
      ...
    
      // alle analogen Eingänge auf digital umstellen
      ADCON1 = 7;               // Die analogen Eingänge werden als digitale Eingänge
                                // genutzt.
      // RA0 bis RA3 sind externe Eingänge der originalen Platine zur 
      // Motoransteuerung
      // RA4 und RA5 sind UNBELEGTE Pins
      TRISA = 0b.1111.1111;		// Alle Pins des Ports A sind als Eingänge geschaltet.
    
      // RB1 und RB2 sind die Ausgänge um die Richtung der beiden Motoren zu steuern
      // RB0, RB3 bis RB7 sind UNGENUTZTE Pins
      TRISB = 0b.0000.0000;		// Alle Pins des Ports B sind als Ausgänge geschaltet.
      PORTB = 0b.0000.0000;     // Alle Pins des Port B auf low schalten
    
      // RC0 und RC5 sind ungenutzte Pins
      // RC1 und RC2 sind PWM-Ausgänge zur Geschwindigkeitsregelung der Motoren
      // RC3 und RC4 sind I2C-Leitungen
      // RC6 ist der serielle Ausgang
      // RC7 ist der serielle Eingang
      TRISC = 0b.1001.1000;     // Alle Pins bis auf RC3, RC4 und RC7 als Ausgänge definiert
                                // RC3 = I2C, RC4 = I2C
      PORTC = 0b.0000.0000;     // Alle Pins des Port C auf low schalten
    
      delay100(40);
    
      // I2C einstellen und aktivieren
      SSPADD = 0b.0000.1100;    // Teiler von 12 -> i1c-takt von 385kHz
      SSPCON = 0b.0000.1000;    // I2C master mode
      SSPEN = 1;
    
      PEIE = 1;   // Peripheral Interrupt Enable bit
      RCIE = 1;   // USART Receive Interrupt Enable bit
      GIE = 1;    // global interrupt enable
      erasebuffer();
    
      while(1)
      {
        i2c_test();
      }
    }
    Slave
    Code:
    #pragma origin 4		// Der folgende Code steht ab Adresse 4
    
    interrupt int_handler(void)
    {
      int_save_registers		// W, STATUS (und  PCLATH) retten
      char sv_FSR = FSR;  // save FSR if required
    
      //Interrupt from MSSP (I2C)-module
      if(SSPIF)
      {
        SSPIF=0; //Reset interrupt from MSSP-module. 
    
        char x = SSPBUF;
        PORTB.0 = 1;
        PORTB.1 = 1;
        PORTB.3 = 1;
      }
    
      FSR = sv_FSR;       // restore FSR if saved
      int_restore_registers		// W, STATUS (und PCLATH) Wiederherstellen
    }
    
    void main(void)
    {
      // alle analogen Eingänge auf digital umstellen
      ADCON1 = 7;               // Die analogen Eingänge werden als digitale Eingänge
                                // genutzt.
    
      // RA0, RA3 und RA4 werden als Eingänge genutzt
      TRISA = 0b.1111.1111;		// Alle Pins des Ports A sind als Eingänge geschaltet.
    
      // RB0, RB1 und RB3 sind Ausgänge, die auf low geschaltet werden
      // RB2, RB5, RB6 und RB7 sind Eingänge
      TRISB = 0b.1110.0100;
      PORTB = 0b.0000.0000;
    
      // RC2 ist ein Eingang
      // RC3 und RC4 sind für I2C
      // RC5 und RC6 ist ein Ausgang
    
      TRISC = 0b.0001.1100;
      PORTC = 0b.0000.0000;     // Alle Pins des Port C auf low schalten
    
      // I2C einstellen und aktivieren
    
      SSPADD = 0x40;    // Teiler von 12 -> i1c-takt von 385kHz
      SSPCON = 0b.0011.0110;    // I2C slave mode
      SSPEN = 1;
    
      PEIE = 1;   // Peripheral Interrupt Enable bit
      SSPIE = 1;  // Synchronous Serial Port Interrupt Enable bit
      GIE = 1;    //global interrupt enable
    
      SSPIF = 0;      // clear SSPIF interrupt flag
    
      while(1)
      {
      }
    }
    Wenn alles funktionieren würde, dann würde zumindest erstmal die Interrupt-Routine des Slave aufgerufen. Dort sollten dann die Ausgänge RB0, RB1 und RB2 auf high gezogen werden. Das passiert aber leider nicht. Hat evtl. jemand eine Idee was ich falsch mache? Ich bin schon wieder ein bißchen verzweifelt.

    mfg
    Sebastian

  2. #2
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.836
    Mich nur oberflächlich mit PIC und I2C beschäftigt:

    Woher weiß der Slave, daß er die Adresse FE hat ? Das gehört doch ins SPADD ? Oder nicht ?
    mfg robert
    Wer glaubt zu wissen, muß wissen, er glaubt.

Berechtigungen

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