Forum: Mikrocontroller und Digitale Elektronik RFM12 Rutine Hängt beim warten auf FIFO


von Sonke A. (soeni)


Lesenswert?

Ich nutze die Testrutine von hier: 
Beitrag "Beispielprogramm für RFM12 433MHz Funk-Module"
die find ich auch recht übersichtlich, entsprechende sachen kann man 
einstellen usw. nur leider bleibt die rutine immer hängen und zwar beim 
senden, an der folgenden Stelle:
1
void rf12_ready(void)
2
{  cbi(RF_PORT, CS);
3
  while (!(RF_PIN&(1<<SDO))); // wait until FIFO ready
4
}

Warum wird den mein Fifo nicht fertig? bzw. was passiert da?

CS wird gesetzt (ich denke mal das soll Chip Select sein ind ist somit 
mit nSel vom Funkplatinchen verbunden.)

Wo kan der fehler liegen?


EDIT:

zur ergänzung hab einen Atmega128 und der Port B wird da benutzt

#define SDI    3
#define SCK    1
#define CS    0  // nsel?
#define SDO    2

von Jean P. (fubu1000)


Lesenswert?

Sönke Paschko wrote:

> [c]
> void rf12_ready(void)
> {  cbi(RF_PORT, CS);
>   while (!(RF_PIN&(1<<SDO))); // wait until FIFO ready
> }

OK, sofern RF_PIN, PINB entspricht.


> #define SDI    3
> #define SCK    1
> #define CS    0  // nsel?
> #define SDO    2

Falsch, ersetzen durch :

#define SDI 2
#define SCK 1
#define CS 0
#define SDO 3

Gruß

von Sonke A. (soeni)


Lesenswert?

Hm
danke

also

ich schließe das Modul wiefolgt an:

Modul   Mega128
SDI     PORTB 2
SDO     PORTB 3
SCK     PORTB 1
CS      PORTB 0

+ widerstand

wenn ich jetzt die anschlüsse vertausche und die portbits passiert 
wieder nix.

oder hab ich mir das modul damit schon zerschossen?

von Jean P. (fubu1000)


Lesenswert?

Hi,
ich habe keine Ahnung was du mit deinen Sätzen mir sagen willst.
Du solltest nur die #defines ändern.
Am besten du postest mal nen Schaltplan und deinen gesamten Code.
Meinetwegen pass ich den dann schnell an.

N8

von Sonke A. (soeni)


Angehängte Dateien:

Lesenswert?

Hallo,

im anhang der Schaltplan.

An der Pinhead sitzt der uC mit den entsprechenden Ports. ich hoffe das 
ist gut genug beschriftet.

Nun meintest du doch das ich die SDI und SDO vertauschen soll?!?

PS: der widerstand ist noch nicht eingetragen, aber in der Schaltung 
vorhanden (1k)

von Jean P. (fubu1000)


Lesenswert?

OMG,
wo fängt man an.
1.) PB3 und PB2 in deiner Schaltung ist vertauscht. Beide Anschlüsse am 
RFM12 wechseln.
2.) nFFS mit 10k gegen VCC schalten.
3.) Poste deinen gesamten Code nach dem umlöten der obengenannten Punkte 
und Schaltplan am besten dazu nochmal.

Gruß

von Sonke A. (soeni)


Lesenswert?

Hi, danke für deine Mühen,

wie schon gesagt, nffs hängt schon über 1k an vcc sind da wirklich 10 
notwendig?
1
/// Auszug aus int main
2
  #include <avr/interrupt.h>
3
  #include <avr/io.h>
4
  #include <avr/pgmspace.h>
5
  #include <stdint.h>
6
  #include <stdio.h>
7
  #include <stdlib.h>
8
  #include <string.h>
9
  #include <util/delay.h> 
10
// ...
11
DDRB = 0b01001011;  // Eingang Encoder / Funkmodul
12
13
14
/// Auszug aus der Headerdatei
15
#define RF12FREQ(freq)  ((freq-430.0)/0.0025)              // macro for calculating frequency value out of frequency in MHz
16
17
#ifndef cbi
18
#define cbi(sfr, bit)     (_SFR_BYTE(sfr) &= ~_BV(bit)) 
19
#endif
20
#ifndef sbi
21
#define sbi(sfr, bit)     (_SFR_BYTE(sfr) |= _BV(bit))  
22
#endif
23
24
25
// Die eigendlichen Funktionen (Übernommen aus dem oben genannten Beitrag)
26
27
28
29
#define RF_PORT  PORTB
30
#define RF_DDR  DDRB
31
#define RF_PIN  PINB
32
33
#define SDI    2
34
#define SCK    1
35
#define CS    0  // nsel?
36
#define SDO    3
37
38
unsigned short rf12_trans(unsigned short wert)
39
{  unsigned short werti=0;
40
  unsigned char i;
41
42
  cbi(RF_PORT, CS);
43
  for (i=0; i<16; i++)
44
  {  if (wert&32768)
45
      sbi(RF_PORT, SDI);
46
    else
47
      cbi(RF_PORT, SDI);
48
    werti<<=1;
49
    if (RF_PIN&(1<<SDO))
50
      werti|=1;
51
    sbi(RF_PORT, SCK);
52
    wert<<=1;
53
    _delay_us(0.3);
54
    cbi(RF_PORT, SCK);
55
  }
56
  sbi(RF_PORT, CS);
57
  return werti;
58
}
59
60
void rf12_init(void)
61
{       // Auskommentiert weil bereits in der int main geschehen
62
  //RF_DDR=(1<<SDI)|(1<<SCK)|(1<<CS);
63
  RF_PORT=(1<<CS);
64
65
  //for (unsigned char i=0; i<10; i++)
66
    _delay_ms(100);      // wait until POR done
67
68
  rf12_trans(0xC0E0);      // AVR CLK: 10MHz
69
  rf12_trans(0x80D7);      // Enable FIFO
70
  rf12_trans(0xC2AB);      // Data Filter: internal
71
  rf12_trans(0xCA81);      // Set FIFO mode
72
  rf12_trans(0xE000);      // disable wakeuptimer
73
  rf12_trans(0xC800);      // disable low duty cycle
74
  rf12_trans(0xC4F7);      // AFC settings: autotuning: -10kHz...+7,5kHz
75
}
76
77
void rf12_setbandwidth(unsigned char bandwidth, unsigned char gain, unsigned char drssi)
78
{
79
  rf12_trans(0x9400|((bandwidth&7)<<5)|((gain&3)<<3)|(drssi&7));
80
}
81
82
void rf12_setfreq(unsigned short freq)
83
{  if (freq<96)        // 430,2400MHz
84
    freq=96;
85
  else if (freq>3903)      // 439,7575MHz
86
    freq=3903;
87
  rf12_trans(0xA000|freq);
88
}
89
90
void rf12_setbaud(unsigned short baud)
91
{
92
  if (baud<663)
93
    return;
94
  if (baud<5400)          // Baudrate= 344827,58621/(R+1)/(1+CS*7)
95
    rf12_trans(0xC680|((43104/baud)-1));
96
  else
97
    rf12_trans(0xC600|((344828UL/baud)-1));
98
}
99
100
void rf12_setpower(unsigned char power, unsigned char mod)
101
{  
102
  rf12_trans(0x9800|(power&7)|((mod&15)<<4));
103
}
104
105
void rf12_ready(void)
106
{  cbi(RF_PORT, CS);
107
  while (!(RF_PIN&(1<<SDO))); // wait until FIFO ready
108
  //_delay_ms(10);
109
}
110
111
void rf12_txdata(unsigned char *data, unsigned char number)
112
{  unsigned char i;
113
  rf12_trans(0x8238);      // TX on
114
  rf12_ready();
115
  rf12_trans(0xB8AA);
116
  rf12_ready();
117
  rf12_trans(0xB8AA);
118
  rf12_ready();
119
  rf12_trans(0xB8AA);
120
  rf12_ready();
121
  rf12_trans(0xB82D);
122
  rf12_ready();
123
  rf12_trans(0xB8D4);
124
  for (i=0; i<number; i++)
125
  {    rf12_ready();
126
    rf12_trans(0xB800|(*data++));
127
  }
128
  rf12_ready();
129
  rf12_trans(0x8208);      // TX off
130
}
131
132
void rf12_rxdata(unsigned char *data, unsigned char number)
133
{  unsigned char i;
134
  rf12_trans(0x82C8);      // RX on
135
  rf12_trans(0xCA81);      // set FIFO mode
136
  rf12_trans(0xCA83);      // enable FIFO
137
  for (i=0; i<number; i++)
138
  {  rf12_ready();
139
    *data++=rf12_trans(0xB000);
140
  }
141
  rf12_trans(0x8208);      // RX off
142
}
143
144
145
146
147
148
149
150
151
unsigned char * receive(void)
152
{  
153
  unsigned char test[32];  
154
  rf12_rxdata(test,32);  
155
  // daten verarbeiten
156
  return test;
157
}
158
159
void send(void)
160
{  unsigned char test[]="Dies ist ein 433MHz Test !!!\n   ";  
161
  rf12_txdata(test,32);
162
}
163
164
165
166
167
168
169
170
171
// Testfunktionen
172
173
void funk_sendetest(void){
174
175
176
  rf12_init();          // ein paar Register setzen (z.B. CLK auf 10MHz)
177
  rf12_setfreq(RF12FREQ(433.92));  // Sende/Empfangsfrequenz auf 433,92MHz einstellen
178
  rf12_setbandwidth(4, 1, 4);    // 200kHz Bandbreite, -6dB Verstärkung, DRSSI threshold: -79dBm 
179
  rf12_setbaud(19200);      // 19200 baud
180
  rf12_setpower(0, 6);      // 1mW Ausgangangsleistung, 120kHz Frequenzshift
181
182
  
183
  //unsigned char i=0;
184
  unsigned char i=0;
185
186
187
  // Displayausgabe
188
  lcd_clear();
189
  set_cursor(0,1);
190
191
  uart_puts("\r\n\r\n   Funktest Senden: \r\n");      // Ausgabe UART
192
  lcd_string("Funktest Senden:   ESC=exit");  // Ausgabe LCD
193
   
194
  set_cursor(0,2);
195
196
  while(uart_ask() != 27){   // kein Escape gedrückt  ??
197
198
    if(!ENCODERTAST) {
199
        
200
      beep_short();    // Kurz piepen
201
      _delay_ms(500);
202
      return;      // Programmabbruch
203
    }
204
  
205
206
    if(i>10){
207
      set_cursor(0,2);
208
      lcd_string("                ");// Zeile löschen
209
      set_cursor(0,2);
210
      i=0;
211
    }
212
    
213
    i++;
214
215
      
216
      lcd_string("-");
217
      send();
218
      _delay_ms(1000);
219
220
221
                    
222
223
    }
224
225
226
227
228
}
229
230
231
232
233
234
235
236
// 
237
238
void funk_empfangtest(void){
239
240
241
  rf12_init();          // ein paar Register setzen (z.B. CLK auf 10MHz)
242
  rf12_setfreq(RF12FREQ(433.92));  // Sende/Empfangsfrequenz auf 433,92MHz einstellen
243
  rf12_setbandwidth(4, 1, 4);    // 200kHz Bandbreite, -6dB Verstärkung, DRSSI threshold: -79dBm 
244
  rf12_setbaud(19200);      // 19200 baud
245
  rf12_setpower(0, 6);      // 1mW Ausgangangsleistung, 120kHz Frequenzshift
246
247
  
248
  //unsigned char i=0;
249
  unsigned char i=0;
250
  unsigned char * Text;
251
252
253
  // Displayausgabe
254
  lcd_clear();
255
  set_cursor(0,1);
256
257
  uart_puts("\r\n\r\n   Funktest Empfang: \r\n");      // Ausgabe UART
258
  lcd_string("Funktest Empfang:  ESC=exit");  // Ausgabe LCD
259
   
260
  set_cursor(0,2);
261
262
  while(uart_ask() != 27){   // kein Escape gedrückt  ??
263
264
    if(!ENCODERTAST) {
265
        
266
      beep_short();    // Kurz piepen
267
      _delay_ms(500);
268
      return;      // Programmabbruch
269
    }
270
  
271
272
    if(i>10){
273
      set_cursor(0,2);
274
      lcd_string("                ");// Zeile löschen
275
      set_cursor(0,2);
276
      i=0;
277
    }
278
    
279
    i++;
280
281
      
282
    Text = receive();
283
    set_cursor(0,3);
284
    lcd_string(Text);
285
      
286
287
288
                    
289
290
    }
291
292
293
294
295
}


so das wars denke ich

von Urs (Gast)


Lesenswert?

Nach meiner Erfahrnung MUSS das nFFS Pin des RFM12 Moduls mittels eines 
nicht zu kleinen Pull-Ups auf High gesetzt werden, um einen sicheren 
Betrieb zu gewährleisten. Es unbeschaltet zu lassen (interner 133k 
Pull-Up) reicht scheinbar nicht, auch wenn im Datenblatt, sowohl von 
Hope, also auch dem "Original" von (jetzt) Silabs was anderes steht. 
Auch der interne Pull-Up des AVRs scheint zu klein zu sein, wenn man den 
Pin mit einem auf Eingang geschalteten Pin eines AVRs verbindet. Pin auf 
Ausgang und High geht aber.

Andernfalls hängt der RF12 bei mir beim Senden.

von Urs (Gast)


Lesenswert?

Achso, hatte ihr schon. Na dann vergesst mein Posting.

von Sonke A. (soeni)


Angehängte Dateien:

Lesenswert?

Halt das DDR hatte ich noch falsch, das war noch die alte Version. jetzt 
lautet es:

DDRB = 0b01000111;  // Eingang Encoder / Funkmodul

Den Widerstand hab ich jetzt auch auf 10k erhöht und die Schaltung 
angepasst (Im Anhang)

von Jean P. (fubu1000)


Lesenswert?

Hi,
zuerst würde ich an deiner Stelle den Hardware SPI verwenden. Danach 
würde ich vielleicht erstmal deine ganzen Sende und Empfangs Sachen 
vergessen und dir per UART nach der rf12_init(), die Werte des RFM12 
Status Registers anzeigen lassen. Wenn du dann sicher bist, das er 
richtig initialisiert ist, kümmerst du dich um die Funk Sachen.

Gruß

von Sonke A. (soeni)


Lesenswert?

also meiner Meinung nach nutze ich den Hardware SPI ?!? der ist doch 
beim Atmega128 da?!

Ich habe davon wenig Ahnung, würde aber gerne mein Wissenn aufbessern. 
am liebsten würde ich die Ansteuerung selber schreiben, dazu brauch ich 
aber entweder eine sehr gute anleitung, die nicht den fast fertigen code 
liefert oder jemand der mir hilft.

Aber zum SPI, ich hab mir da die Beschreibung rausgesucht und 
initialisiere den SPI jetzt nach dieser. Leider weis ich nicht, was ich 
aktivieren soll. ist ein Interrupt nötig? welche Frequenz...

Mein code dazu sieht wiefolgt aus:
1
 /*
2
Das SPCR wird nun mit dem Bitmuster  01010001b konfiguriert. Damit ist der 
3
Mikrocontroller als Master, SPI enable, Interrupt Disable, CPU-Takt durch 16, Polarität auf 
4
null und Datenübernahme bei der ersten Taktflanke konfiguriert. */
5
6
SPCR = 0b01010001;
7
8
//SPSR (Statusregister)
9
10
if(SPCR == 0b01010001){
11
set_cursor(0,4);
12
lcd_string("Statusregister: 0b01010001");
13
_delay_ms(1000);
14
}

Das Register wurd einwandfrei beschrieben und kann ausgelesen werden.

von Jean P. (fubu1000)


Lesenswert?

Hi,
also du benutzt die Pins des Hardware SPI's, aber nicht die Register 
(siehe deine rf12_trans Methode).
SPSR und SPCR sind die Steuerregister und SPDR das Datenregister.

Aber zurück zum Problem. NAch der init(), lies doch mal das Status 
Register, des RFM12 aus und sende es dir per UART aufn PC (oder aufs 
Display). Dann weisste schon mal, ob die Initialisierung erfolgreich 
war. Wenn du nicht sicher bist ob die Bits des Registers ok sind, poste 
es hier.

Gruß

von Sonke A. (soeni)


Lesenswert?

Ist das SPI INIT so richtig? wie muss ich denn die Transmitfunktion 
abändern. einfach nur das gewünschte in das Register schreiben? 
(Datenregister) reicht das?

und wie frag ich das Statusregister des Moduls ab?

von Sonke A. (soeni)


Lesenswert?

Guten Morgen,

Das Statusregister des SPI beinhaltet doch die ankommenden Daten. Kann 
ich so einfach den Status des Moduls auslesen? Wird der vom Modul 
autommatisch gesendet? (oder landen die im Datenregister)

kann mir nochmal jemand helfen bitte ??

von Sonke A. (soeni)


Lesenswert?

Wie kann ich den werkennen, ob das Datenregister schon rausgeschoben 
wurde, wenn ich neue Daten reintue? und wie frage ich den Status des 
Moduls ab?

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.