RFM12 Rutine Hängt beim warten auf FIFO

#1160907
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
#1161265
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ß
#1174834
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
Gast #1174856
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.
#1175296
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ß
#1175365
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.
#1175390
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ß

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren