www.mikrocontroller.net

Forum: Compiler & IDEs Suche einfaches TWI Beispiel


Autor: Mario (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hi,
ich muss für ein Projekt mehrere Atmega vernetzen. Ich habe gelesen, 
dass sich der TWI bus dafür eignet. Ich möchte nur einen Wert von einem 
µC in einen anderen Schreiben. Also ich sende mit dem Master z.B.

Start
Variablennamen
VariablenWert
Ende

und der Slave soll das empfangen und entsprechend speichern. Um die 
auswertung soll es hier nicht gehen, sondern nur wie ich via twi senden 
und empfangen kann.

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Anbei eine einfache Polled-Mode Lösung für eine TWI-Master Anwendung. 
(Für TWI-Slave empfehle ich den ISR-Modus zu nutzen, da die SW nicht die 
Zeit  damit verbraten sollte, ständig auf ein TWI-Ereigniss warten zu 
müssen.

[c]
#include <avr/interrupt.h>
#include <util/twi.h>

//-------------------------------------------
// Definition of local constants
//-------------------------------------------

// master transfer acknowledge for address or data
#define TW_MT_ACK (u08)0x08

//-------------------------------------------
// Function Prototypes
//-------------------------------------------
void TWI_init(void);
void TWI_read (u08 TWI_adr, u08 *val, u08 count);
void TWI_write(u08 TWI_adr, u08 *val, u08 count);

//--------------------------------------------------------
// Intialize the I2C-Bus Interface
// as Master with SCL 100kHz, non interrupt driven
//--------------------------------------------------------

void TWI_init(void)
{
  //--------------------------------------------------------
  // SCL frequency: 102.400 kHz (F_CPU = 7.3728 MHz)
  // SCL = F_CPU/(16+2*TWBR*4^TWSR)
  //--------------------------------------------------------
  TWBR = 0x1C;                 // TWI-datrate divider = 28
  TWSR = 0x00;                 // TWI-clock prescaler = 1
  TWCR = (1<<TWEA)|(1<<TWEN);  // no interrupt mode
}



void TWI_read(u08 TWI_adr, u08 *val, u08 count)
//------------------------------------------------
// Read n=count bytes from I2C-Bus in polled mode
// needs about 200us for reading addr + one byte
//------------------------------------------------
{
  u08 i=0;
  TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);     // send START condition
  while (!(TWCR & (1<<TWINT)));               // wait for response
  if ((TWSR & 0xF8) == TW_START)              // if START was successful
  {
    TWDR = (TWI_adr | 0x01);                  // put slave address+READ 
to TWDR
    TWCR = (1<<TWINT)|(1<<TWEN);              // and start transmission
    while (!(TWCR & (1<<TWINT)));             // wait for response
    if ((TWSR & 0xF8) == TW_MR_SLA_ACK)       // if acknowledge ok
    {
      count--;
      while (count>i)                         // while more than one 
byte to read
      {
        TWCR=(1<<TWINT)|(1<<TWEA)|(1<<TWEN);  // then start transfer 
with acknowledge
        while (!(TWCR & (1<<TWINT)));         // wait for response
        val[i++]=TWDR;                        // read databyte from TWDR
      }
      TWCR=(1<<TWINT)|(1<<TWEN);              // start last byte 
transfer without acknowledge
      while (!(TWCR & (1<<TWINT)));           // wait for response
      val[i]=TWDR;                            // read databyte from TWDR
    }
    else
    {
      UART0_putl_I("Error: I2C[R] Addr");
    }
  }
  else
  {
    UART0_putl_I("Error: I2C[R] Start");
  }
  TWCR = (1<<TWINT)|(1<<TWSTO)|(1<<TWEN);      // transmit STOP 
condition
  delay_us(10);                                // wait until STOP is 
transmitted
}



void TWI_write(u08 TWI_adr, u08 *val, u08 count)
//------------------------------------------------
// write n=count bytes to I2C-Bus in polled mode
// needs about 200us for writing Addr + one byte
//------------------------------------------------
{
  TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);   // send START condition
  while (!(TWCR & (1<<TWINT)));             // wait for response
  if ((TWSR & 0xF8) == TW_START)            // if START was successful
  {
    TWDR = (TWI_adr & 0xFE);                // put slave address+WRITE 
to TWDR
    TWCR = (1<<TWINT)|(1<<TWEN);            // and start transmission
    for (u08 i=0; i<count; i++)
    {
      while (!(TWCR & (1<<TWINT)));         // wait for response
      if ((TWSR & 0xC8) == TW_MT_ACK)       // if acknowledge ok
      {
        TWDR = val[i];                      // put databyte  to TWDR
        TWCR = (1<<TWINT)|(1<<TWEN);        // and start transmission
      }
      else
      {
        UART0_putl_I("Error: I2C[W] Data");
      }
    }
  }
  else
  {
    UART0_putl_I("Error: I2C[W] Start");
  }
  while (!(TWCR & (1<<TWINT)));             // wait for response
  TWCR = (1<<TWINT)|(1<<TWSTO)|(1<<TWEN);   // transmit STOP condition
  delay_us(10);                             // wait until STOP is 
transmitted
}
[\c]

Autor: Torsten K. (avr_fan)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Mario,

schau Dir mal die Quellen unter folgendem Link an.
Damit kann man sehr einfach eine Kommunikation über die TWI aufbauen.

Beitrag "AVR TWI Master und Slave Funtionen in C"

Gruss Torsten

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.