Forum: Mikrocontroller und Digitale Elektronik Verständnisfrage TWI (I2C) Routine


von Maxim (Gast)


Lesenswert?

Hallo Leute,

ich bin noch relativ neu im Thema µC, aber ich habe mich auf die 
"Forschung" von I2C Bus gestürzt.
Im der Codesammlung bin ich auf den folgenden Beitrag gestoßen:
Beitrag "AVR TWI Master und Slave Funtionen in C"

Diesen Code habe ich runter gezogen und versuche es jetzt zu verstehen, 
leider gibt es paar Stellen wo ich nicht weiter komme.

Könnte mir jemand auf die Sprünge helfen?
>>>Das ist die Slave Routine:
>while (1)
>    {
>/*
>** Check wether something is to do for the TWI slave interface
>*/
>    if (TWIS_ResonseRequired (&TWIS_ResonseType))
>      {
>      switch (TWIS_ResonseType)
>        {
>/*
>** Slave is requests to read bytes from the master.
>** It is expliciltely assumed, that the master sends 8 bytes
>*/
>        case TWIS_ReadBytes:
>          for (i=0;i<7;i++)
>            {
>            byte[i] = TWIS_ReadAck ();
>            printf ("Byte read: >%d\n",byte[i]);
>            }
>          byte[7] = TWIS_ReadNack ();
>          printf ("Byte read: %d\n",byte[7]);
>          TWIS_Stop ();
>          break;
>/*
>** Slave is requested to send bytes to the master.
>** It is expliciltely assumed, that the master expects 8 bytes
>*/
>        case TWIS_WriteBytes:
>          for (i=0;i<8;i++)
>            {
>            TWIS_Write (j++);
>            printf ("Byte sent:  %d\n", >j-1);
>            }
>            TWIS_Stop ();
>          break;
>        }
>      }
>/*
>** Do something else, e.g.
>*/
>    i++;
>    }

Die erste If Schleife macht mir Sorgen
-->if (TWIS_ResonseRequired (&TWIS_ResonseType))<--
Wenn ich es richtig verstehe wird hier die Funktion 
"TWIS_ResonseRequired" aufgerufen und dem Pointer in der Funktion die 
Variable
-->(&TWIS_ResonseType)<-- übergeben.

Wenn ich mir jetzt aber die Funktion anschaue verstehe ich das ganze 
nicht so ganz.

>uint8_t  TWIS_ResonseRequired (uint8_t *TWI_ResonseType)
>  {
>  *TWI_ResonseType = TWSR;
>  return TWCR & (1<<TWINT);
>  }

Die Variable TWIS_ResonseType wird im Kopfteil deklariert, es wird aber 
kein Wert zugewiesen also hat die Variable den Wert Null.
Also steht hier (uint8_t *TWI_ResonseType) eine Null.
Und jetzt kommt das was ich nicht verstehe, wieso wird jetzt dem Pointer
den Statuswert zugewiesen?
Anschließend wird der Funktion der Status von TWINT zurück übergeben.



>>>Jetzt kommen wir zu der Master Routine:
>while (1)
>    {
>/*
>** Read byte(s) from the slave.
>** It is implicitely assumed, that the slave will send
>** 8 bytes
>*/
>      if (!TWIM_Start (SlaveAddress, TWIM_READ)) //Lesen=1
>      {
>      TWIM_Stop ();
>    //  printf ("Could not start TWI Bus for READ\n");
>        }
>    else
>      {
>      for (i=0;i<7;i++)
>        {
>            Data[i] = TWIM_ReadAck ();
>      //  printf ("Reading Byte %d: %d\n", i, >Data[i]);
>        }
>          Data[7] = TWIM_ReadNack ();
>      //printf ("Reading Byte %d: %d\n", i, Data[7]);
>      TWIM_Stop ();
>      Delay_ms (1000);
>      }
>/*
>** Write byte(s) to the slave.
>** It is implicitely assumed, that the slave will
>** accepts 8 bytes
>*/
>      if (!TWIM_Start (SlaveAddress, TWIM_WRITE)) //Schreiben=0
>      {
>      TWIM_Stop ();
>      //printf ("Could not start TWI Bus for WRITE\n");
>        }
>    else
>      {
>      for (i=0;i<8;i++)
>        {
>            TWIM_Write (j++);
>        //printf ("Byte %d sent: %d\n", i, j);
>        }
>      TWIM_Stop ();
>      Delay_ms (1000);
>      }
>/*
>** Do something else
>*/
>    i++;
>    }

Hier sehen wir eine Immerschleife wo gleichzeitig eine Sende und eine 
Empfangsroutine aufgerufen werden.
Warum wird es gleichzeitig aufgerufen?

Ich hoffe mir kann jemand helfen.

von Timo P. (latissimo)


Lesenswert?

Wo wird denn die Variable angelegt? Sicherlich bei den 
Initialisierungen.
Diese zeigst du hier nicht...

übrigens wird erst gelesen, dann(also zeitlch gesehen danach) wird erst 
geschrieben. Die Funktionsaufrufe passieren NICHT gleichzeitig!

von Maxim (Gast)


Lesenswert?

Sorry, du hast natürlich Recht, dass es nach einander aufgerufen wird.
Was ich meinte ist, dass da nicht irgendwie nach den Daten abläuft...
Daten vorhanden??-->Senden


>>>OK hier ist die komplette Slave Routine:

#include <stdio.h>
#include <avr/interrupt.h>

#include "General.h"
#include "RS232.h"
#include "Delay.h"
#include "TWI_Slave.h"
/*
** This main programm demonstrates how to use the
** implemented TWI slave functions. These are:
**  TWIS_Init
**  TWIS_ReadAck
**  TWIS_ReadNack
**  TWIS_Write
**  TWIS_Stop
**  TWIS_ResonseRequired
**
** For testing this program, use the program
** TWI_Master_main.c in the slave uC and connect the
** two TWI lines properly (don't forget to also
** connect GND between Master and Slave!)
**
** Used uC for Slave is ATMega8
*/
int main (void)
  {
  uint8_t    i=0;
  uint8_t    j=0;
  uint8_t    byte[8];
  uint8_t    TWIS_ResonseType;
/*
** Clear any interrupt
*/
  cli ();
/*
** Wait 1 second for POR
*/
  Delay_ms (500);
/*
** Initiate RS232
*/
  RS232_Init ();
  printf ("Hello world...\n");
/*
** Start TWI Slave with address 15 and bitrate of 100000 Hz
*/
  TWIS_Init (15, 100000);

  while (1)
    {
/*
** Check wether something is to do for the TWI slave interface
*/
    if (TWIS_ResonseRequired (&TWIS_ResonseType))
      {
      switch (TWIS_ResonseType)
        {
/*
** Slave is requests to read bytes from the master.
** It is expliciltely assumed, that the master sends 8 bytes
*/
        case TWIS_ReadBytes:
          for (i=0;i<7;i++)
            {
            byte[i] = TWIS_ReadAck ();
            printf ("Byte read: %d\n",byte[i]);
            }
          byte[7] = TWIS_ReadNack ();
          printf ("Byte read: %d\n",byte[7]);
          TWIS_Stop ();
          break;
/*
** Slave is requested to send bytes to the master.
** It is expliciltely assumed, that the master expects 8 bytes
*/
        case TWIS_WriteBytes:
          for (i=0;i<8;i++)
            {
            TWIS_Write (j++);
            printf ("Byte sent:  %d\n", j-1);
            }
            TWIS_Stop ();
          break;
        }
      }
/*
** Do something else, e.g.
*/
    i++;
    }
  return 0;
  }

von Maxim (Gast)


Lesenswert?

Kann mir den keiner helfen? oder ist die Frage zu blöd?

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.