Forum: Mikrocontroller und Digitale Elektronik Funkübertragung mit zwei RFM12


von Robin L. (robin_l)


Lesenswert?

Hallo,

ich bin am basteln und habe mir zwei fast identische 
Mikocontroller-Boards mit jeweils einem PIC18F2550 aufgebaut. Die 
Jeweils eine SPI-Schnittstelle besitzen und einen USB-Anschluss.
Auf den PICs sind bereits die Bootloader gebrannt/geflashet.

nun habe ich zwei RFM12 Module an die zwei Boards angeschlossen und los 
programmiert.
Ich wollte es erreichen, dass durch das Drucken bei einer der beiden 
Platine die LED der anderen Platine an geschaltet wird.

Da ich noch nicht besonders gut im programmieren bin hoffe ich hier auf 
Unterstützung.
Wäre für jeden Tipp dankbar.
Anbei die Funktionen für die Schnittstelle sowie die main.c 's.

SPI
1
#include <delays.h>
2
#include <p18f2550.h>
3
4
5
#define NSEL_Set LATBbits.LATB2=1
6
#define NSEL_Clr LATBbits.LATB2=0
7
8
//Übertragung an Slave-16 Bit werden in 2 x 8 Bit übertragen
9
unsigned int WriteRFM(unsigned int  data_in){
10
    // unsigned int continous = 0;
11
    unsigned int dataReturn[2];
12
    unsigned int data_out;
13
    unsigned char data1_write[2];
14
    data1_write[1] = data_in & 0xff;
15
    data1_write[0] = data_in >> 8;
16
    NSEL_Clr;
17
18
    dataReturn[0] = SSPBUF; // byte aus buffer lesen
19
    PIR1bits.SSPIF = 0;     //Clear interrupt flag
20
    SSPCON1bits.WCOL = 0;       //Clear any previous write collision
21
    SSPBUF = data1_write[0]; // byte in buffer schreiben
22
    while(!(PIR1bits.SSPIF)); //wait until cycle complete
23
    dataReturn[0] = SSPBUF; // byte aus buffer lesen
24
25
    PIR1bits.SSPIF = 0;     //Clear interrupt flag
26
    SSPCON1bits.WCOL = 0;       //Clear any previous write collision
27
    SSPBUF = data1_write[1]; // byte in buffer schreiben
28
    while(!(PIR1bits.SSPIF)); //wait until cycle complete
29
    dataReturn[1] = SSPBUF; // byte aus buffer lesen
30
31
    NSEL_Set;
32
    data_out = (unsigned int)dataReturn[0] <<8 | (unsigned int)dataReturn[1];
33
    return data_out;
34
}
35
36
unsigned char CheckTXBuffer(void){
37
    unsigned char a;
38
    NSEL_Clr;
39
    a=PORTBbits.RB0;
40
    NSEL_Set;
41
    return(a);
42
}
43
44
45
void RFMinit(void){
46
    ADCON1 |= 0x0F; //Set I/0-Pins to default
47
                                            //TRIS -> 0 = Ausgange, 1= Eingang
48
                                            //LAT  -> 1 = Setzen auf 5V
49
    TRISBbits.TRISB0=1; // SDI
50
    TRISBbits.TRISB1=0; // CLK
51
    TRISBbits.TRISB2=0; // NSEL
52
    TRISBbits.TRISB3=0; // LED
53
    TRISBbits.TRISB4=0; // LED 2
54
    //TRISBbits.TRISB4=0; // Connect Key  // Connect Key is on RB5 on new hardware
55
    TRISBbits.TRISB5=1; // Connect Key  // Connect Key is on RB5 on new hardware
56
    TRISCbits.TRISC2=1; // Boot key
57
    TRISCbits.TRISC7=0; // SDO
58
59
    LATBbits.LATB3=1;  //Controller AN
60
    //LATBbits.LATB4=1;
61
    NSEL_Set;
62
63
    //SPI Initialisieren PIC
64
    SSPSTAT = 0xC0;     // Data Sampled at End of data output time
65
                        // Transmit occurs on transition 0->1
66
    SSPCON1 = 0x21;     // SSPEN=1, Clock Idle is low,
67
                        // SPI-Master Fosc/16 = 48Mhz/16= 3 MHz
68
                        // => 333 ns Periodendauer
69
70
    Delay1KTCYx (10);
71
72
    // Einstellungen wurden noch nicht angepasst
73
    WriteRFM(0x80E7);   // Configuration Command
74
                        // EL = 1, EF = 1, 868 MHz, 12 pF
75
    WriteRFM(0x8239);   // Power Mangement Command
76
                        // ER=0, EBB=0, ET=1, ES=1, EX=1, EB=0, EW=0, DC=1
77
    WriteRFM(0xA640);   // Frequency Setting Command
78
                        // 0x640=1600 => 860Mhz+1600*0.005Mhz = 868 MHz
79
    WriteRFM(0xC611);   // Data Rate Command
80
                        // CS=0, Baudrate=10MHz/(29*(0x11+1))=19.2kbps
81
    WriteRFM(0x94A0);   // Receiver Control Command
82
                        // VDI enable, Fast VDI, 134 kHz Bandbase, 
83
                        // LNA gain 0 dBm, DRSSI threshold -103 dBm
84
    WriteRFM(0xC2AC);   // Data Filter Command
85
                        // AL=1, ML=0, Digital Filter select,
86
                        // DQD-Threshold = 4
87
    WriteRFM(0xCA01);   // FIFO and Reset Mode Command
88
                        // FIFO interrupt at 8 Bytes, SYNC-Word enable
89
                        // SYNC-Length = 2 Byte (2DD4), FF=0 (Sync Reset), DR=1
90
    WriteRFM(0xC483);   // AFC Command
91
                        // Keep f_offset only during receiving, No Range limit
92
                        // ST=0, FI=0, OE=1, EN=1
93
    WriteRFM(0x9850);   // TX Configuration Command
94
                        // MP=0, 00kHz deviation, Output Power 0dBm
95
    WriteRFM(0xE000);   // Wake-Up Timer Command
96
                        // Time=0
97
    WriteRFM(0xC800);   // Low Duty-Cycle Command
98
                        // Disable Duty-Cycle
99
    WriteRFM(0xC040);   // Low Battery Detector and µC Clock Divider
100
                        // Clock = 1.66 MHz, Vbat=2.25 V
101
102
103
}
104
/*****************************************************************************/
105
/* RFM12_SetBandwidth                                                        */
106
/*                                                                           */
107
/* Set bandwidth.                                                            */
108
/*                                                                           */
109
/* bandwidth:  Baseband Bandwidth [kHz]                                      */
110
/*             0 .. reserved                                                 */
111
/*             1 .. 400 kHz                                                  */
112
/*             2 .. 340 kHz                                                  */
113
/*             3 .. 270 kHz                                                  */
114
/*             4 .. 200 kHz                                                  */
115
/*             5 .. 134 kHz                                                  */
116
/*             6 .. 67 kHz                                                   */
117
/*             7 .. reserved                                                 */
118
/* gain:       LNA gain (dBm)                                                */
119
/*             0 .. 0 dBm                                                    */
120
/*             1 .. -6 dBm                                                   */
121
/*             2 .. -14 dBm                                                  */
122
/*             3 .. -20 dBm                                                  */
123
/* drssi:      RSSIsetth [dBm]                                               */
124
/*             0 .. -103 dBm                                                 */
125
/*             1 .. -97 dBm                                                  */
126
/*             2 .. -91 dBm                                                  */
127
/*             3 .. -85 dBm                                                  */
128
/*             4 .. -79 dBm                                                  */
129
/*             5 .. -73 dBm                                                  */
130
/*             6 .. reserved                                                 */
131
/*             7 .. reserved                                                 */
132
/*                                                                           */
133
/* Return:  none                                                             */
134
/*****************************************************************************/
135
void RFM12_SetBandwidth(unsigned int bandwidth, unsigned int gain, unsigned int drssi)
136
{
137
    WriteRFM(0x9400|((bandwidth&7)<<5)|((gain&3)<<3)|(drssi&7));
138
}
139
/*****************************************************************************/
140
/* RFM12_SetFreq                                                             */
141
/*                                                                           */
142
/* Set frequency. Use RFM12FREQ macro to convert frequency to proper value.  */
143
/*                                                                           */
144
/* freq:  RFM12 frequency for wireless communication                         */
145
/*        Example usage: RFM12_SetFreq(RFM12FREQ(430.2400MHz));              */
146
/*        Possible frequency values: 430.2400MHz .. 439.7575MHz              */
147
/*                                                                           */
148
/* Return:  none                                                             */
149
/*****************************************************************************/
150
void RFM12_SetFreq(unsigned int freq)
151
{
152
    /* 430.2400MHz */
153
    if (freq < 96)
154
    {
155
        freq = 96;
156
    }
157
    /* 439.7575MHz */
158
    else if (freq > 3903)
159
    {
160
        freq = 3903;
161
    }
162
    WriteRFM(0xA000 | freq);
163
}
164
165
/*****************************************************************************/
166
/* RFM12_SetBaud                                                             */
167
/*                                                                           */
168
/* Set baudrate.                                                             */
169
/*                                                                           */
170
/* baud:  desired baudrate                                                   */
171
/*                                                                           */
172
/* Return:  none                                                             */
173
/*****************************************************************************/
174
void RFM12_SetBaud(unsigned int baud)
175
{
176
    if (baud < 663)
177
    {
178
        return;
179
    }
180
181
    /* Baudrate= 344827,58621/(R+1)/(1+CS*7) */
182
    if (baud < 5400)
183
    {
184
        WriteRFM(0xC680|((43104/baud)-1));
185
    }
186
    else
187
    {
188
        WriteRFM(0xC600|((344828UL/baud)-1));
189
    }
190
}
191
192
193
/*****************************************************************************/
194
/* RFM12_SetPower                                                            */
195
/*                                                                           */
196
/* Set output power.                                                         */
197
/*                                                                           */
198
/* power:  output power                                                      */
199
/*         0 .. 0 dBm (1mW)                                                  */
200
/*         1 .. -3 dBm (501 µW)                                              */
201
/*         2 .. -6 dBm (251 µW)                                              */
202
/*         3 .. -9 dBm (126 µW)                                              */
203
/*         4 .. -12 dBm (63 µW)                                              */
204
/*         5 .. -15 dBm (32 µW)                                              */
205
/*         6 .. -18 dBm (16 µW)                                              */
206
/*         7 .. -21 dBm (8 µW)                                               */
207
/* mod:    frequency deviation                                               */
208
/*         0 .. 15 kHz                                                       */
209
/*         1 .. 30 kHz                                                       */
210
/*         2 .. 45 kHz                                                       */
211
/*         3 .. 60 kHz                                                       */
212
/*         4 .. 75 kHz                                                       */
213
/*         5 .. 90 kHz                                                       */
214
/*         6 .. 105 kHz                                                      */
215
/*         7 .. 120 kHz                                                      */
216
/*         8 .. 135 kHz                                                      */
217
/*         9 .. 150 kHz                                                      */
218
/*         10 .. 165 kHz                                                     */
219
/*         11 .. 180 kHz                                                     */
220
/*         12 .. 195 kHz                                                     */
221
/*         13 .. 210 kHz                                                     */
222
/*         14 .. 225 kHz                                                     */
223
/*         15 .. 240 kHz                                                     */
224
/*                                                                           */
225
/* Return:  none                                                             */
226
/*****************************************************************************/
227
void RFM12_SetPower(unsigned int power, unsigned int mod)
228
{
229
    WriteRFM(0x9800|(power&7)|((mod&15)<<4));
230
}
231
232
/*****************************************************************************/
233
/* RFM12_TxData                                                              */
234
/*                                                                           */
235
/* Transmit data via RFM12 wireless tranceiver module.                       */
236
/*                                                                           */
237
/* data:   pointer to data buffer to be transmitted                          */
238
/* length: data buffer length                                                */
239
/*                                                                           */
240
/* Return:  none                                                             */
241
/*****************************************************************************/
242
void RFM12_TxData(unsigned int *data, unsigned int length)
243
{
244
    unsigned int i;
245
246
    /* enable TX */
247
    WriteRFM(0x8238);
248
249
    /* send preamble (0xAA) */
250
    Delay1KTCYx(7);   // Warte 581 us
251
    while(CheckTXBuffer()==0);  //Warten, bis Sendebuffer frei
252
    WriteRFM(0xB8AA);
253
    Delay1KTCYx(5);   // Warte 416 us
254
    while(CheckTXBuffer()==0);  //Warten, bis Sendebuffer frei
255
    WriteRFM(0xB8AA);
256
    Delay1KTCYx(5);   // Warte 416 us
257
    while(CheckTXBuffer()==0);  //Warten, bis Sendebuffer frei
258
    WriteRFM(0xB8AA);
259
260
    /* send sync word 0x2DD4 */
261
    Delay1KTCYx(5);   // Warte 416 us
262
    while(CheckTXBuffer()==0);  //Warten, bis Sendebuffer frei
263
    WriteRFM(0xB82D);
264
    Delay1KTCYx(5);   // Warte 416 us
265
    while(CheckTXBuffer()==0);  //Warten, bis Sendebuffer frei
266
    WriteRFM(0xB8D4);
267
268
    /* send data buffer */
269
    for (i=0; i < length; i++)
270
    {
271
        Delay1KTCYx(5);   // Warte 416 us
272
        while(CheckTXBuffer()==0);  //Warten, bis Sendebuffer frei
273
        WriteRFM(0xB800|(*data++));
274
    }
275
276
    /* transmit 2 dummy bytes to avoid that last bytes of real payload don't */
277
    /* get transmitted properly (due to transmitter disabled to early) */
278
    Delay1KTCYx(5);   // Warte 416 us
279
    while(CheckTXBuffer()==0);  //Warten, bis Sendebuffer frei
280
    WriteRFM(0xB800);
281
    Delay1KTCYx(5);   // Warte 416 us
282
    while(CheckTXBuffer()==0);  //Warten, bis Sendebuffer frei
283
    WriteRFM(0xB800);
284
285
    /* disable TX */
286
    WriteRFM(0x8208);
287
}
288
289
/*****************************************************************************/
290
/* RFM12_TxData                                                              */
291
/*                                                                           */
292
/* Receive data via RFM12 wireless tranceiver module.                        */
293
/*                                                                           */
294
/* data:   pointer to data buffer to be received                             */
295
/* length: number of bytes to be received                                    */
296
/*                                                                           */
297
/* Return:  none                                                             */
298
/*****************************************************************************/
299
void RFM12_RxData(unsigned int *data, unsigned int length)
300
{
301
    unsigned int i;
302
303
    /* enable RX */
304
    WriteRFM(0x82C8);
305
306
    /* set FIFO mode */
307
    WriteRFM(0xCA81);
308
309
    /* enable FIFO */
310
    WriteRFM(0xCA83);
311
312
    //delay_us(3);
313
    for (i=0; i < length; i++)
314
    {
315
        *data++ = WriteRFM(0x0000);
316
    }
317
318
    /* disable RX */
319
    WriteRFM(0x8208);
320
}

main-des ersten Boards
1
/** I N C L U D E S **********************************************************/
2
#include <p18f2550.h>
3
#include <delays.h>
4
#include "rfm12.h"
5
6
7
8
/** V A R I A B L E S ********************************************************/
9
#pragma udata
10
unsigned char data;
11
/** P R I V A T E  P R O T O T Y P E S ***************************************/
12
13
/** V E C T O R  R E M A P P I N G *******************************************/
14
15
extern void _startup (void);        // See c018i.c in your C18 compiler dir
16
#pragma code _RESET_INTERRUPT_VECTOR = 0x000800
17
void _reset (void)
18
{
19
    _asm goto _startup _endasm
20
}
21
#pragma code
22
23
#pragma code _HIGH_INTERRUPT_VECTOR = 0x000808
24
void _high_ISR (void)
25
{
26
    ;
27
}
28
29
#pragma code _LOW_INTERRUPT_VECTOR = 0x000818
30
void _low_ISR (void)
31
{
32
    ;
33
}
34
35
/** D E C L A R A T I O N S **************************************************/
36
#pragma code
37
38
//------------------------------------------------------------------------------
39
    //Main
40
//------------------------------------------------------------------------------
41
42
void main(void)
43
{
44
    unsigned int data_out;
45
    //RFM012 &SPI Inizalisierung
46
    RFMinit();
47
    Delay1KTCYx (10);   // Warte x * 1000 Instructioncycles
48
                        // = 10*1000*1/(48Mhz/4)=10*83.3 µs = 833 µs
49
50
    while(1){
51
        // Das Senden eines Bytes (8 Bit) dauert bei 19.2 kbps etwa 416 µs
52
        if(PORTBbits.RB5)       //Taste Connect
53
        {
54
            data_out=0x00; //Send 0x00 (Taste nicht gedrückt)
55
        }
56
        else
57
        {
58
            data_out=0x01; //Send 0x01 (Taste gedrückt)
59
        }
60
        RFM12_TxData(data_out,1);
61
        Delay1KTCYx(100);   // Warte 80 ms
62
  };
63
}//end main

main des zweiten Boards
1
#include <p18f2550.h>
2
#include <delays.h>
3
#include "rfm12.h"
4
5
6
7
/** V A R I A B L E S ********************************************************/
8
#pragma udata
9
unsigned char data;
10
/** P R I V A T E  P R O T O T Y P E S ***************************************/
11
12
/** V E C T O R  R E M A P P I N G *******************************************/
13
14
extern void _startup (void);        // See c018i.c in your C18 compiler dir
15
#pragma code _RESET_INTERRUPT_VECTOR = 0x000800
16
void _reset (void)
17
{
18
    _asm goto _startup _endasm
19
}
20
#pragma code
21
22
#pragma code _HIGH_INTERRUPT_VECTOR = 0x000808
23
void _high_ISR (void)
24
{
25
    ;
26
}
27
28
#pragma code _LOW_INTERRUPT_VECTOR = 0x000818
29
void _low_ISR (void)
30
{
31
    ;
32
}
33
34
/** D E C L A R A T I O N S **************************************************/
35
#pragma code
36
37
//------------------------------------------------------------------------------
38
    //Main
39
//------------------------------------------------------------------------------
40
41
void main(void)
42
{
43
    unsigned int TempVar;
44
    unsigned int *data_in;
45
    //RFM012 &SPI Inizalisierung
46
    RFMinit();
47
    Delay1KTCYx (10);   // Warte x * 1000 Instructioncycles
48
                        // = 10*1000*1/(48Mhz/4)=10*83.3 µs = 833 µs
49
50
    while(1){
51
        // Das Senden eines Bytes (8 Bit) dauert bei 19.2 kbps etwa 416 µs
52
        RFM12_RxData(data_in,1);
53
        if(*data_in == 0x01)       //Taste Boot
54
        {
55
            LATBbits.LATB3 = 1;
56
        }
57
        else
58
        {
59
            LATBbits.LATB3 = 0;
60
        }
61
        
62
        Delay1KTCYx(100);   // Warte 80 ms
63
  };
64
}//end main

von Holger W. (holgerw)


Lesenswert?

Was ist jetzt dein Problem ?
Funktioniert denn die Kommunikation zw. PIC und dem RFM12 ?

Holger

von Robin L. (robin_l)


Lesenswert?

Hallo,
ach total vergessen!
Ja die funktioniert!!
Kann Statusbits und Empfangbits auslesen.
Jedoch die Funkübertragung klappt nicht...
Drücke ich den Taster so passiert nichts.

von Holger W. (holgerw)


Lesenswert?

Leg mal die Baudrate fest, ich hatte Probleme mit der Berechnung, z.b.
case 4800    :   RFM12_trans(0xC647);         //  4800 Baud

Holger

von Holger W. (holgerw)


Lesenswert?

Wo rufst du denn z.b. RFM12_SetFreq und andere auf ? kann es nicht 
finden.
Die Frequenz wird auch in dem Beispiel von Benedikt in einem Makro 
umgerechnet, wie machst du das ?

Die Init sieht bei mir auch etwas anders aus:
RFM12_trans(0x0000);        // Status lesen (u.a. nIRQ löschen)
    RFM12_trans(0x80D7);            // Enable FIFO
    RFM12_trans(0xC2AB);            // Data Filter: internal
    RFM12_trans(0xCA81);            // Set FIFO mode
    RFM12_trans(0xE000);            // disable wakeuptimer
    RFM12_trans(0xC800);            // disable low duty cycle
    RFM12_trans(0xC4F7);            // AFC settings: autotuning: 
-10kHz...+7,5kHz
//    RFM12_trans(0xC0E0);            // CLK: 10MHz


dazu dann noch Frequenz, Baudrate und Power/Gain.

Holger

von Robin L. (robin_l)


Lesenswert?

Das habe ich bereits schon versucht (siehe RFMinit()).
1
 WriteRFM(0xC611);   // Data Rate Command
2
                        // CS=0, Baudrate=10MHz/(29*(0x11+1))=19.2kbps

Momentan benötige ich die Funktionen für die Bautrate und Co nicht.
da ich alles in der RFMinit() festlege.

von Holger W. (holgerw)


Lesenswert?

Dein Empfang ist auch etwas merkwürdig.
Der RFM12 muss in den Empfangsmodus versetzt werden.
Dann müsstest du den SPI Empfang pollen oder im IRQ abfragen und die 
Bytes einlesen.
Du musst aber noch ein Protokoll implementieren, damit du weisst wann 
die Übertragung beginnt / aufhört.
Ich mache Software SPI und kann dir bei SPI direkt nicht helfen.

Holger

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.