Forum: Mikrocontroller und Digitale Elektronik [dsPIC33E] I2C Masterinterrupt wird nicht ausgelöst


von Christian K. (studentchrisk)


Lesenswert?

Hey,
ich möchte einen Chip von TI via I2C ansprechen.
Da ich bisher noch nicht damit gearbeitet habe, hab ich mir den 
Beispielcode von Microchip runtergeladen 
(http://www.microchip.com/wwwproducts/Devices.aspx?dDocName=en559417)und 
ihn auf meinen Chip angepasst, Adresse vom Chip und BRG-Register auf 
100kHz.

Mein Problem ist, dass er nachdem er die Startbedingung 
(I2C1CONbits.SEN=1;) gesetzt hat keinen Masterinterrupt auslöst.
die Loop meiner Main
1
 while(1)
2
  {
3
    if(enable==1) 
4
    {
5
      enable=0;
6
      // Write Data
7
                        
8
      i2cmem.oData=&wData;
9
      i2cmem.cmd = I2C_WRITE;  
10
                        
11
      while(i2cmem.cmd!=I2C_IDLE )
12
        {
13
        i2cmem.tick(&i2cmem); 
14
      }
15
16
      // Read Data
17
      i2cmem.oData=&rData;
18
      i2cmem.cmd = I2C_READ;
19
      while(i2cmem.cmd!=I2C_IDLE)
20
        {
21
        i2cmem.tick(&i2cmem); 
22
      }
23
    }
24
  };

und der Anfang der Funktion die die Kommunikation übernehmen soll
1
void I2CEMEMdrv(I2CEMEM_DRV *i2cMem)
2
{
3
4
static int state=0, cntr=0, rtrycntr=0;
5
6
    switch(state)
7
    {
8
    case 0: 
9
        if( (i2cMem->cmd == I2C_WRITE)  || (i2cMem->cmd == I2C_READ)  ) 
10
      state=1;   
11
          
12
        break;
13
14
  /*==================================*/        
15
  /* Control/Address Phase      */
16
  /*==================================*/
17
    case 1:
18
    // Start Condition
19
    I2C1CONbits.SEN=1;
20
    state=state+1;
21
        break;
22
23
24
    case 2:
25
        // Start Byte with device select id
26
      if(jDone==1)  { 
27
                jDone=0;
28
            state=state+1;
29
      I2C1TRN=(0x00A0)|(((i2cMem->oData->csel)&0x7)<<1);
30
    }
31
        break;
Muss ich noch irgend eine Library hinzufügen damit es funktioniert?
Den gesamten Code findet man unter Dokumentation und Software auf der 
Microchip Seite!
Wenn jemand eine Idee hat wieso der Interrupt nicht ausgelöst wird wäre 
ich sehr dankbar!

Grüße
Chris

von Florian T. (florian_t91)


Lesenswert?

Arbeitest du mit c++? Welchen Compiler verwendest du dazu?
Habe leider i2c Schnittstelle noch nicht getestet. Aber mit Interrupts 
arbeiten wäre wohl besser.

von Bronco (Gast)


Lesenswert?

Mußt Du denn nicht irgendwo die Funktion
1
void I2CEMEMdrv(I2CEMEM_DRV *i2cMem)
aus deiner Hauptschleife aufrufen?

von Christian K. (studentchrisk)


Lesenswert?

Hey,
als Compiler benutze ich den XC16 und benutz c.

ja den Teil hab ich jetzt nicht mit in den angezeigten Code gemacht 
sorry.
1
// EEPROM DRIVER OBJECT
2
typedef struct { 
3
        unsigned int  cmd; 
4
    I2CEMEM_DATA  *oData;          
5
        void (*init)(void *);                   
6
        void (*tick)(void *); 
7
        }I2CEMEM_DRV; 
8
    
9
#define I2CSEMEM_DRV_DEFAULTS { 0,\
10
        (I2CEMEM_DATA *)0,\
11
        (void (*)(void *))I2CEMEMinit,\
12
        (void (*)(void *))I2CEMEMdrv}

und aus der main.c
1
// Instantiate Drive and Data objects
2
I2CEMEM_DRV i2cmem= I2CSEMEM_DRV_DEFAULTS;
3
I2CEMEM_DATA wData;
4
I2CEMEM_DATA rData;

ich bin inzwischen so weit das ich weiß, dass der Interrupt nicht 
ausgelöst wird weil die Startbedingung vom I2C nicht erfüllt wird.
Über ODCx werden die Pins als Open Drain ja gesetzt, beim Foren 
durchstöbern hab ich gelesen, dass man die TRIS Register auch als Output 
setzen muss damit der Pin als Open Drain fungiert.
Allerdings hab ich dann das Problem das sowohl die SDA als auch SCL 
Leitung standartmäßig auf Masse liegen, was nicht seien darf weil im 
IDLE-Modus müssen sowohl SDA als SCL high sein. (wenn ich sie über das 
LAT-Register dann auf high setze funktioniert es auch nicht)

von Michael K. (Gast)


Lesenswert?

Hatte mal beim IIS Port eines DS das Problem das der Port nur teilweise 
funktionierte. Sehr kurios, habe unendliche Stunden darin versenkt.
Lösung: Der nicht benutze AD-Wandler, der die IIS Port Pins hätte 
benutzen können, musste explizit auf digital in gestellt werden.

Schau Dir mal an was noch auf den Pins liegen könnte und geh das Stück 
für Stück durch.

TRIS bits ...
Sicher das die dann auf Masse liegen ?
Es müssen normalerweise nur bestimmte Bedingungen erfüllt sein damit die 
Hardware (hier IIC) die Kontrolle über die Port Pins übernehmen darf.
Das heißt nicht zwangsläufig das die Port Pins dann das tun was in den 
Port Pin Registern steht.

von Christian K. (studentchrisk)


Lesenswert?

also auf den Pins liegt noch SPI und SPO sowie JTAG... hab beides 
disabled aber es funktioniert immer noch nicht!
was ich grad versucht habe
1
// Start Condition
2
    I2C1CONbits.SEN=1;
3
                if (I2C1STATbits.S==1){
4
                    LATAbits.LATA0=1;
5
                }
sprich nachdem ich die Startbedingung initialisiert hab zu gucken ob das 
Statusbit gesetzt ist, welches für die Startbedingung zuständig ist.
Es ist nicht gesetzt.

von Christian K. (studentchrisk)


Lesenswert?

okay Problem gelöst.
man musste im
1
_FPOR (ALTI2C1_ON);
die Pins noch mappen. Das fehlt in dem Beispielcode von Microchip 
einfach!

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.