www.mikrocontroller.net

Forum: Codesammlung AVR TWI Master und Slave Funtionen in C

Autor: Manni (Gast)
Datum: 04.01.2008 21:51
Dateianhang: TWI_Master-Slave_C_Functions.zip (15,8 KB, 604 Downloads)

Hallo,

anbei relativ einfache AVR TWI Funktionen in C für die Kommunikation
zwischen zwei uC. Für den Master habe ich den ATMega32 und den Slave
ATMega8 verwendet. Sollte aber auch auf anderen ATMegas laufen, sofern
das TWI implementiert ist. Hab's aus diversen Sourcen aus diesem Forum
abgeleitet. Da die Funktionen entsprechend dokumentiert sind, sollte die
Nutzung relativ einfach sein.

Die Funktionen können als Basis verwendet werden, um ein entsprechendes
Protokoll zwischen den beiden uC aufzubauen.

Vielleicht kann's jemand brauchen, da ich dies in der Form noch nicht im
Forum gefunden habe.

Als AddOn gibt's noch eine Funktionssammlung für das serielle Interface
und Delay-Routinen (Delay_ms(x) und Delay_us (x)).

Gruss
Manni
Autor: Bernhard Schulz (bernhard)
Datum: 04.01.2008 22:10

Hallo Manni,

das scheint das Gegenstück zu meinem Assembler - Beispiel zu sein ;)

Beitrag "TWI / I2C einf. MASTER SLAVE Beispiel(Assembler) ATmega8"


Bernhard
Autor: Manni (Gast)
Datum: 04.01.2008 22:16

Mag sein.

Hab's aber aus diversen C Quellen zusammengesetzt. Die Master Quelle
kommt von Peter Fleury <pfleury@gmx.ch>. Da es die C Source für den
Slave bei Fleury nicht gibt (er steuert I2C ICs an) habe ich sie in
ähnlicherweise aufgebaut.

Dein Assembler Beispiel habe ich gesehen, wollte aber nicht wieder auf
ASM zurückfallen --> Gewohnheitsfaktor.

Manni
Autor: Torsten K. (avr_fan)
Datum: 19.01.2008 02:18

Hallo Manni,

ich hab mir deine TWI_Functions mal runtergeladen und ausgetestet. Für
den TWI_Master gibt es ja jede Menge an Vorlagen, aber beim TWI_Slave
für den AVR sieht es ja eher bescheiden aus (zumindest in C). Da ich
aber nun mehrere AVR miteinander verbinden muß, ist das genau das
richtige. Bei mir läuft die Kommunikation problemlos und stabil, ich
werde jetzt mal auf der Basis ein Protokoll aufsetzen, um entsprechende
Befehle zwichen den Controllern austauschen zu können.

Viele Grüsse
Torsten
Autor: neuer (Gast)
Datum: 21.01.2008 16:37

ist das ein schreibfehler in deiner datei oder dauern 500ms bei dir im
programm tatsächlich 1 sec.


/*
** Wait 1 second for POR
*/
  Delay_ms (500);
Autor: neuer (Gast)
Datum: 21.01.2008 18:44

2 bascom routinen die man leicht in winavr-c umsetzen kann.
kurz-funktionsfähig und einfach im händling.
-twi-master send-empfang
-twi-slave empfang-send

twi-master send-empfang-------------------------------------------------

$regfile = "m32def.dat"
$crystal = 8000000
$hwstack = 32
$swstack = 32
$framesize = 64
$baud = 19200

Declare Sub Twi_send_byte(byval Slave As Byte , Zeichen As Byte)
Declare Function Twi_read_byte(byval Slave As Byte) As Byte

Dim Twi_control As Byte
Dim Twi_status As Byte
Dim Twi_data_em As Byte
Dim Twi_data_se As Byte

Enable Interrupts

Twcr = &B00000100                       ' erstmal nur TWI aktivieren
Twsr = 0                                ' Status und Prescaler Register
Twbr = 72                               ' Bit Rate Register, 100kHz

Waitms 500
Twi_data_se = 145

Do

   Call Twi_send_byte(&H50 , Twi_data_se)
   Waitms 250
   Twi_data_em = Twi_read_byte(&H50)
   Waitms 250
   Print Twi_data_em

Loop

End

Function Twi_read_byte(byval Slave As Byte) As Byte
    Twi_read_byte = 0                   ' Wert vorbelegen

    ' Startbedingung
    Twcr = &B10100100                   ' TWINT

    ' warten bis TWINT gesetzt ist
    Gosub Twi_wait_int

    ' wenn Zugriff auf den Bus erlaubt, Slaveadresse ausgeben
    If Twi_status = &H08 Or Twi_status = &H10 Then
        Twdr = Slave Or &H01            ' slave adresse + Read
        Twcr = &B10000100               ' TWINT löschen, Byte senden

        ' warten bis TWINT gesetzt ist
        Gosub Twi_wait_int

        ' Slave hat sich gemeldet
        If Twi_status = &H40 Then
            Twcr = &B10000100           ' TWINT löschen, Byte senden
            Gosub Twi_wait_int
            ' ein Byte wurde empfangen
            If Twi_status = &H58 Or Twi_status = &H50 Then
               Twi_read_byte = Twdr     ' Daten lesen
            End If
        End If
    Else
        ' Bus belegt, wird er wieder freigegeben
        Twcr = &B10000100               ' TWINT löschen, Bus freigeben
    End If
End Function

Sub Twi_send_byte(byval Slave As Byte , Zeichen As Byte)
    ' Startbedingung
    Twcr = &B10100100                   ' TWINT

    ' warten bis TWINT gesetzt ist
    Gosub Twi_wait_int

    ' wenn Zugriff auf den Bus erlaubt, Slaveadresse ausgeben
    If Twi_status = &H08 Or Twi_status = &H10 Then
        Twdr = Slave And &HFE           ' slave adresse + Write
        Twcr = &B10000100               ' TWINT löschen, Byte senden

        ' warten bis TWINT gesetzt ist
        Gosub Twi_wait_int

        ' Slave hat sich gemeldet
        If Twi_status = &H18 Or Twi_status = &H20 Then
            Twdr = Zeichen              ' Daten
            Twcr = &B10000100           ' TWINT löschen, Byte senden

            ' warten bis TWINT gesetzt ist
            Gosub Twi_wait_int
        End If
    Else
        ' Bus belegt, wird er wieder freigegeben
        Twcr = &B10000100               ' TWINT löschen, Bus freigeben
    End If
End Sub

Twi_wait_int:
    Do
        Twi_control = Twcr And &H80
    Loop Until Twi_control = &H80
    Twi_status = Twsr And &HF8
Return



twi-slave
empfang-send---------------------------------------------------

$regfile = "m32def.dat"
$crystal = 8000000
$hwstack = 32
$swstack = 32
$framesize = 64
$baud = 19200

Config Lcdpin = Pin , Db4 = Portc.2 , Db5 = Portc.3 , Db6 = Portc.4 ,
Db7 = Portc.5 , E = Portc.6 , Rs = Portc.7
Config Lcd = 20 * 2

Dim Twi_control As Byte
Dim Twi_status As Byte
Dim Twi_data_em As Byte
Dim Twi_data_se As Byte

Declare Sub Twi_sla_se_em()
Declare Sub Twi_init_slave()

Enable Interrupts

Twi_data_em = 0
Twi_data_se = 77

Call Twi_init_slave

Cls

Do

   Waitms 300
   Call Twi_sla_se_em()
   Cls
   Lcd Twi_data_em

Loop

End

Sub Twi_sla_se_em()
     ' schauen ob TWINT gesetzt ist
    Twi_control = Twcr And &H80         ' Bit7 von Controlregister

    If Twi_control = &H80 Then
        Twi_status = Twsr And &HF8      ' Status

        ' wurde ein Byte geschickt
        If Twi_status = &H80 Or Twi_status = &H88 Then
            Twi_data_em = Twdr          ' neue Daten merken
        End If

        ' will der Master ein Byte haben
        If Twi_status = &HA8 Or Twi_status = &HB8 Then
         Twdr = Twi_data_se             ' neue Daten ausgeben
       End If
        ' TWINT muss immer gelöscht werden, damit es auf dem Bus weiter
geht
        Twcr = &B11000100               ' TWINT löschen, erzeugt ACK
    End If
 End Sub

Sub Twi_init_slave
    Twsr = 0                            ' status und Prescaler auf 0
    Twdr = &HFF                         ' default
    Twar = &H50                         ' Slaveadresse setzen
    Twcr = &B01000100                   ' TWI aktivieren, ACK
einschalten
End Sub
Autor: hans-jakob (Gast)
Datum: 06.05.2008 17:02

hallo manni!

ich versuche in den letzten tagen dein programm zum laufen zu bringen!

ich benutzte einen atmega16 als slave und einen atmega 2561 als master!

zum deguggen lasse ich mir über printf fktionen texte ausgeben!

allerdings streikt bei mir die printfunktion sobald ich werte ausgeben
möchte zbsp: printf ("jetzt kommt die zahl:  %d \n", test1);

mein programm bzw meine terminals für die com schnittstelle hängen sich
dann immer auf!


ich verwende die aktuelle avr studio 4.14 version und das im moment
neuesete winavr.

in anderen foren habe ich gelesen dass ich über die configurtion options
noch die bibliotheken lbprintf_flt.a und libprintf_min.a

und bei den custom options beim linker die -Wl,-u,vfprintf und
-lprintf_flt miteinfügen soll.

allerdings alles käsekuchen, keine verbesserung oder verschlechterung

kennst du oder jemand anderes den Fehler?

vilen dank
Autor: Manni (Gast)
Datum: 09.05.2008 20:47
Dateianhang: Makefile (2,4 KB, 17 Downloads)

Na Hoppla,

habe ganz vergessen, dass ich die TWI S/W ins Forum gestellt hatte.
Deshalb antworte ich jetzt hier erst so spät. Trotzdem freut es mich,
dass jemand die S/W verwenden kann.

@ neuer( Gast)
Das ist ein reiner Schreibfehler. Die Funktion Delay_ms macht das was
sie soll: Parameter sind die Millisekunden. Zur BAS software kann ich
nichts hinzufügen. BAS habe ich vor 20 Jahren verlassen :-) als K&R mit
C DER Standard wurde. Wiess bis heute nicht, warum es immer noch
Menschen gibt, die mit BAS rumspielen !?!

@ hans-jakob
Ich habe die S/W mit ATmega32 und -8 getestet. Sollte also auch mit
ATmega16 gehen. Zum atmega 2561 kann ich leider keine Aussagen machen,
da ich mit dem noch nicht gearbeitet habe. S/W-mäßig sollten aber alle
Atmel uC funktionieren, da alles H/W unabhängig ist, wenn die Baudrate
und das transmission protokoll richtig eingestellt ist mit:

/*
** Set transmission type, Asynchron 8N1
*/
  UCSRC |= (1 << URSEL)|(3<<UCSZ0);

Bei mir läuft alles mit 8MHz Clock.
Ich habe drüber hinaus keine zusätzlichen Bibliotheken wie
lbprintf_flt.a und libprintf_min.a gelinkt. Optimisation ist -O0.
Anbei zur Hilfe noch mein Makefile, welches das Default ist, welches
Winavr generiert (habe nichts dran geändert).
Was nicht funktioniert sind printf(s) von float/double Zahlen, wie in
den Comments in der Datei RS232.c dargestellt.

Grüße
Manni
Autor: Manni (Gast)
Datum: 09.05.2008 20:51

@ Torsten K.

Wenn du da was zusammengestellt hast, d.h. Protokoll, würde mich das
Ergebnis wirklich interessieren, da ich für meine Anwendung was im
HauRuck-Verfahren zusammengestellt habe mit Tausend if und else
Anweisungen, also nicht professionelles, sollte nur schnell
funktionieren.

Gruß
Manni

Antwort schreiben

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

Wichtige Regeln - erst lesen, dann posten!

  • Suchfunktion und Betreffsuche benutzen - vielleicht gibt es schon einen ähnlichen Beitrag
  • Aussagekräftigen Betreff wählen
  • Im Betreff angeben um welchen Controllertyp es geht (AVR, PIC, ...)
  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang
  • JPEG-Dateien (.jpg) nur für Fotos verwenden, Schaltpläne, Screenshots usw. als PNG oder GIF anhängen

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [pre]vorformatierter Text (z.B. Code in anderen Sprachen)[/pre]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel






webmaster@mikrocontroller.netImpressumWerbung auf Mikrocontroller.net