Datum: 04.01.2008 21:51
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
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
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
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
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);
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
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
Datum: 09.05.2008 20:47
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
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