Forum: Mikrocontroller und Digitale Elektronik RFM12 empfangen durch Interrupt


von Mathias D. (darkfirefighter)


Lesenswert?

Hallo zusammen,

ich kann mit meinem RFM12 bereits empfangen allerdings blockiert mir das 
bisher den µC für andere Dinge. Deshalb wollte ich das empfangen 
Interrupt gesteuert machen. Beim lesen verschiedener Beiträge habe ich 
das so verstanden: Immer dann wenn nach 2D4D eine gewisse Anzahl x an 
Bytes im FIFO angekommen ist der nIRQ auf Low gezogen wird. Diesen Pin 
habe ich auf den INT0 meines Mega168 geklemmt.
Das Problem ist jetzt nur, dass kein Interrupt ausgelöst wird und auch 
der nIRQ dauernd auf Low ist. Leider habe ich noch aus keinem Beitrag 
entnehmen können welche Einstellungen ich genau zu machen habe.
Mein FIFO initialisiere ich mit
1
D = Spi16(0x82c8);
2
D = Spi16(0xca52);
Damit sollte ja nach 5 Byte der nIRQ auf Low gezogen werden oder?
Gesendet werden die Zahlen 12, 1, 0, 1, 12

Den Interrupt initialisiere ich folgendermaßen:
1
EIMSK |= (1<<INT0);
2
EICRA |= (1<<ISC01);
ISC01 = 1, da ich ja auf eine fallende Flanke reagieren will oder?

Meine Interruptroutine sieht so aus:
1
ISR(INT0_vect)
2
{
3
    PORTC |= (1<<PC4); //um zu sehen ob der Interrupt ausgelöst wurde
4
  
5
    for (N=1; N<=5; N++) //empfangen der 5 Byte
6
    {
7
      PORTB &= ~(1<<CS);
8
9
      D = Spi16(0xb000);
10
      data_in[N] = D;
11
    }
12
13
    D = Spi16(0x8208); //ausschalten und wieder einschalten des FIFO
14
    D = Spi16(0x82c8); //um weitern Empfang zu ermöglichen
15
    D = Spi16(0xca52);
16
}

Nur kommt es so leider nicht zu einem Interrupt.
Habe ich einen Denkfehler gemacht?
Wäre froh wenn ihr mir helfen könnt, da ich aus den vielen Beiträgen und 
Codeschnippseln die man so findet auch nicht schlau werde
Danke!

Grüße
Mathias

von Michael U. (amiga)


Lesenswert?

Hallo,

Mathias Dubdidu schrieb:
> Das Problem ist jetzt nur, dass kein Interrupt ausgelöst wird und auch
> der nIRQ dauernd auf Low ist. Leider habe ich noch aus keinem Beitrag
> entnehmen können welche Einstellungen ich genau zu machen habe.
> Mein FIFO initialisiere ich mit
>
1
> D = Spi16(0x82c8);
2
> D = Spi16(0xca52);
3
>
> Damit sollte ja nach 5 Byte der nIRQ auf Low gezogen werden oder?

Wo soll er die lassen? Er hat nur 16 BIT FIFO, Du mußt also jedes Byte 
abholen.
0xca81 ist sinnvoll.

Kannst ja hier mal reinschauen, läuft bei mir im Dauerbetrieb.

Beitrag "RFM12 Empfang von Sensordaten im IRQ"

Gruß aus Berlin
Michael

von STK500-Besitzer (Gast)


Lesenswert?

Ist es dein einziger Interrupt im Programm?
Hast du auch ein "SEI"?

von Mathias D. (darkfirefighter)


Lesenswert?

Michael U. schrieb:
> Hallo,
>
> Mathias Dubdidu schrieb:
>> Das Problem ist jetzt nur, dass kein Interrupt ausgelöst wird und auch
>> der nIRQ dauernd auf Low ist. Leider habe ich noch aus keinem Beitrag
>> entnehmen können welche Einstellungen ich genau zu machen habe.
>> Mein FIFO initialisiere ich mit
>>
1
>> D = Spi16(0x82c8);
2
>> D = Spi16(0xca52);
3
>>
>> Damit sollte ja nach 5 Byte der nIRQ auf Low gezogen werden oder?
>
> Wo soll er die lassen? Er hat nur 16 BIT FIFO, Du mußt also jedes Byte
> abholen.
> 0xca81 ist sinnvoll.

Ok das heißt mit 0xca81 würde er nach einem Byte mit nIRQ auf Low gehen 
und damit den Interrupt auslösen oder?
Und dann kann ich alles 5Byte nacheinander abhohlen


STK500-Besitzer schrieb:
>Ist es dein einziger Interrupt im Programm?
>Hast du auch ein "SEI"?

Ja ist mein einziger Interrupt habe auch ein sei()
direkt nach allen Initialisierungen und vor dem Aufruf der 
Endlosschleife

von Werner B. (werner-b)


Lesenswert?

Mathias Dubdidu schrieb:
1
...
2
> for (N=1; N<=5; N++) //empfangen der 5 Byte
3
>     {
4
>       PORTB &= ~(1<<CS);
5
> 
6
>       D = Spi16(0xb000);
7
>       data_in[N] = D;
8
>     }
9
...
Ich sehe da schon das nächste Problem...

Hinweis als Frage definiert:
Wie (gross) ist dein "data_in" definiert?
bzw. Was steht in data_in[0]?

von Mathias D. (darkfirefighter)


Angehängte Dateien:

Lesenswert?

Werner B. schrieb:
> Mathias Dubdidu schrieb:
>
1
> ...
2
>> for (N=1; N<=5; N++) //empfangen der 5 Byte
3
>>     {
4
>>       PORTB &= ~(1<<CS);
5
>>
6
>>       D = Spi16(0xb000);
7
>>       data_in[N] = D;
8
>>     }
9
> ...
10
>
> Ich sehe da schon das nächste Problem...
>
> Hinweis als Frage definiert:
> Wie (gross) ist dein "data_in" definiert?
> bzw. Was steht in data_in[0]?

data_in ist mit data_in[10] definiert. Den Eintrag bei Index 0 habe ich 
ausnahmsweise ignoriert, da ich das Programm von Bascom nach C übersetzt 
ist. (es handelt sich um das Programm aus der Elektor)
Das empfangen ansich funktioniert ja auch wenn ich andauernd die 
Empfangsfunktion aufrufe. Nur blockiert mir eben das dann den µC der 
eigentlich noch ein Lauflicht steuern soll. Ich habe mal das 
vollständige Programm angehängt.

von Michael U. (amiga)


Lesenswert?

Hallo,

Mathias Dubdidu schrieb:
> Michael U. schrieb:
>> Hallo,
>>
>> Mathias Dubdidu schrieb:
>>> Das Problem ist jetzt nur, dass kein Interrupt ausgelöst wird und auch
>>> der nIRQ dauernd auf Low ist. Leider habe ich noch aus keinem Beitrag
>>> entnehmen können welche Einstellungen ich genau zu machen habe.
>>> Mein FIFO initialisiere ich mit
>>>
1
>>> D = Spi16(0x82c8);
2
>>> D = Spi16(0xca52);
3
>>>
>>> Damit sollte ja nach 5 Byte der nIRQ auf Low gezogen werden oder?
>>
>> Wo soll er die lassen? Er hat nur 16 BIT FIFO, Du mußt also jedes Byte
>> abholen.
>> 0xca81 ist sinnvoll.
>
> Ok das heißt mit 0xca81 würde er nach einem Byte mit nIRQ auf Low gehen
> und damit den Interrupt auslösen oder?
> Und dann kann ich alles 5Byte nacheinander abhohlen

Nein. Rechne Dir aus, wie lange er bei Deiner Baudrate bracuhct, um 1 
Byte zu empfangen. Dann entscheide, ob Du per Polling in der ISR bleibst 
und auf die restlichen Bytes wartest (Abfrage des FIFO-Bits: SDI aof L, 
CS aktiv und SDO abfragen, bis es H wird -> FIFO-Byte da.
Wenn das Zeitverschwendung ist, hole das eine Byte ab, Du weist ja, 
wieviele Du sendest, also zwischenspeichern, Anzahl merken und eben auf 
den nächsten IRQ warten.
Wenn Du alle Bytes hast eben den FIFO neu starten.

Gruß aus Berlin
Michael

von Mathias D. (darkfirefighter)


Lesenswert?

Michael U. schrieb:
> Nein. Rechne Dir aus, wie lange er bei Deiner Baudrate bracuhct, um 1
> Byte zu empfangen. Dann entscheide, ob Du per Polling in der ISR bleibst
> und auf die restlichen Bytes wartest (Abfrage des FIFO-Bits: SDI aof L,
> CS aktiv und SDO abfragen, bis es H wird -> FIFO-Byte da.
> Wenn das Zeitverschwendung ist, hole das eine Byte ab, Du weist ja,
> wieviele Du sendest, also zwischenspeichern, Anzahl merken und eben auf
> den nächsten IRQ warten.
> Wenn Du alle Bytes hast eben den FIFO neu starten.


Ok der Befehl für die Baudrate ist ja dieser hier:
1
D = Spi16(0xc647)
das müssten dann 4,789kBd sein oder? Nach Wikipedia ist 1Bd = 
1Symbol/sekunde
Ist dann hier 1Symbol = 1Byte oder 1Bit?

Mein anderes Problem ist aber dass ich nicht mal in die ISR reinkomme. 
Wäre ich dann da drin würde ich per Polling bleiben und die restlichen 
Bytes abwarten

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
Noch kein Account? Hier anmelden.