Nach einigen grauen Haaren habe ich es endlich geschafft, ein RFM02 unter Bascom zum Laufen zu bringen. Da ich hier schon super Anregungen (in diesem Fall vielen Dank an Benedikt!) bekommen habe, stelle ich den Code mal rein. Hardware: - Mega16 - RFM02 über SDI,SCK,CS und FSK mit uC verbunden - CPU Takt: 7.3728 MHz Benedikt verwendet in seinem Code die Option, die zu sendenden Daten über die SDI Leitung einzutakten. Wenn das Modul auf Tx-Sync eingestellt ist, gibt es dazu kurze Nadelimpulse im Baudratentakt über die NIRQ Leitung raus. Die Daten können dann über die SDI Leitung eingetaktet werden und werden mit der fallenden Flanke des NIRQ Impulse übernommen. Benedikt's Code prüft per while-Schleife, wann NIRQ hochgeht. Dann werden noch innerhalb des kurzen Impulses die Daten an SDI angelegt und beim Runterfallen von NIRQ eingelesen. Portiert man den Code auf Bascom, funktioniert das Ganze NICHT (FRUST!!!). Grund (LANGE SUCHE): Die while-Schleife braucht zu lange beim Pollen (zumindest bei meinem Quarztakt). Kann durchaus an Bascom liegen. Es gibt einen undokumentierten Befehl (0xD040 oder so), der den Duty-cycle des NIRQ Taktes auf 50 % umschaltet. Dann wird laut Forum hier auf der steigenden und fallenden Flanke eingelesen. Hab ich nicht zum Laufen bekommen. Lösung: Wenn man das Funkmodul für die Datenübertragung über die FSK Leitung konfiguriert, ändert sich die ausgegebene Funkfrequenz direkt mit dem Pin-Zustand: FSK=1: f = f0 + Modulationsfrequenz FSK=0: f = f0 - Modulationsfrequenz Oder andersrum -> Datenblatt, egal. Ich kann also anstatt den Taktgeber des RFM02 zu verwenden auch die Baudrate auch im uC erzeugen und einfach die Daten raustakten. Das RFM12 wartet zwecks Abtastsynchronisation nur auf die 0xAA's und dann auf das Schlüsselwort (0x2d 0xd4). Hab das mal in Bascom eingetippt (Baudratenerzeugung per Timer0) und bislang läuft das Ding perfekt. Cheers Klaus p.s.: Hoffe, die Farbe meiner Haare kehrt in den nächsten Tagen zurück.
:
Verschoben durch Moderator
Na so was, mir ging es genau so. Mit Hilfe eines Logikanalysators habe ich meine jetzt auch am Laufen. Bis auf das FSK-Senden verwende ich die Bascom SPI-Befehle. So habe ich jetzt die RFM01 und RFM02 am Funken, jetzt bin ich bei den RFM12. Da schreibe ich auch noch meine eigenen Routinen dazu. Das RFM02 habe ich auf einem Pollin-Funk-AVR Board, das RFM01 auf einem Pollin-Add-On Board verbunden mit Atmel-Evaluation Board jeweils mit ATMega8. Gruß, Holger
Diese Version benutzt den SDI Pin zum Senden. Im Gegensatz zur FSK-Version muss hier die Datenübertragung durch Senden von "C6" mit anschließendem IRQ-Polling eingeleitet werden. Das ist nicht SPI kompatibel, daher verwende ich hier Soft-SPI.
Super, danke für die Programme, werde ich durchsehen und ausprobieren. Allerdings hat die SDI-basierte Übertragung mit Polling des NIRQ bei mir nicht funktioniert. Du hast anscheinend einen 12 MHz Quarz genommen, vielleicht macht das die while-Schleife den entscheidenden Tick schneller. Was ansonsten prima wäre: Senden von 0xC6 und dann die Daten über die SDI Leitung mit uC-gesteuertem Takt rausgeben, ohne das NIRQ Signal zu verwenden. Evtl. funktioniert das, wenn man das TX-Sync-Bit ausschaltet. So könnte man sich die FSK Leitung sparen. Cheers Klaus
Ich glaube nicht, dass das Polling das Problem bei dir war. Ich habe das NIRQ Polling in 2 Versionen getestet. Einmal nur auf L-H Flanke warten und dann auf L-H/H-L Flanken. In der SDI Version übrigens wartet NIRQ nur auf die L-H Flanke. Die Verzögerungen zur FSK/SDI Flanke sind 0,8µs bzw. 2,6µs. Ich werde das auch mal mit anderen Quarzfrequenzen testen. In der SDI Version wird FSK nicht mehr benutzt. Du meinst bestimmt, ohne die IRQ Leitung zu senden. Dann sollte allerdings das Timing zum Start der Übertragung stimmen. Nach dem SPI Befehl (hc039) braucht der RFM02 noch 1ms bis zum Start der Übertragung. Gruß, Holger
Zum Polling-Problem: Wenn ich das richtig verstehe, ist der NIRQ-Impuls im kurzen duty-cycle ca. 1.6 us. Wenn ich wie Benedikt mit einer while-Schleife auf die L-H Flanke gewartet habe, hat der uC die Daten immer MEHRERE us nach der L-H Flanke auf SDI gelegt. Da war dann die NIRQ Leitung schon wieder auf L runter und hat dementsprechend das vorherige SDI-Bit eingelesen. Was ich noch nicht verstehe: Prinzipiell sollte das egal sein, da es keine BYTE-Synchronisation gibt. Ich denke, das RFM02 schickt die Daten einfach entsprechend der anliegenden Bits raus und das RFM12 sucht nach der richtigen Bitreihenfolge für das Schlüsselwort. Insofern sollte es völlig unproblematisch sein, wenn man das zu sendende Bit NACH der H-L Flanke von NIRQ an SDI legt, dann wird's halt mit der nächsten NIRQ H-L Flanke rausgeschickt. Da ich jetzt immerhin eine funktionierende Kommunikation hinbekommen habe, kann ich da mal ein paar Tests machen und sicher sein, daß es nicht an anderen Parametern scheitert :-)
Der Ablauf stimmt so. Ab dem 2. IRQ läuft die eigentliche Datenübertragung. Im Anhang ist ein Screenshot des Logikanalysators. Ohne den hätte ich schon aufgegeben. So kann ich probieren und sehe sofort, ob das noch funktioniert oder nicht.
Supi, dann ist soweit eigentlich alles verstanden. Was die Anzahl der notwendigen Leitungen angeht, hat man jetzt die Wahl zwischen SCK, SDI, NIRQ oder SCK, SDI, FSK Macht insofern also noch keinen Unterschied. Für die eigene Taktratenerzeugung brauche ich einen Timer, das wäre ein Grund für SDI-basierte Übertragung. Warum die bei mir nicht funktioniert hat, ist noch offen. Die Zeitverzögerung durch die while-Schleife kann es ja nicht gewesen sein. Wenn ich Dein Bild vom Logiganalysator richtig interpretiere, vergehen rund 2.5 us (Marker B - Marker A) zwischen L-H Flanke von NIRQ und Anlegen des Bits an SDI. Das passt von der Grössenordnung zu meiner Verzögerung. Ideal wäre es, Daten per SDI ohne NIRQ zu übertragen (nur 2 Leitungen). Zumindest wenn es nur wenige Bytes sind, sollte das mit einem uC-internen Taktgenerator gehen, man darf dann nur die NIRQ Impulse nicht "unglücklich treffen" (also SDI Pin möglichst zwischen 2 NIRQ Impulsen verändern). Vielleicht gibt es eine charakteristische Zeit, ab der die NIRQ Impulse nach Senden von 0xC6 auftreten. Komme leider bis Fr nicht dazu, das zu testen :-( Viele Grüsse Klaus
Heureka. Hab gerade doch mal aus Spass einen 11.0592 MHz Quarz eingelötet -> läuft. Vermutung: Die erste while-Schleife, die solange NIRQ=0 wartet, geht so langsam, daß die while-Schleife für die NIRQ H-L Flanke zu spät geprüft wird. Kann man mal drüber nachdenken, evtl. langt eine Prüfung der ersten Flanke oder etwas in der Art, heute nicht mehr :) Cheers Klaus
Oops, hatte ich überlesen. Du schreibst, Du hast das Warten nur auf die L-H Flanke bereits getestet. Falls das funktioniert, wird das evtl. auch mit dem langsamen Quarz gehen (vorausgesetzt, die while-Schleife ist nicht so langsam, daß sie den ganzen Impuls verpasst). Falls es nicht geht, könnte ich natürlich immer noch mit einem Interrupt arbeiten, aber am liebsten würde ich die NIRQ Leitung komplett weglassen. Ansonsten würde mich trotzdem auch die Sache mit dem undokumentierten 50 % duty-cycle Kommando interessieren, vielleicht bekommt man das auch noch zum Laufen. So far Klaus
Hhmm. Bei 7.3728 MHz Quarztakt beträgt ein Taktzyklus 136 ns. Schätze mal, eine einfache while-Schleife in Assembler benötigt rund 10 Taktzyklen. Das sollte also bei einem 1.6 us Impuls hinkommen. Falls Bascom für die while-Schleife Code mit 30 Zyklen generiert, wird's vielleicht knapp. Evtl. lohnt es, die while-Schleife selbst in Assembler zu programmieren?
Das könnte man im Simulator doch ablesen. Dann hättest du die Zeiten doch.
Hab ich noch nicht benutzt, schaue ich mir mal an (Bascom oder AVR Studio?). Die vermutlich kürzeste Schleife der Welt müsste so gehen $asm While_start: SBIS pina,4 RJMP while_start $end Asm Bzw. identisch mit SBIC für "while NIRQ=0". Wenn das alles so stimmt. Cheers Klaus
BASCOM :) $sim am Anfang eingeben und Compilieren. Dann zum Simulator. Wenn du den das mal Disassmblieren möchtest http://comwebnet.weimars.net/forum/showthread.php?tid=366 oder HexHacker bei Google eingeben.
Alright, SBIS und RJMP brauchen laut Simulator zusammen 4 Taktzyklen (Datenblatt lesen hilft aber auch :-)). Dann würde die Schleife rund 0.6 us brauchen, das sollte gehen. Debuggen mache ich meist mit RS232 oder LED's auf dem Zielboard, aber der Simulator ist auch ganz nett.
Ich probiere gerade mit anderen Taktfrequenzen herum. Wie es aussieht, liegt das Problem bei der Erkennung der IRQ-Flanke selbst. Bei 8 MHz wird ab und zu ein IRQ-Puls beim Pollen gar nicht erkannt. Bei 12 MHz funktioniert alles. Im Bild sieht man den Vergleich, unten mit 12 MHz und oben mit 8 MHz.
Ich habe jetzt noch eine 25µs Warteschleife nach dem IRQ Polling eingefügt. Funktioniert immer noch. Das FSK-Bit wird mit Sicherheit erst bei der nächsten L-H Flanke des IRQ eingelesen.
Jetzt habe ich mal von Polling auf INT umgestellt. Jetzt werden die Flanken zuverlässig erkannt. Bei 8 MHz und 19,2 kbit Datenrate braucht der Prozessor ca. 19 µs für die Routine. Zwischen den IRQ's liegen 52 µs. Bei 4 MHz funktioniert das zeitlich nicht mehr, da werden wieder ab und zu Bits ausgelassen. Da habe ich auf 9.6 kbit umgestellt und es ging wieder. Wenn du also die Bitrate entsprechend der Prozessorfrequenz anpasst, dann klappt das auch.
Frage: Hast Du die Flankenerkennung beim Polling mit dem Assemblercode oder mit der Bascom while-Schleife gemacht? Laut Bascomsimulator braucht die Bascom while-Schleife 15 Takte, die Assemblerschleife aber nur 4 (aus Interesse: wieviele Takte braucht AVR-GCC?). Das sollte nochmal ordentlich was bringen. Bitrate liegt bei mir irgendwo in der Gegend von 4.8 kbit/s, ist nach Deinen Messungen also auch bei 8 MHz kein Problem. Generell würde ich in meiner Anwendung aber gerne mit dem CPU Takt weiter runter (Richtung 1 MHz). Daher werde ich nochmal das 50 % Tastverhältnis beim NIRQ durch Senden von 0xD040 ausprobieren. Umschalten tut das Modul, gibt auf dem Oszi ein schönes Rechtecksignal. Noch besser wäre natürlich, wenn man auf das Polling komplett verzichten könnte und den Takt im uC erzeugen könnte. Wenn man dann die Daten noch per SDI raustaktet bräuchte man nur noch CS, SCK und SDI Leitung anschliessen.
Das Problem beim Polling mit niedrigen Frequenzen ist wohl, dass die IRQ's einfach ab und zu nicht mehr erkannt werden. Die Assemblerroutine würde das Problem verbessern, aber wahrscheinlich nicht komplett lösen. Nur das Verwenden des INT ist wohl die beste Lösung. Das mit dem 0xD040 habe ich schon probiert. Es wird nicht einfach das Tastverhältnis des IRQ geändert, sondern das Polling selbst. Nach einer steigenden Flanke musst du dann auf die fallende Flanke triggern. Sonst passt das zeitlich nicht mehr. Allerdings konnte ich damit nichts empfangen. Wer weiß was damit noch verstellt wurde. Könnte sein, das auch die Datenrate halbiert wurde oder irgend etwas anderes. Ich habe bis jetzt hier alles in Bascom programmiert. Auf dem IRQ würde ich aber nicht verzichten, damit funktioniert das zuverlässig.
Jetzt habe ich fast alles ausprobiert und insgesamt 6 verschiedene Versionen zum Funktionieren gebracht, dazu RFM12 mit 16 bit FIFO als Zugabe. Das sind: - Sendedaten an FSK oder SDI, - NIRQ Polling oder INT0 zur Sendesyncronisierung - Normale Datenrate oder "Halfrate-Mode" (0xD040) Folgende Erkenntnisse gibt es dazu: - NIRQ Polling funktioniert bei 8MHz und darunter nicht mehr zuverlässig, da der NIRQ Puls zu kurz ist - Die SDI-Routine ist etwas schneller als FSK - Bei normaler Datenrate reicht es auf die L-H Flanke des NIRQ zu warten - Im "Halfrate-Mode" ist das Tastverhältnis des NIRQ 50%, es muss allerdings die doppelte Datenrate des Empfängers eingestellt werden. Bei normaler Datenrate ergaben sich folgende Limits bezüglich AVR-Taktrate: - 1 MHz - 2,6 kbit - 2 MHz - 4,8 kbit - 4 MHz - 9,6 kbit - 8 MHz - 19,2 kbit - 12 MHz - 38,4 kbit - 16 MHz - 57,4 kbit Mit "Halfrate" kann die Datenrate sogar verdoppelt werden: - 4 MHz - 19,2 kbit - 16 MHz - 86,2 kbit Die im RFM02 eingestellte Datenrate ist dann die doppelte der o.g. Wichtige Anmerkung: Wer beim Empfänger die Routinen von Benedikt K./Fossie Bär verwendet, muss die Werte für die Baudrate exakt eintragen. Statt z.B. 19200 muss es 19157 sein, sonst wird ein anderer Wert berechnet und eingestellt. Im Beispiel hier sollte es 0xC611 (19157) sein, bei 19200 ist es aber 0xC610 (20,284 kbit).
Habe gerade meine Traumkonfiguration getestet: RFM02 per SCK, SDI und CS an den Mega. TX-Sync-Bit deaktiviert. Dann Datenübertragung mit 0xC6 angestossen und die Daten mit einer im uC-generierten Baudrate per SDI rausgeschickt. LÄUFT! I'am very happy. Dadurch, daß man das TX-Sync-Bit (Register C2) deaktiviert, sendet das RFM02 entsprechend auch keine Impulse auf NIRQ. Ich habe also auch keinerlei Synchronisationsprobleme. Da keine Pulse gepollt werden müssen, sollte man damit auch mit uC's mit niedrigen Quarzfrequenzen arbeiten können. Vielen Dank an Holger für die ganzen Tests!!!
mit bitwait statt while gehts auch unter 8 MHz ! gibt auch weniger Code :-)
Hallo Max, besten Dank für den Hinweis, gut möglich, daß ich das Polling für eine low power Variante (kleine Frequenz) ohne externen Quarz für die Taktrate mal brauchen werde. Viele Grüsse Klaus
By the way: Die Routine mit der eigenen Takterzeugung muss bei hohen Datenraten kalibriert werden, da die Schleife in der Senderroutine Zeit benötigt. Ich habe als pragramatisch dummen Ansatz den Vorladewert für den Timer in der Timer1_routine in einem Bereich um den berechneten Wert variiert. Man sieht dann mit Hilfe eines Empfängers, bei welchen Werten die ersten Übertragungsfehler beginnen und kann den Wert einfach auf die Mitte des Bereichs setzen. Bei niedrigen Übertragungsraten hatte ich damit keine Probleme. Beste Grüsse Klaus
Sorry guys i'm writing english below your german discussion... would you please bring me shematic of your successful Rfm01<==>RFm02 bascom code mr "Holger Sch" ? my email is dayaghi[at]gmail.com thanks a lot...
jetzt muss ich mal ganz dumm fragen was wird hir gesendet??? welcher wert????
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.