Forum: Compiler & IDEs I2C (TWI) : Wie lang wartezeit zwischen lese- und schreibzyklus?


von M. H. (dbzwerg)


Angehängte Dateien:

Lesenswert?

Hallo,

ich benutze für mein Projekt die I2C-lib von jtronics um daten zwischen 
einem Mega 8 und mega1284 auszutauschen.

Nun habe ich festgestellt wenn ich vom master einen write zyklus und 
direkt danach einen read Zyklus starte empfang  ich vom slave "müll" 
...wenn ich aber einen kleinen delay zwischen die beiden zyklen setze 
sind die daten in ordnung.

Ist dies normal d.h. nach jedem write befehl muss ich eine gewisse Zeit 
"pause machen"? Falls ja wie lang sollte die wartezeit betragen?

anbei die I2C libs vom master sowie slave , sowie meine lese und schreib 
funktionen die ich daraus gebastelt habe...

MFG


Erstmal die Codezeile die mir Probleme macht
1
....
2
3
4
        // Auslesen des vom Bediener gewählten CC-Modus
5
         
6
          return_ccc = Read_CCC(CCC_ADRESSE, CCC_SET_NEW_MODE);
7
          
8
          if ( return_ccc == TRUE)    // Wurde neuer Modus ausgewählt?
9
          {
10
            uart_puts("----> daten schreiben:\t");
11
            send_int_uart(CCC_ADRESSE);
12
            uart_puts("\t");
13
            send_int_uart(CCC_SET_NEW_MODE);
14
            uart_puts("\t");
15
            send_int_uart(TRUE);
16
            uart_puts("\n\r");
17
            
18
            Write_CCC(CCC_ADRESSE,CCC_SET_NEW_MODE,TRUE);   // Status in den CCC Empfangsbuffer schreiben            
19
/* ohnes dieses delay gibt es fehler--->*/            _delay_ms(1);
20
            cc_mode = Read_CCC(CCC_ADRESSE, CCC_MODE);     // Neuen VM übernehmen
21
            Write_CCC(CCC_ADRESSE,CCC_SET_NEW_MODE,FALSE);     // Status in den CCC EMpfangsbuffer schreiben
22
            
23
            uart_puts("---->  Neuer CC-Modus empfangen:\t");
24
            send_int_uart(cc_mode);
25
            uart_puts("\n\r"); 
26
          }
27
....



1
/*********************************************************************
2
Funktionsname:         Read_CCC
3
FUnktion:          Liest Daten von CCC aus 
4
Übergabeparamter:      CCS Adresse, Datenposition im CCS Speicher
5
Rückgabe wert (uchar):    Ausgelesenes Datenbyte
6
7
**********************************************************************/    
8
      unsigned char Read_CCC(unsigned char ADDR, unsigned char CMD) 
9
      {   
10
        int data =0;
11
        int connect = 0;
12
        connect = i2c_start(ADDR+I2C_WRITE);   // set device address and write mode
13
        
14
        if(connect == 0)
15
        {
16
          i2c_write(CMD);                 // write command, sendet Startpostion der Leseadresse an Slave
17
    
18
          i2c_rep_start   (ADDR+I2C_READ);   // Repeated Start
19
        
20
          data = i2c_readNak();      // Liest akutelle Bufferposition vom Slave aus und schrebit sie in die variable "ccs_data"
21
          i2c_stop();            // set stop conditon = release bus
22
          
23
          return data;            // Gibt das gelesene Byte an funktion zurück
24
        }
25
        else
26
        {
27
          i2c_stop();  
28
        }
29
      }      
30
      
31
32
/*********************************************************************
33
Funktionsname:         Write_CCC
34
FUnktion:          Sendet  Daten an den CCC 
35
Übergabeparamter:      CCS Adresse, Datenposition im CCS Speicher , Datenbyte
36
Rückgabe wert (uchar):    Fehlercode( 0 = ok, sonst Fehler(siehe TWSTim Datenblatt)
37
38
**********************************************************************/
39
    unsigned char Write_CCC(unsigned char ADDR, unsigned char CMD, unsigned char DATA) 
40
        {
41
          int ret = 0xff;
42
          ret= i2c_start(ADDR+I2C_WRITE);   // set device address and write mode
43
    
44
          if ( ret == 0) 
45
          {
46
            ret = i2c_write(CMD);                 // write command
47
            ret = i2c_write(DATA);                  // write data
48
            i2c_stop();                         // set stop conditon = release bus
49
          }  
50
          else
51
          {
52
              // check value of TWI Status Register. Mask prescaler bits.
53
            ret = TW_STATUS & 0xF8;
54
            i2c_stop();  
55
56
          }
57
          return (ret);
58
        }

von Peter D. (peda)


Lesenswert?

Der Master muß natürlich nach jedem Byte schreiben (Adresse, Daten) auf 
ACK prüfen.

Das HV-I2C der AVRs hat leider auch diverse Bugs.
Bei 100kHz ist eine Pause 4,7µs zwischen Stop und Start vorgeschrieben, 
die hält der AVR nicht von selber ein.
Solange der Slave den Stop-Interrupt nicht gelöscht hat, geht ihm ein 
neues Start durch die Lappen.
Und als Multimaster kann das HV-I2C richtig abstürzen und muß disabled 
werden.

Das HW-I2C der Atmel 8051 hat auch Fehler.
Nur das HW-I2C der Philips 8051, also das Original ist fehlerfrei.

Programmtechnisch sehen diese 3 HW-I2C identisch aus (Register, Bits, 
Abläufe), aber intern sind sie es nicht. Da haben die bei Atmel beim 
Nachentwickeln des Philips-I2C geschlampt.

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.