Ich möchte mein Atmega8 als I2C Slave arbeiten lassen.
Ich will das mein I2c Master dem Slave Befehle senden, und "register" auslesen kann.
gibts da irgend eine DLL? man muss ja nicht immer alles neu erfinden ;)
Vielen Dank!
Druckbare Version
Ich möchte mein Atmega8 als I2C Slave arbeiten lassen.
Ich will das mein I2c Master dem Slave Befehle senden, und "register" auslesen kann.
gibts da irgend eine DLL? man muss ja nicht immer alles neu erfinden ;)
Vielen Dank!
Ich habe ein Beispielprogramm gefunden, direkt von Atmel.
http://www.atmel.fi/dyn/products/app...?family_id=607
Ich habe mich dort für "AVR311: Using the TWI module as I2C slave" entschieden.
nun aber schon ein Porblem.. im Source file werden header gebraucht die ich, und mein der AVR compiler, bis jetzt nicht kannten.
es handelt sich um diese zwei:
kann mir jemand sagen was das nun ist?Code:#include <ioavr.h>
#include <inavr.h>
bei ioavr.h denk ich mal das es sich um <avr/io.h> handelt..
Vielen Dank!
ok, hat geklappt ;)
mit <avr/io.h> und der Signal.h
dann noch kleinere anpassungen wie der ISR name.. ;)
Dürfte daran liegen, dass der Code für nen anderen Compiler (IAR) gedacht ist...Zitat:
Zitat von ChRiZ
Ich hab auch mal angefangen, nen I2C Slave zu proggen. Bis jetzt nur Empfangen von Daten. Soll ichs mal posten?
Ja bitte. Auf jeden Fall. Das interessiert mich nämlich auch und könnte es auch bei meinem aktuelle Projekt gebrauchen...
EDIT: Programm ins Wiki verschoben!
https://www.roboternetz.de/wissen/in...ve_mit_avr-gcc
Hier die neueste Version, frisch geschrieben und nur kurz getestet (schien sofort zu laufen...). Jetzt kann der Master auch Daten vom Slave aus dem txbuffer abholen.
EDIT: Programm ins Wiki verschoben!
https://www.roboternetz.de/wissen/in...ve_mit_avr-gcc
Hallo uwegw!
Ich war in den Ferien und habe deine Antworten erst kürzlich gesehen!
Vielen Dank! funktionierte auch bei mir auf anhieb!!
Nur Daten Empfangen konnte ich bisher noch keine, ich fülle in meinem Programm einfach den TxBuffer..
aber das klappt shcon noch ;)
Vielen Dank nochmals!
greetz ChRiZ
Wenn ich den Code von uwewg bei mir in AVRstudio kopiere, kommt folgenden Fehlermeldung:
../../../../../avr-libc-1.4.5/crt1/gcrt1.S:51: undefined reference to `main'
Kann mir jemand sagen, an was es liegt?
Gruß, Werner
Was steht in der Zeile 51? Wie sieht den Hauptprogramm aus? Kommt der Fehler auch, wenn du die Datei mit meinem Code nicht einbindest?
Den Fehler kenne ich an sich nicht. Ich habe nun nochmal dein Code Nr.2 kopiert und kompilieren lassen.
Irgendwie scheint mit nem Code von Winavr selber was nicht zu stimmen.
Gruß, Werner
Wie ist das Hauptprogramm, wie ist das makefile?
Makefile macht ja avrstudio selber. Darum muss ich mich ja im Normalfall nicht kümmern!?
Hauptprogramm existiert eigentlich keins. Solange doch dieser Code nicht fehlerfrei kompiliert wird, wird ein Hauptprogramm auch nichts bringen. Sehe ich das falsch?
Der Code sollte später auf einem Mega 8 ohne externen Quarz laufen.
Ich würd mich echt freuen, wenn des klappen würde!
Gruß, Werner
du brauchst auf jeden Falll nen Funktion namens main. Die muss in jedem Programm vorhanden sein. main wird als erstes aufgerufen, wenn der AVR startet.
Pack am besten ne Ausgabe des rxbuffers (LEDs, LCD, UART, wasauchimmer du am AVR hängen hast) in main. Oder die Werte aus dem rxbuffer lesen, verändern und in txbuffer packen....
avr-gcc.exe -mmcu=atmega8 M8LED.o Zeit.o twislave.o -o M8LED.elf
twislave.o: In function `init_twi_slave':
../twislave.c:35: multiple definition of `init_twi_slave'
M8LED.o:C:\Dokumente und Einstellungen\Werner\Eigene Dateien\M8LED\twislave.c:35: first defined here
twislave.o: In function `__vector_17':
../twislave.c:47: multiple definition of `__vector_17'
M8LED.o:C:\Dokumente und Einstellungen\Werner\Eigene Dateien\M8LED\twislave.c:47: first defined here
make.exe: *** [M8LED.elf] Error 1
Habs gerade mal mit dem Programmersnotepad kompiliert, weil man da ja offensichtlich eine genauere Fehlerbeschreibung bekommt.
So wie es ausschaut, meckert er zweimal wegen multipler Definition.
Hast du ne Ahnung, was ich anders machen kann?
Hast du vielleicht das ganze Zeug einmal im Hauptprogramm und einmal in der twislave.c stehen? Oder die twislave.c zweimal eingebunden? (muss ich bei Gelegenheit mal ändern, damit das nicht mehr zu nem Fehler führt)
Ich hab jetzt mal meine aktuelle Version ins Wiki gepackt.
https://www.roboternetz.de/wissen/in...ve_mit_avr-gcc
Ne genauere Beschreibung folgt die Tage.
Ich glaube das war der springende Punkt. Wenn ich jetzt über diesen Projektmanager twislave.c einfüge, diese Datei extra kompiliere und anschließend build klicke, kommt kein Fehler mehr!
Habe aber jetzt noch ne Frage. Wie kann ich den nun die Funktion am leichtesten testen:
init_twi_slave(0x50);
Reicht das schon, dass ich vom Master aus was sinnvolles empfange?
Sorry für die vielen Fragen...
Mit
init_twi_slave(0x50);
aktivierst du die Schnittstelle und setzt die Slave-Adresse auf 0x50.
Um die Kommunikation zu testen, müssterst du z.B. was in den txbuffer schreiben:
txbuffer[0]=255;
txbuffer[1]=100;
txbuffer[2]=33;
...
Wenn du jetzt vom Master aus auf den Slave zugreifst, müsstest du diese Wert erhalten.
Nen Codeschnipsel für den Master, benutzt die fleury-Master-lib:
Code:#define SLAVE_ADRESSE 0x50
if(!(i2c_start(SLAVE_ADRESSE+I2C_WRITE))) //Slave bereit zum lesen?
{
i2c_write(0x00); //buffer Startadresse zum Auslesen
i2c_rep_start(SLAVE_ADRESSE+I2C_READ); //Lesen beginnen
byte0= i2c_readAck();
byte1= i2c_readAck();
byte2= i2c_readAck();
i2c_stop();
}
Das will bei mir nicht klappen ](*,)
Nach wie vor wird das bei mir nicht richtig kompiliert.
Standardfehler sind mittlerweile:
../../../../../avr-libc-1.4.5/crt1/gcrt1.S:51: undefined reference to `main'
oder
make.exe: *** No rule to make target `C:/Dokumente', needed by `main.elf'. Stop.
Das Problem ist, dass diese c-Datei in meiner main.c nie ordentlich eingebunden ist, ansonsten käme doch kein impilicit Declaration.
Hab echt keine Ahnung, warum das bei mir so Probleme macht...
Gruß
PS: Nichtmal dieses bescheurte Beispielprogramm 311 von Atmel wird fehlerfrei kompiliert!
Du scheinst die Dateien im Ordner C:/Dokumente und Einstellungen/... liegen zu haben, richtig? Pfade mit Leerzeichen darin sind oft problematisch... Der Compiler sieht bei dir nur das "C:/Dokumente", abwe nicht den weiteren Pfad zu der Datei, die er kompilieren soll. Speicher den Kram mal woanders ab.
Vielen Dank für den Tipp mit dem Pfad. Jetzt funktionieren die Makefiles.
Mittlerweile bin ich in der Lage ein byte zu empfangen, anschließend hängt sich mein Master auf.
Anschließend sollte eigentlich wieder eine LED blinken, was sie aber nicht tut.Code:if (!(i2c_start(SLAVE_ADRESSE+I2C_WRITE))) //Slave bereit zum lesen?
{
i2c_write(0x00); //Buffer Startadresse zum Auslesen
i2c_rep_start(SLAVE_ADRESSE+I2C_READ); //Lesen beginnen
byte0= i2c_readAck();
if (byte0==25){
PORT_REL1 |= (1 << PAD_REL1);
wait_10ms(100);
PORT_REL1 &= ~(1 << PAD_REL1);
}
//PORT_LED &= ~(1 << PAD_LED);
i2c_stop();
}
An welcher Stelle genau klemmt es?
Ich habe den Fehler gefunden. Das Problem war der Master. Man muss immernoch was schreiben, bevor man stoppen oder erneut was empfangen kann:
Anscheinend habe ich mittlerweile TWI verstanden 8-[Code:i2c_write(0x00); //Buffer Startadresse zum Auslesen
i2c_rep_start(SLAVE_ADRESSE+I2C_READ); //Lesen beginnen
byte0= i2c_readAck();
i2c_write(0xb0);
byte1= i2c_readAck();
i2c_write(0xc5);
i2c_stop();
Vielen Dank nochmal uwegw für deine Hilfe!
Gruß, Werner
mmmh... komische Sache. Bei mir klappt alles einwandfrei, wenn ich erst den Schreibzugriff starte, die Startposition 0x00 schreibe, per repeated Start auf lesen schalte und dann Wert für Wert auslesen.
Hast du in deinem Post von 16:29 den ersten Start beim kopieren weggelassen, oder fehlt der auch im Programm?
i2c_start(SLAVE_ADRESSE+I2C_WRITE))
Das habe ich nur im Forum weggelassen.
Hallo,
ich finde es super das hier der Quelltext für den i2c-slave steht.
Natürlich habe ich den i2c-slave ausprobiert und er funktioniert eigentlich auch. Nur leider habe ich das Problem das nach einer Stopcondition der slave die sda-Leitung auf low zieht und nicht mehr frei gibt. Dadurch kann ich leider nur einmal Daten abrufen und dann nie wieder :(
Wär schön wenn mir jemand mit dem Problem helfen könnte.
mfg
Heady
Ach ja hat sich erledigt.
Ich hab vergessen meinen master ein NOACK senden zu lassen -.-
Sehr merkwürdig... Wenn nen Stop reinkommt (case TW_SR_STOP:), wird die Übertragung beendet, der Bus freigegeben, und der Slave wartet darauf, dass er wieder adressiert wird.
Ist es wirklich der Slave, oder klemmt es doch im Master? Wie sieht dein Master-Code aus?
EDIT: schön, dass es jetzt klappt. Aber gib mir doch bitte mal deinen fehlerhaften Code, damit ich den Fehler im Slave eventuell abfangen kann...
hmm ... hab den original Code momentan nicht hier. Aber er war ca. so:
meine korrigierte Version ist:Code:int read_data(addr, subaddr, uint8 *data, uint8 cnt){
uint8 i;
ic2_start(addr+write);
delay();
i2c_write(sub_addr);
if(!i2c_read_ack()){
i2c_stop();
return;
}
delay();
i2c_start(addr+read);
delay();
for(i=0;i<cnt;i++){
*(data++) = i2c_read();
if(i<cnt-1)
i2c_write_ack(); //schreibt ein ACK
delay();
}
i2c_stop();
return i;
}
Also ich hab es nach gemessen und es ist eindeutig der Slave der die Leitung runter zieht.Code:int read_data(addr, subaddr, uint8 *data, uint8 cnt){
uint8 i;
ic2_start(addr+write);
delay();
i2c_write(sub_addr);
if(!i2c_read_ack()){
i2c_stop();
return;
}
delay();
i2c_start(addr+read);
delay();
for(i=0;i<cnt;i++){
*(data++) = i2c_read();
i2c_write_ack(i<cnt-1); //schreibt ein ACK wenn der Parameter 0 ist und NOACK wenn der Parameter 1 ist
delay();
}
i2c_stop();
return i;
}
Aber stimmt schon, eigentlich müsste der Slave einfach reseten und auf empfang gehen wenn eine stop-condition kommt. Und so wie ich das sehe sollte er das nach dem Quelltext auch tun. Wer weiß vielleicht ein bug im TWI ;)
Welche Master-Lib steckt dahinter?
Da steckt meine eigene master-lib dahinter da der Master über gpio pins läuft
Hallo,
ich habe gerade den Code zum Slave gefunden, aber im Moment komme ich leider nicht weiter:
bekomme ich den Fehler vom compiler:Code:#include "avr/io.h"
#include "uart.h"
init_twi_slave(0x50);
int main(void)
{
txbuffer[0]=255;
txbuffer[1]=100;
txbuffer[2]=33;
}
Build started 25.3.2007 at 20:54:27
avr-gcc.exe -mmcu=atmega8 -Wall -gdwarf-2 -O0 -MD -MP -MT twislave.o -MF dep/twislave.o.d -c ../twislave.c
../twislave.c:40: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'rxbuffer'
../twislave.c:43: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'txbuffer'
../twislave.c:50: error: expected ')' before 'adr'
../twislave.c: In function 'init_twi_slave':
../twislave.c:77: warning: implicit declaration of function 'sei'
../twislave.c: At top level:
../twislave.c:95: warning: return type defaults to 'int'
../twislave.c: In function 'ISR':
../twislave.c:115: error: 'rxbuffer' undeclared (first use in this function)
../twislave.c:115: error: (Each undeclared identifier is reported only once
../twislave.c:115: error: for each function it appears in.)
../twislave.c:133: error: 'txbuffer' undeclared (first use in this function)
../twislave.c:160: warning: control reaches end of non-void function
make: *** [twislave.o] Error 1
Build failed with 7 errors and 3 warnings...
Die Buffer muß ich die selbst definieren oder muß ich noch etwas anderes einbinden ?
viele Grüße
Mario
lässt ahnen, dass du eine veraltete avr-gcc-Version hast. Dein Compiler kenn anscheinden den Datentyp uint8_t nicht, und behandelt auch die Interrupts noch mit signal statt ISR.Code:../twislave.c: In function 'ISR':
Im Wiki hab ich ne auch ne neue der twislave.c Version eingefügt, solltest du auch mal aktualisieren.
Hast du die twislave.c im Makefile eingebunden? Sonst fehlt im Hauptprogramm noch #include "twimaster.c"
hmm, gcc Heute heruntergeladen:
C:\WINDOWS>avr-gcc --version
avr-gcc (GCC) 4.1.1 (WinAVR 20070122)
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
C:\WINDOWS>
Die twislave.c ist von jetzt gerade, selber Fehler.
Habe gerade die twimaster.c eingebunden, selber Fehler.
ich habe auch gelesen das .c Dateien nicht includiert werden sondern eingebunden, warscheinlich von der Funktion das gleiche, scheinbar nur "optik".
merkwürdig...Zitat:
Zitat von Makrolon
zu welcher Version der twislave.c passen die Zeilennummern aus den Fehlermeldungen?
neuer Fehler, passend zur neuen twislave.c
Build started 25.3.2007 at 21:51:17
avr-gcc.exe -mmcu=atmega8 -Wall -gdwarf-2 -O0 -MD -MP -MT twislave.o -MF dep/twislave.o.d -c ../twislave.c
../twislave.c:49: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'rxbuffer'
../twislave.c:52: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'txbuffer'
../twislave.c:59: error: expected ')' before 'adr'
../twislave.c: In function 'init_twi_slave':
../twislave.c:95: warning: implicit declaration of function 'sei'
../twislave.c: At top level:
../twislave.c:116: warning: return type defaults to 'int'
../twislave.c: In function 'ISR':
../twislave.c:146: error: 'rxbuffer' undeclared (first use in this function)
../twislave.c:146: error: (Each undeclared identifier is reported only once
../twislave.c:146: error: for each function it appears in.)
../twislave.c:166: error: 'txbuffer' undeclared (first use in this function)
../twislave.c:188: warning: control reaches end of non-void function
make: *** [twislave.o] Error 1
Build failed with 7 errors and 3 warnings...
Ich hab jetzt den Fehler reproduzieren können.
Lösung:
#include <avr/interrupt.h> und #include <avr/io.h> müssen im Hauptprogramm VOR #include "twislave.c" stehen.
Wie gesagt, das ganze ist noch nicht ganz ausgereift. Ich hab noch nicht vile Erfahrung mit dem Erstellen von libs, und bring arbeite mich so learning by doing in die Materie ein.
Der Bugfix: in der twislave.c an Anfang noch
#include <avr/interrupt.h>
#include <avr/io.h>
einfügen, dann sollte es immer gehen.
PS: was macht die twimaster.c in deinem Projekt? Entweder Master ODER Slave. Für Multimaster müsste man beides in einer lib kombinieren.
vielen Dank für die Hilfe.
habe jetzt mal den Code geändert:
bekomme jetzt einen anderen Fehler:Code:#include <avr/interrupt.h>
#include <avr/io.h>
#include "twislave.c"
init_twi_slave(0x50);
int main(void)
{
txbuffer[0]=255;
txbuffer[1]=100;
txbuffer[2]=33;
}
Build started 25.3.2007 at 22:09:27
avr-gcc.exe -mmcu=atmega8 -Wall -gdwarf-2 -O0 -MD -MP -MT slave.o -MF dep/slave.o.d -c ../slave.c
../slave.c:5: error: expected declaration specifiers or '...' before numeric constant
../slave.c:5: warning: data definition has no type or storage class
../slave.c:5: warning: type defaults to 'int' in declaration of 'init_twi_slave'
../slave.c:5: error: conflicting types for 'init_twi_slave'
../twislave.c:90: error: previous definition of 'init_twi_slave' was here
../slave.c: In function 'main':
../slave.c:14: warning: control reaches end of non-void function
make: *** [slave.o] Error 1
Build failed with 3 errors and 3 warnings...
Irgendwie hakt es beim Datentyp. Kennt der kein uint8_t mehr?
Oder ist nur das AVRStudio schuld? Ich verwende programmes notepad. Ich weiß nicht, wie das Studio mit solchen Projekten aus mehreren Codedateien umgeht.
versuch mal ne eigene Variable als uint8_t anzulegen. Wenn er dabei meckert, versuch mal #include <stdint.h>