www.mikrocontroller.net

Forum: Mikrocontroller und Elektronik RFM12 Interrupt gesteuert

Autor: Mann Nima (hitec)
Datum: 24.04.2009 09:15

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"""
Autor: Lorenz .. (lorenz)
Datum: 24.04.2009 09:52

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
Autor: Michael U. (amiga)
Datum: 24.04.2009 10:30
Angehängte Dateien:

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
Autor: Michael U. (amiga)
Datum: 24.04.2009 10:31
Angehängte Dateien:

Hallo,

hier noch das .h File dazu.

Gruß aus Berlin
Michael
Autor: Mann Nima (hitec)
Datum: 24.04.2009 13:02

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
Autor: Mann Nima (hitec)
Datum: 04.05.2009 11:08

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
Autor: Christoph (Gast)
Datum: 03.07.2009 16:50

@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
Autor: Michael U. (amiga)
Datum: 03.07.2009 17:43

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
Autor: Christoph Klein (hyla)
Datum: 04.07.2009 11:23

@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
Autor: Michael U. (amiga)
Datum: 04.07.2009 11:58
Angehängte Dateien:

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
Autor: Christoph Klein (hyla)
Datum: 04.07.2009 22:08

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
Autor: Michael U. (amiga)
Datum: 04.07.2009 22:25

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
Autor: Christoph Klein (hyla)
Datum: 04.07.2009 23:32

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
Autor: Michael U. (amiga)
Datum: 05.07.2009 09:56

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
Autor: Christoph Klein (hyla)
Datum: 05.07.2009 10:54

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
Autor: Michael U. (amiga)
Datum: 05.07.2009 11:18

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

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!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel




Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichungen und Screenshots im PNG- oder GIF-Format hochladen.
Siehe Bildformate

Hinweis: der Originalbeitrag ist mehr als 6 Monate alt.
Mit dem Abschicken erkennst du die Nutzungsbedingungen an.

webmaster@mikrocontroller.netImpressumNutzungsbedingungenWerbung auf Mikrocontroller.net