Hallo, habe bei "uC & Elektronik" einen Beitrag laufen wegen I2C projekten in WINAVR. Da es aber scheinbar keine Projekte dazu gibt will/muß ich jetzt auch nochmals ganz von vorne auf einen neuen Weg anfangen die I2C zu schreiben. Habe dabei vor, die Projekte von Atmel 311 usw. auf WINAVR umzuschreiben. Dabei habe ich aber das Problem, das eine in der Header definierte Variable in der C-File nicht erkannt wird. Auszug aus Header: union TWI_statusReg // Status byte holding flags. { unsigned int all; struct { unsigned char lastTransOK:1; unsigned char RxDataInBuf:1; unsigned char genAddressCall:1; // TRUE = General call, FALSE = TWI Address; unsigned char unusedBits:5; }; }; extern union TWI_statusReg TWI_statusReg; Auszug aus C: TWI_statusReg.all = 0; Doch leider erkennt der Compiler nicht die Variable. Hat jemand ahnung woran es liegen kann? Gruß, Peter
Du hast die Variable nur deklariert, nicht definiert. In der Headerdatei steht nur drin, daß es eine Variable gibt, aber nicht, wo. Um das "wo" zu klären, musst Du in einem Sourcefile noch eine Instanz dieser Variablen anlegen. union TWI_statusReg TWI_statusReg; in ein Sourcefile geschrieben löst das Problem. Fast. Der Name der Variablen darf nicht der Namen des Typs (hier: der union) entsprechen, also solltest Du das ganze umbenennen: union TWI_statusReg mein_status_reg; und auch die Deklaration in der Headerdatei entsprechend anpassen.
Hallo Rufus, deklaration steht ja auch in der Header nach der deklaration. Mit dem Problem des gleichen Namens kannst du recht haben, ich habs mal geändert -> aber kein Erfolg. Habe auch noch mal versucht die Instanz in der Funktion selbst anzulegen. aber auch kein Erfolg. Es kommt immer die Fehlermeldung: d:\elektronik\winavr_projekte\atmega32\twi_test/twi.c:63: undefined reference to `TWI_statusReg' Was tun? Der ursprüngliche Code von Atmel ist für IAR ausgelegt. Ich weis nicht, ob das so viel ausmachen kann. Gruß, Peter
Du darft dann natürlich auch nicht TWI_statusReg.all = 0; schreiben, sondern musst mein_status_reg.all = 0;
Hallo, das war klar. Ich hatte halt nur die Deklartion und den entsprechenden aufruf geändert. Jetzt glaube ich das ich es gefunden. der Compiler hat ein problem mit der "extern union" in der Deklaration. Mit einem reinem "union" kann er kompilieren. Tja wenn man auf dem Schlauch steht hilft halt immer wieder eine Pause. Danke an alle die sich Gedanken und die Arbeit zu antworten gemacht haben. Gruß Peter
> der Compiler hat ein problem mit > der "extern union" in der Deklaration. Selbstverständlich darf man eine union extern deklarieren.
Hallo Jörg, hast du das mit WINAVR schon mal gemacht? Ich meine eine Definition: extern union Beispielunion meineunion; zum laufen gebracht. Ich hab halt das extern weggelassen, dann konnte er kompilieren. Kann zwar leider unter der woche immer nicht testen, weil ich da keinen eigenen Rechner habe, wo ich die Software laufen lassen kann. Aber mich würden trotzdem Erfahrungen dazu interessieren. Werde mich auf alle Fälle am WE nochmals damit beschäftigen. Zwangsweise, will ja die ATMEL I2C Routinen übertragen und zum laufen bringen. Gruß, Peter
In der Headerdatei sollte unbedingt "extern" stehen, im C-Sourcefile muss das "extern" weggelassen werden. Wenn Du die Zeile union Beispielunion meineunion; sowohl in Deiner Headerdatei als auch im C-Sourcecode unterbringst, sollte eigentlich der C-Compiler nörgeln, da das eine doppelt definierte Variable ist. Allerdings gibt es eine gcc-Abartigkeit, daß der diesen Standardprogrammierfehler (der vor allem dann auftritt, wenn eine Headerdatei mit der Definition von Variablen in mehreren Sourcefiles eingebunden wird), "verschluckt" und klammheimlich alle "Doubletten" überlagert. Das kann man aber irgendwie abschalten, wie, das wird man vermutlich auch irgendwie herausfinden können. Die "saubere" und vor allem portierbare Variante ist jedenfalls, Variablen in Headerdateien nur zu deklarieren (indem das Wort "extern" verwendet wird) und sie in genau einem Sourcefile des Projekts zu definieren (indem das Wort "extern" weggelassen wird). Natürlich muss die Definition ausserhalb jedes Funktionsrumpfes erfolgen, da die Variable sonst eine automatische Variable ist, auf dem Stack landet und nur so lange existiert, bis die betreffende Funktion verlassen wird. In diesem Fall ist ein Zugriff auf diese Variable aus anderen Modulen nicht möglich, auch der Linker wird das betreffende Symbol nicht auflösen können. Beispiel: ######## bla.h ######### union Beispielunion { int a; char b; } extern union Beispielunion meineunion; ######## bla.c ############ #include "bla.h" union Beispielunion meineunion; void irgendeinefunktion(void) { meineunion.a = 0; } ######### ende #########
Hallo Peter Bevor Du das Rad ein zweites mal erfindest: unter folgendem Link findest Du eine umfangreiche Funktions-Sammlung, bzw. Libraries für WinAVR, unter anderem auch für den I2C-Bus: http://hubbard.engr.scu.edu/embedded/avr/avrlib/index.html Ich bin gerade daran, für ein eigenes Speicher-kritisches Projekt einen minimale I2C-Bus Treiber Funktionen entworfen, konnte sie aber noch nicht testen, da die HW noch im Bau ist! Ich habe ein kurzes Beispielprojekt mit diesen Funktionen im beigefügt, aber wie gesagt, noch ohne Gewähr dass es richtig tut! Mit freundlichen Grüßen Peter
Ouups.... Da ist schon ein Bug in TWI_write(): 0xFE statt 0xF0 TWDR = (TWI_adr & 0xFE); // put slave address+WRITE to TWDR Ich weiss leider nicht, wie man in diesem Forum Beiträge editiert, bzw. aktualisiert, geht das überhaupt? Gruss Peter
>Ich weiss leider nicht, wie man in diesem Forum Beiträge editiert, >bzw. aktualisiert, geht das überhaupt? Nein.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.