Forum: Mikrocontroller und Digitale Elektronik TWI/I2C Master is blocking?


von Sven (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,
ich bin gerade dabei mehrere avr controller mittels twi/i2c zu 
verbinden.
Dabei gibt es einen Master und jeweils einen Slave Receiver und einen 
Slave Transmitter.
Ich habe das Problem das der Master blockiert, wenn dieser Daten vom 
Slave abfragt. Dies kann ich aber nicht zulassen. Ich habe schon 
verschiedenste Library's ausprobiert (mit interrupt und ohne) leider 
funktionieren diese mit interrupt überhaupt nicht bei mir.

Im Anhang ist die derzeitige Version die soweit erstmal funktioniert. 
Gibt es eine Möglichkeit diese so anzupassen, dass der Master nicht mehr 
blockiert wenn er Daten ließt?

Danke
Sven

von Peter D. (peda)


Lesenswert?

Sven schrieb:
> Ich habe das Problem das der Master blockiert, wenn dieser Daten vom
> Slave abfragt.

Liegt meisten daran, daß Du das I2C-Protokoll verletzt.
Der Master muß das letzte Byte mit NACK beantworten.
Sonst kann er kein Stop senden.


Peter

von Sven (Gast)


Lesenswert?

Wenn ich deine Antwort richtig deute, glaubst du, dass der Master die 
Slaves zum blockieren bringt. Dies ist aber nicht der Fall. Der Master 
blockiert wenn er Daten vom Slave abfragt!

Beim Master sieht das so aus.
1
    if( !TWIM_Start( TWI_ADRESS_SENSORBOARD, TWIM_READ) )
2
  {
3
        TWIM_Stop();
4
        return;
5
     }
6
7
    for( i = 0; i < max_bytes_read-1; i++)
8
    {
9
        int twi_read = TWIM_ReadAck();
10
        if( twi_read == -1 )
11
        {
12
            TWIM_Stop();
13
            return;
14
        }
15
        buf[i] = (unsigned char)twi_read;
16
  }
17
    buf[i] = TWIM_ReadNack();
18
  TWIM_Stop();

Blockiert wird der Master beim Aufruf von TWIM_ReadAck()

Beim Slave sieht das ganze so aus
1
void twi_putc_len(unsigned char *s, short len)
2
{
3
    uint8_t  TWIS_ResponseType;
4
  while( 1 )
5
    {
6
        if( TWIS_ResonseRequired( &TWIS_ResponseType ) )
7
    {
8
      if( TWIS_ResponseType == TWIS_WriteBytes )
9
            {
10
        for(int i = 0; i < len; i++)
11
        {                   
12
                    TWIS_Write( s[i] );
13
        }
14
        TWIS_Stop();
15
        return;
16
      }
17
    }
18
  }
19
}
20
21
...
22
main
23
...
24
25
    while( 1 )
26
    {
27
...
28
        twi_putc_len( (unsigned char*)&packet, sizeof(struct Packet) );
29
        _delay_ms(2000);
30
    }

Das heißt der slave wartet immer 2 Sekunden. Und diese Zeit wartet der 
Master auch.

Gibt es hier eine Möglichkeit dies zu umgehen?

Danke
Sven

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.