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


von Alexander C. (alexc)


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.


1
// some definitions
2
#define SYS_FREQ    (20000000L)
3
#define PB_FREQ      (5000000L)      //=SYS_FREQ/FPBDIV
4
#define I2C_CLOCK_FREQ  (100000L)
5
#define nbr_ms_cycles  (1E-3 * SYS_FREQ)  //1ms / T = n = 1ms *f 
6
#define i2cchn      I2C2A        //I2C channel at Pins 5,6
7
8
#define BRG_VAL     ((PB_FREQ/2/I2C_CLOCK_FREQ)-2)
9
10
/* my scratchpad for I2C channel enumeration: - I2C name
11
 *
12
 *          chn   :  I2C1A
13
 *          chn   :  I2C2A
14
 *          chn   :  I2C3A
15
 *          chn 3  :  I2C1
16
 *          chn   :  I2C2
17
 */ 
18
19
20
/** 
21
  * The main function does a loop forever, until it gets manually stopped or an error occured.
22
  * \return This is a program for a microcontroller. There exists no return value, because there exists no operating system.
23
  */
24
int main(void)
25
{  
26
  DBINIT();// Initialize debug messages (when supported)
27
28
  //disable the I2C port before reconfiguring and starting again ???
29
  I2CEnable(i2cchn, FALSE);
30
    
31
  //*Configure
32
  I2CConfigure(i2cchn, I2C_ENABLE_SLAVE_CLOCK_STRETCHING);
33
  
34
  //*SetFrequency
35
  int actualClock = I2CSetFrequency(i2cchn, PB_FREQ, I2C_CLOCK_FREQ);
36
  if ( abs(actualClock-I2C_CLOCK_FREQ) > I2C_CLOCK_FREQ/10 )
37
  {
38
     DBPRINTF("I2C clock frequency (%ld) error exceeds 10%%\n", actualClock);
39
  }
40
41
  //do the work around taken from the errata sheet
42
  LATGbits.LATG7=0;
43
  TRISGbits.TRISG7=0;
44
45
  //*Enable I2C  
46
  I2CEnable(i2cchn, TRUE);
47
  
48
  int result;
49
50
  while(1)
51
  {  
52
    //check if the I2C bus is idle
53
    if (I2CBusIsIdle(i2cchn))
54
    {
55
      //send a START condition
56
      result = I2CStart(i2cchn); 
57
    }
58
    
59
    //send '0001010' to the bus, in write mode
60
    int data = (0xA<<1) | 0; 
61
    if (I2CTransmitterIsReady(i2cchn))
62
    {
63
      result = I2CSendByte(i2cchn, data);
64
      
65
      //wait for the transmission to complete
66
      while(!I2CTransmissionHasCompleted(i2cchn));
67
      if (I2CTransmissionHasCompleted(i2cchn))
68
      {
69
        DBPRINTF("All the data was sucessfully written to the I²C bus.");
70
        if (I2CByteWasAcknowledged(i2cchn))
71
        {
72
          DBPRINTF("Slave has acknowledged the recieved data.");
73
          //data send to the Slave is valid, now other operations can follow
74
          
75
        }
76
      }
77
    }    
78
    I2CStop(i2cchn); //finally send a STOP condition
79
  }
80
}

von Sebastian H. (sebihepp)


Lesenswert?

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

von Alexander C. (alexc)


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?

von Alexander C. (alexc)


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

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.