Hallo Zusammen, ich bin seit lange Zeit mit dem Modul RFM12 beschäftigt, ich kann schon senden und empfängen ohne Interrupt. d.h ich hole die Daten ohne Interrupt ab. jetzt möchte ich die Daten holen nur wenn sie wirklich angekommen sind. Pin nIRQ von RFM12 ist mit Interrupt (INT0) von Mikrocontroller angeschloßen. der Modul ist wie folgendes initialisiert: void rf12_init(void) { RF_DDR=(1<<SDI)|(1<<SCK); PORTD|=(1<<SCK); RF_DDR &= ~(1<<SDO); DDRD|=(1<<CS); PORTD|=(1<<CS); _delay_ms(500); // wait until POR done rf12_trans(0xC0E0); // AVR CLK: 10MHz rf12_trans(0x80D7); // Enable FIFO rf12_trans(0xC2AB); // Data Filter: internal rf12_trans(0xCA81); // Set FIFO mode rf12_trans(0xE000); // disable wakeuptimer rf12_trans(0xC800); // disable low duty cycle rf12_trans(0xC4F7); // AFC settings: autotuning: -10kHz...+7,5kHz rf12_trans(0x0000); } /****** Interrupt 0 **************/ ISR(INT0_vect){ receive(); } void init_INT0(void){ EICRA = (1<<ISC01)|(1<<ISC00); //rising Edge EIMSK=0x01; } Mein Problem ist, der sender sendet jede Sekunde ein Packet aber Interrupt löst nicht aus beim empfänger, es ist auf high. wie soll ich RFM12 konfigurieren damit Interrupt funktioniert. ich bitte sie um Ratschläge """Wer hilft wird geholfen"""
Hi, ich habe die RFM12-Module auch am Laufen, allerdings mir IRQ über den FFIT-Pin. Dein Problem wird wahrscheinlich der IRQ selbst sein. Du hast den IRQ-Event auf "rising edge" gestellt. Jedoch ist der IRQ activ LOW. Dann musst du im IRQ-Handler selbst aber noch drauf achten, dass du auch wirklich alle Bytes abholst. Denn der IRQ des Moduls bleibt solange auf LOW, wie Daten vorhanden sind. Durch deine Flankentriggerung wird bei dir der IRQ aber nur 1x ausgelöst. Also evtl eine Schleife einbauen. Lorenz
Hallo, vielleicht kannst Du hier was entnehmen: die Routine empfängt bei mir Datenpakete von mehreren Sensoren. Den Kram mit meinen Arrays kannst Du ja rauswerfen (Test Sensornummer, Prüfsumme, umkopieren in das globale Array). Läuft hier seit Wochen stabil, manchmal unter http://roehre.homeip.net user: test Passwort: test zu erreichen. Gruß aus Berlin Michael
Guten Tag, Ich danke euch für eure schnelle Antworten, ich werde die Vorschläge verarbeiten, die Ergebnisse werde ich auf jeden Fall hier posten. bis gleich
Hallo Zusammen, endlich kann ich jetzt senden und empfangen mit Hilfe von Interrupt (nIRQ). dabei habe ich die Deklarationsreihe von Timer und external Interrupt ausgetauscht. damals: klappt nicht void main(void){ init_timer1(); init_INT1(); . . for(;;){ } } jetzt: Klappt void main(void){ init_INT1(); init_timer1(); . . for(;;){ } } Meine Vermutung für den ersten Fall, dass es nicht funktioniert hat, weil ich den Timer für Senden benutze, der Timer lauft ab und die Interrupt ist noch nicht initialisiert. auf jeden Fall hat jetzt geklappt, wenn jemand meine code braucht, kann ich es posten. vielen Dank für eure mitdenken
@lorenz: Verstehe ich nicht ... der FIFO des Moduls hält doch max. 16 Bit. Wenn ich ihn auslese (ich verwende Bytes, nicht Worte) müßte FFIT doch wieder zurück auf HI gehen, oder? Oder meinst Du mit "alle Bytes" "alle Bits" oder "alle zwei Bytes"? Was mir auch nur äußerst zögernd klar wurde ist, dass für das Funktionieren des Interrupts natürlich (?) das Rx-Teil des Moduls eingeschaltet sein muss. Viele Code-Beispiele für das RFM12-Modul, die Polling verwenden schalten das Rx-Teil unmittelbar vor dem Empfang ein und danach wieder aus. Ist sehr verwirrend für mich und zeitintensiv, das Arbeiten mit den RFM12-Modulen ... wenn ich daran denke, wie simpel und rasch das Arbeiten mit XBEE-Modulen ging, frage ich mich ob sich der Aufwand überhaupt lohnt. :) Christoph
Hallo, @Christoph (Gast): Was mir auch nur äußerst zögernd klar wurde ist, dass für das Funktionieren des Interrupts natürlich (?) das Rx-Teil des Moduls eingeschaltet sein muss. Viele Code-Beispiele für das RFM12-Modul, die Polling verwenden schalten das Rx-Teil unmittelbar vor dem Empfang ein und danach wieder aus. Mal dumm gefragt: wie auch sonst? Er muß ja schließlich empfangen können, um festzustellen, ob was für ihn dabei ist (Syncword). Wenn der Empfänger ausgeschaltet ist, geht das schlecht. :-) Viele Codebeispiele basieren aufeinander und sind durchaus nicht vollkommen und leider auch nicht immer fehlerfrei. Die Datenblätter sind ...naja fragwürdig..., einiges merkt man dann wirklich erst im Einsatz. Ganz praktisch sind die Dinger aber ihr Geld allemal wert, seit ich einige Ungereimtheiten verstanden habe, kaufen sie hier wie gewünscht incl. Empfang transparent komplett im IRQ, Sender mit Sleep usw. usw. http://www.avr.roehres-home.de http://roehre.homeip.net Gruß aus Berlin Michael
@Michael: Ich komm hier nicht weiter. Vielleicht hast Du noch einen Tipp... Ich verwende URadigs USB-Funkmodul-Projekt (http://www.ulrichradig.de/home/index.php/avr/usb-funk) für den RFM12. Dabei stricke ich an seinem Code Beispiel herum, u.a. habe ich das für den CodeVision-Compiler umgearbeitet. Im "Polling-Modus" funktioniert das alles so weit. Meine Module funktionieren also, Anschlüsse im Source-Code stimmen etc. Jetzt will ich den in URadigs Code verwendeten Polling Mode auf Interrupt umstellen. Dazu habe ich eine eigene Interrupt-Routine geschrieben, die den Into-Interrupt verwendet. Wenn jetzt etwas gesendet wird geht der (low-aktive) Anschluss NIRQ auf Low, der Interrupt wird angesprungen, der Pin bleibt aber low, sodass sich dann nichts mehr tut. Interessanterweise passiert mir das selbe, wenn ich Deine RFM12.C-Routinen einbinde. Irgend eine Idee, was ich falsch machen könnte? >> Viele Codebeispiele basieren aufeinander und sind durchaus nicht >> vollkommen und leider auch nicht immer fehlerfrei. >> Die Datenblätter sind ...naja fragwürdig..., einiges merkt man dann >> wirklich erst im Einsatz. Ohja. ;) Grüße, Christoph
Hallo, da ich ja immernoch an meinem Logicanalyzer den RFM12-Empfänger als Signalgeber dran habe, gibt es einen Screenshot. nIRQ geht bei Fifo voll auf L (zeitgleich mit SDO = H, eigentlich logisch) und geht wieder auf H bei der H/L-Flanke des Taktes, der das erste Datenbit aus dem Fifo holt eigentlich auch logisch). Vermutung: irgendwas stimmt bei Deinem Empfangskommando nicht, so das der Fifo einfach nicht ausgelesen wird. Dann dürfte nIRQ bis in alle Ewigkeit auf L bleiben. PS: eigentlich ja zu warm für Computer, aber mein Sensor sagt hier 3 Grad weniger als auf dem Balkon. Sollte mich wohl in den Keller oder ins Gefrierfach begeben... http://roehre.homeip.net Gruß aus Berlin Michael
Was ist das für ein Logikanalysator? :) Ich bin immer noch nicht weiter. Zwischendurch ging mal gar nichts mehr. Tot, das Modul, der ATmega8 war zu nichts mehr zu bewegen. Mehr aus Verzweiflung habe ich mal einen externen Takt an XTAL1 gelegt und siehe da: Der Chip wurde wieder erkannt, ich hatte beim pausenlosen Umflashen ;) aus Versehen auf "externen Oszillator" gefused. Es bleibt dabei. Polling geht. Obwohl ich da auch ein komisches Phänomen sehe: ich sende den Zählerstand eines 8 Bit Counters, der Empfänger gibt das über USB/USART aus. Am Anfang werden brav meine Ziffern ausgegeben: 98 99 100 101 ... Nach einiger Zeit kommt zwischen diese Ziffern irgend ein Zeichen dazu: z.B: öö ö9ö8ö öö ö9ö9ö öö1ö0ö0ö öö1ö0ö1ö ... Wenn ich den Empfänger resette stimmt es für eine Weile wieder. ;) Also, im Prinzip geht das. Aber kaum nehme ich den Interrupt mit hinein geht nichts mehr. Und NIRQ geht auf "lo" und bleibt da lieber mal ;) Naja. Mit den Jahren ... Grüße, Christoph
Hallo, sendest Du den Zählerstand als Byte oder schon als ASCII-Ziffern? Sendest Du alles einzelnm also Sender aktiv, Sync-Bytes und Sync-Word schicken, Deinen Zählerstand Sneder wieder aus? Die Module brauchen prinzipbedingt ausreichend Pegelwechsel, damit die Bitsyncronisation nicht aus dem Tritt kommt. Wenn Du also z.B. binär 00, 01, 01, 03 usw. direkt hintereinander sendest, ist der Kram üner kurz oder lang aus dem Tritt. Es gibt je für den Empfänger nur die Möglichkeit, den Buttakt aus den Daten zu gewinnen. Deshalb am Anfang die 3x 0xAA, das ist eine gut geeignete 0-1 Folge, die einmal AFC und Vertärkung des Empfängers einregelt und andererseits die PLL für den Bittakt einrasten läßt. Das Synword gibt dann den Hinweis, wo ein Byte anfängt. Die Bits sehen schließlich alle gleich aus... Ab jetzt ist der Empfänger darauf angewiesen, mit den Flanken in den Datenbytes den Bittakt stabil zu halten. Sind es zuwenig Flanken kommt er aus dem Tritt. Auch eine Störung kann nicht abgefangen werden, es gibt ja in den Daten keinen Hinweis mehr, wann ein Byte beginnt. Also einzelne nicht zu lange Pakete und dann Sender aus. Die Empfangsroutine muß natürlich wissen, wieviele Bytes erwartet werden, wenn die da sind, wird der Fifo aus- und wieder angemacht, damit der Empfänger wieder syncronisieren kann. Gruß aus Berlin Michael
Michael U. schrieb: > Hallo, > > sendest Du den Zählerstand als Byte oder schon als ASCII-Ziffern? Als ASCII-Ziffern. > Sendest Du alles einzelnm also Sender aktiv, Sync-Bytes und Sync-Word > schicken, Deinen Zählerstand Sneder wieder aus? Genau. Mords Overhead. :) URadig hat sogar noch ein Byte für "Byte-Anzahl" und ein Checksum Byte. > > Die Module brauchen prinzipbedingt ausreichend Pegelwechsel, damit die > Bitsyncronisation nicht aus dem Tritt kommt. > Wenn Du also z.B. binär 00, 01, 01, 03 usw. direkt hintereinander > sendest, ist der Kram üner kurz oder lang aus dem Tritt. Wie gesagt. Sollte passen. > Ab jetzt ist der Empfänger darauf angewiesen, mit den Flanken in den > Datenbytes den Bittakt stabil zu halten. Sind es zuwenig Flanken kommt > er aus dem Tritt. > Auch eine Störung kann nicht abgefangen werden, es gibt ja in den Daten > keinen Hinweis mehr, wann ein Byte beginnt. Interessant. > Die Empfangsroutine muß natürlich wissen, wieviele Bytes erwartet > werden, wenn die da sind, wird der Fifo aus- und wieder angemacht, damit > der Empfänger wieder syncronisieren kann. Ich würde (später, wenn alles mal funktioniert) mit dem <CR> arbeiten. Also einfach solange Zeichen in den Buffer laden, bis ein Return kommt. Nochmal zu meinem Interrupt-Problem. Es ist echt myteriös. Ich initialisiere das Modul in üblicher Weise ;) Am Schluss meiner INIT-Routine habe ich: MCUCR |= ISC01; // INT0 fallende Flanke für RFM12 nIRQ // GICR = INT0; rf12_trans(0x82C8); // RX on Meine Interrupt-Routine ist "Short & Sweet": interrupt[EXT_INT0] void ext_int0_isr(void) { rf12_rx_ready = TRUE; } Ich setze einfach ein Flag, wenn der Interrupt ausgelöst wurde. Im Moment läuft Polling zur Abfrage der gesendeten Daten. Am Pin NIRQ sehe ich negative Spikes in Vierer-Gruppen, die meinen gesendeten Bytes entsprechen. Kompiliere ich das so wie oben funktioniert alles. Nehme ich die Kommentierung vor der GICR-Zeile weg (enable also den INT0) funktioniert das Polling zwar immer noch, aber die Spikes an NIRQ sind nicht mehr da, der Interrupt wird ganz zu Beginn einmal ausgelöst und dann nie mehr. Wenn ich die MCUCR-Zeile wegkommentiere und das kompiliere (d.h. ja: Low-level des INT0-Pins generiert einen Interrupt) kriege ich viele viel Interrupts und sonst nichts (klar: NIRQ ist und bleibt auf LOW und löst damit immer wieder Interrupts aus). Auch nicht brauchbar. Idee? Ich nicht mehr. Grüße, Christoph
Hallo, MCUCR |= ISC01; // INT0 fallende Flanke für RFM12 nIRQ // GICR = INT0; rf12_trans(0x82C8); // RX on Das stimmt aber so nicht. MCUCR |= (1<<ISC01) und GICR = (1<<INT0) wäre richtig, das sind Bitnummern... Wobei GCIR |= (1<<INT0) sicherer wäre, um nicht andere Bits in GCIR ungwollt auf 0 zu setzen. Außerdem würde ich vor Freigabe immer mit GIFR |= (1<<INT0) einen evtl. anstehende INT0-IRQ löschen. Gruß aus Berlin
Hi, ich hab meinen Fehler gefunden (wenn auch noch nicht behoben :) ). Michael, Dein Tipp ... >> irgendwas stimmt bei Deinem Empfangskommando nicht ... war gut. Es ist aber nicht das Kommando selbst (es funktioniert ja klaglos, wenn ich das mit Polling einsetze). Das Problem ist, um einen Interrupt per NIRQ-Spike zu generieren muss das Modul - natürlich - entsprechend konfiguriert sein. Ein Teil der Konfiguration erfolgt in der Lese-Routine selbst. Um einen Interrupt zu bekommen, muss ich die Lese-Routine gestartet haben, das passiert aber nicht, weil eben der Interrupt nicht auslöst. Okay. An diesem Code weiter zu machen hat wenig Sinn. Das ist so ein häßliches Sammelsurium, ich fange eher noch mal von vorne an. :) >> MCUCR |= ISC01; // INT0 fallende Flanke für RFM12 nIRQ >> // GICR = INT0; >> rf12_trans(0x82C8); // RX on > Das stimmt aber so nicht. Doch. Das ist eins meiner Probleme mit den zahlreichen Code-Beispielen (die es ja unbestreitbar gibt). Ich mag die "Bitschubsereien" im Code nicht, also so etwas wie GCIR |= (1<<INT0). Ich habe statt dessen ein Definitionsfile für jeden Chip, in dem den Funktions-Bits (also z.B. ISC01) nicht die Nummer des Bits (z.b. 1) zugeordnet wird, sondern der Wert (also hier 2). Ich kann deshalb die Funktionsbits einfach verodern, ohne die Schiebebefehle. Ich darf das nur nicht durcheinander bringen ;) Eine saftige Fehlerquelle mehr für mich :) Grüße, Christoph
Hallo, Christoph Klein schrieb: > ich hab meinen Fehler gefunden (wenn auch noch nicht behoben :) ). > Michael, Dein Tipp ... > >>> irgendwas stimmt bei Deinem Empfangskommando nicht > > ... war gut. Es ist aber nicht das Kommando selbst (es funktioniert ja > klaglos, wenn ich das mit Polling einsetze). Das Problem ist, um einen > Interrupt per NIRQ-Spike zu generieren muss das Modul - natürlich - > entsprechend konfiguriert sein. Ein Teil der Konfiguration erfolgt in > der Lese-Routine selbst. Um einen Interrupt zu bekommen, muss ich die > Lese-Routine gestartet haben, das passiert aber nicht, weil eben der > Interrupt nicht auslöst. Kenne ich auch nur zu gut sowas... Ich habe da kein Problem mit dem Bitgeschiebe, das geht schon automatisch bei mir. Daß die Zeilen da etwas länger sind, ist mir auch egal. > Eine saftige Fehlerquelle mehr für mich :) Genau wegen solcher Nebeneffekte laß ich es lieber. Da ich ja sowieso viele Routinen recycle wäre es wohl nervend, wenn ich dann jedesmal an 2 Stellen aufpassen müßte. Wenn dann eine anderer AVR rein soll, dann werden eben die Errors angeklickt und vor Ort korrigiert. Trotz aller Ungereimtheiten hat man bei Atmal eigentlich schnell raus, wo da noch eine 0 oder 1 in einen Registernamen reingekommen ist. Gruß aus Berlin Michael
Kann jemand noch einem kurz zusammenfassen, was ich für den Interrupt-Betrieb machen muss? Bei mir löst bei einem mal aus, nach dem nächsten Flash nicht mehr.... THX
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.