Hallo Leute,
ich habe mir mal zwei Funkmodule (RFM12) von Pollin gekauft (433 MHz
Variante) und wollte nun Daten zwischen zwei ATmega32 austauschen
lassen. Ich habe folgenden Programmcode:
Für den Sender:
1
/*
2
* RFM12_Transmitter.c
3
*
4
* Created: 10.02.2014 15:15:02
5
* Author: Jens
6
*/
7
8
#define F_CPU 8000000UL
9
10
#include<avr/io.h>
11
#include<util/delay.h>
12
13
voidinit_SPI(void)
14
{
15
// Outputs: SSn, MOSI, SCK; Rest: inputs
16
DDRB|=(1<<PB4)|(1<<PB5)|(1<<PB7);
17
18
// Configure microcontroller as SPI-Master
19
SPCR=(1<<SPE)|(1<<MSTR)|(1<<SPR0);
20
}
21
22
// Function to write a command to the RFM12
23
unsignedintRF12_WRT_CMD(unsignedintaCmd)
24
{
25
unsignedinttemp;
26
27
PORTB&=~(1<<PB4);
28
29
// Write high byte
30
SPDR=(aCmd>>8)&0xff;
31
while(!(SPSR&(1<<SPIF)));
32
33
// Read high byte
34
temp=SPDR;
35
36
// Write low byte
37
SPDR=aCmd&0xff;
38
while(!(SPSR&(1<<SPIF)));
39
40
// Read low byte
41
temp=(temp<<8)|SPDR;
42
43
PORTB|=(1<<PB4);
44
45
return(temp);
46
}
47
48
voidinit_RFM12(void)
49
{
50
RF12_WRT_CMD(0x80D7);// EL, EF, 12.0 pF
51
RF12_WRT_CMD(0x8239);// !er, !ebb, ET, ES, EX, !eb, !ew, DC
Ich wollte zunächst mal den Empfänger einfach nur blinken lassen wenn
überhaupt irgendein Interrupt ausgelöst wird, es kommt also erstmal gar
nicht darauf an was gesendet wird. Leider tut sich garnichts.
Könnt ihr mir weiterhelfen? Achja, die Atmegas's laufen mit 8 MHz
externem Quarz.
Jens K. schrieb:> Hat sich noch keiner mit dem RFM12 beschäfftigt?
Nein, ich habe mich auch schon total darüber geärgert, dass man hier
über die Suche absolut nichts zum RFM12 findet.
Ist das mit dem INT bei Rising Edge richtig?
Ich bastle gerade an Assemblercode für RFM12 und habe im Kopf, dass das
Falling gewesen sein könnte.
Und verkabelt ist es richtig? Schaltplan? Foto?
Verkabelt ist alles richtig
ATmega RFM12
MOSI ------ SDI
MISO ------ SDO
SCK ------ SCK
SSn ------ nSEL
INT0 ------ nIRQ
Auf dem Oszi sehe ich auch das Daten ausgetauscht werden, doch leider
ist mein Oszi schon ziemlich alt und hat Probleme mit der Triggerung,
sodass ich die Packete nicht anschauen kann.
Ich habe jetzt die Initsequenzen etc. nicht genauer durchgearbeitet,
suche gerade eher nach ersten offensichtlichen Dingen.
Und mir sind noch zwei Dinge aufgefallen:
1)
Nach Power On muss man dem RFM 150ms (?) Zeit geben zur Initialisierung
bevor man SPI-Daten schickt.
Also vor dem InitRFM erstmal ein Delay einfügen.
2)
Ich erinnere mich, dass man unbedingt nach der Initsequenz das
Statusregister lesen muss.
Ich habe mich hier im Forum noch ein wenig umgeschaut und festgestellt,
dass das Datenblatt von Pollin scheinbar ziemlich falsch ist. Ich habe
mir nun einen Programming Guide von Hope RF heruntergeladen und dort
sind tatsächlich bei der Initialisierung einige Befehle anders. Der
Programming Guide ist nun allerdings für einen RFM12B und nicht für
einen RFM12, kann ich den Guide trotzdem verwenden?
ich weiß nicht ob zu 100 % aber ja!
ich glaube die unterscheiden sich nur was die Betriebsspannung angeht.
Vllt dem entsprechend sind die Sende und Empfangsleitungen anders.
Ich hatte damals aber auch in dem Hope dingen gestöbert.
(allerdings 8xx MHz)
Ich weiß nicht wie du debuggst... ich hatte damals alle möglichen
printf-ausgaben um zu sehen wo ich wann bin und wo es hängt...
das hat da für gesorgt, dass ich erst ein Jahr später mit dem erworbenen
logic analyser bemerkte dass diese Zeitfresser schuld waren das nichts
ging.
damals musste ich nur die printf alle entfernen und es funkte ^^
printf()'s habe ich nicht drin, aber ich habe nun einen Programming
Guide für den RFM12 gefunden.
Leider funktioniert die Kommunikation immer noch nicht. Beim Empfänger
wird einfach kein Interrupt ausgelöst, welcher signalisieren würde das
Daten da sind. Nun weiß ich natürlich nicht ob überhaupt etwas gesendet
wird und der Empfänger noch nicht richtig funktioniert oder ob der
Sender schon nicht richtig arbeitet.
Ich poste hier nochmal meinen überarbeiteten Code, programmiert nach dem
Guide von Hope:
Sender:
1
/*
2
* RFM12_Transmitter.c
3
*
4
* Created: 10.02.2014 15:15:02
5
* Author: Jens
6
*/
7
8
#define F_CPU 8000000UL
9
10
#include<avr/io.h>
11
#include<util/delay.h>
12
13
voidinit_SPI(void)
14
{
15
// Outputs: SSn, MOSI, SCK; Rest: inputs
16
DDRB|=(1<<PB4)|(1<<PB5)|(1<<PB7);
17
18
// Configure microcontroller as SPI-Master
19
SPCR=(1<<SPE)|(1<<MSTR)|(1<<SPR0);
20
}
21
22
// Function to write a command to the RFM12
23
unsignedintRF12_WRT_CMD(unsignedintaCmd)
24
{
25
unsignedinttemp;
26
27
// SSn low
28
PORTB&=~(1<<PB4);
29
30
// Write high byte
31
SPDR=(aCmd>>8)&0xff;
32
while(!(SPSR&(1<<SPIF)));
33
34
// Read high byte
35
temp=SPDR;
36
37
// Write low byte
38
SPDR=aCmd&0xff;
39
while(!(SPSR&(1<<SPIF)));
40
41
// Read low byte
42
temp=(temp<<8)|SPDR;
43
44
// SSn high
45
PORTB|=(1<<PB4);
46
47
return(temp);
48
}
49
50
voidinit_RFM12(void)
51
{
52
RF12_WRT_CMD(0x80D7);// EL, EF, 12.0 pF
53
RF12_WRT_CMD(0x8239);// !er, !ebb, ET, ES, EX, !eb, !ew, DC
Ich habe nun schon so viele Beiträge zu diesem Thema hier im Forum
gefunden, die mir aber leider nicht weitergeholfen habe. Es muss aber
doch jemanden hier geben der mir weiterhelfen kann?
Hallo Jens,
hier ein paar Dinge, die mir beim Sender in der main() Funktion
aufgefallen sind:
Wieso versendest du 2x 3 Preambles? Es reicht, wenn du 3 Preambles, dann
das lower und higher Byte für frame detection sendest (also genau so wie
du es auch am Anfang machst). Anschließend kommen die Datenbytes.
Die FIFO brauchst du hier nicht deaktivieren, da sie nur für das
Empfangen benötigt wird.
Die Initialisierung scheint mir in Ordnung zu sein (ich habe an manchen
Stellen andere Werte verwendet, aber die Befehle sind alle da :)
Beim Empfänger solltest du hier
// Read status register
RF12_WRT_CMD(0x0000);
// Read data
FIFO_data = RF12_WRT_CMD(0xB000);
noch ein while(PIND & (1<<PD2)); schreiben bevor du die FIFO liest,
ansonsten scheint hier alles in Ordnung zu sein.