www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik PIC32 mit verschiedenen I2C Kanälen


Autor: Alexander Conrad (alexc)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich programmiere einen PIC32MX795F512H und verwende die I²C 
Schnittstelle.
Den zu nutzenden I²C Kanal habe ich als globale Variable innerhalb des 
Codes festgelegt.
Wenn ich den Kanal 'I2C1' verwende funktioniert alles wie gewollt. 
Leider ist dieser Pin durch andere Peripherie schon belegt und ich 
möchte auf einen anderen Kanal ausweichen. Verwende ich also nun z.B. 
'I2C2A' stattdessen, so funktioniert nichts mehr.

Am Code ändere ich also nichts, nur diese Variable.

Hat jemand ein ähnliches Problem schon ein mal gehabt und eine passable 
Lösung gefunden?

Ich freue mich auf eure Kommentare.


// some definitions
#define SYS_FREQ    (20000000L)
#define PB_FREQ      (5000000L)      //=SYS_FREQ/FPBDIV
#define I2C_CLOCK_FREQ  (100000L)
#define nbr_ms_cycles  (1E-3 * SYS_FREQ)  //1ms / T = n = 1ms *f 
#define i2cchn      I2C2A        //I2C channel at Pins 5,6

#define BRG_VAL     ((PB_FREQ/2/I2C_CLOCK_FREQ)-2)

/* my scratchpad for I2C channel enumeration: - I2C name
 *
 *          chn   :  I2C1A
 *          chn   :  I2C2A
 *          chn   :  I2C3A
 *          chn 3  :  I2C1
 *          chn   :  I2C2
 */ 


/** 
  * The main function does a loop forever, until it gets manually stopped or an error occured.
  * \return This is a program for a microcontroller. There exists no return value, because there exists no operating system.
  */
int main(void)
{  
  DBINIT();// Initialize debug messages (when supported)

  //disable the I2C port before reconfiguring and starting again ???
  I2CEnable(i2cchn, FALSE);
    
  //*Configure
  I2CConfigure(i2cchn, I2C_ENABLE_SLAVE_CLOCK_STRETCHING);
  
  //*SetFrequency
  int actualClock = I2CSetFrequency(i2cchn, PB_FREQ, I2C_CLOCK_FREQ);
  if ( abs(actualClock-I2C_CLOCK_FREQ) > I2C_CLOCK_FREQ/10 )
  {
     DBPRINTF("I2C clock frequency (%ld) error exceeds 10%%\n", actualClock);
  }

  //do the work around taken from the errata sheet
  LATGbits.LATG7=0;
  TRISGbits.TRISG7=0;

  //*Enable I2C  
  I2CEnable(i2cchn, TRUE);
  
  int result;

  while(1)
  {  
    //check if the I2C bus is idle
    if (I2CBusIsIdle(i2cchn))
    {
      //send a START condition
      result = I2CStart(i2cchn); 
    }
    
    //send '0001010' to the bus, in write mode
    int data = (0xA<<1) | 0; 
    if (I2CTransmitterIsReady(i2cchn))
    {
      result = I2CSendByte(i2cchn, data);
      
      //wait for the transmission to complete
      while(!I2CTransmissionHasCompleted(i2cchn));
      if (I2CTransmissionHasCompleted(i2cchn))
      {
        DBPRINTF("All the data was sucessfully written to the I²C bus.");
        if (I2CByteWasAcknowledged(i2cchn))
        {
          DBPRINTF("Slave has acknowledged the recieved data.");
          //data send to the Slave is valid, now other operations can follow
          
        }
      }
    }    
    I2CStop(i2cchn); //finally send a STOP condition
  }
}

Autor: Sebastian Hepp (sebihepp)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hast du den Workaround in deinem Code angepasst?
  //do the work around taken from the errata sheet
  LATGbits.LATG7=0;
  TRISGbits.TRISG7=0;

Autor: Alexander Conrad (alexc)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke für die schnelle Antwort!

Ja, das habe ich auch im Code angepasst. Die hier gesetzten Bits G7 und 
G8 beeinflussen die zu I2C2A zugehörigen Pins SDA2A und SCL2A. Somit 
stimmt meine obige Aussage nicht ganz exakt.
Bei I2C1 funktionierte es bisher auch ohne den work around. Warum auch 
immer?

Autor: Alexander Conrad (alexc)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Falls es jemand wissen möchte. Das ganze funktioniert dann, wenn man 
Zahlen anstelle der Namen für die I2C Schnittstellen verwendet. Der 
Parameter heisst demnach:

  *I2C channel enumeration and I2C names
  * 0    ->  I2C1A
  * 1    ->  I2C2A
  * 2    ->  I2C3A
  * 3    ->  I2C1
  * 4    ->  I2C2

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.