mikrocontroller.net

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


Autor: Sonke A. (soeni)
Datum:

Bewertung
0 lesenswert
nicht 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:
void rf12_ready(void)
{  cbi(RF_PORT, CS);
  while (!(RF_PIN&(1<<SDO))); // wait until FIFO ready
}


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

Autor: Jean Player (fubu1000)
Datum:

Bewertung
0 lesenswert
nicht 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ß

Autor: Sonke A. (soeni)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Jean Player (fubu1000)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Sonke A. (soeni)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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)

Autor: Jean Player (fubu1000)
Datum:

Bewertung
0 lesenswert
nicht 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ß

Autor: Sonke A. (soeni)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi, danke für deine Mühen,

wie schon gesagt, nffs hängt schon über 1k an vcc sind da wirklich 10 
notwendig?

/// Auszug aus int main
  #include <avr/interrupt.h>
  #include <avr/io.h>
  #include <avr/pgmspace.h>
  #include <stdint.h>
  #include <stdio.h>
  #include <stdlib.h>
  #include <string.h>
  #include <util/delay.h> 
// ...
DDRB = 0b01001011;  // Eingang Encoder / Funkmodul


/// Auszug aus der Headerdatei
#define RF12FREQ(freq)  ((freq-430.0)/0.0025)              // macro for calculating frequency value out of frequency in MHz

#ifndef cbi
#define cbi(sfr, bit)     (_SFR_BYTE(sfr) &= ~_BV(bit)) 
#endif
#ifndef sbi
#define sbi(sfr, bit)     (_SFR_BYTE(sfr) |= _BV(bit))  
#endif


// Die eigendlichen Funktionen (Übernommen aus dem oben genannten Beitrag)



#define RF_PORT  PORTB
#define RF_DDR  DDRB
#define RF_PIN  PINB

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

unsigned short rf12_trans(unsigned short wert)
{  unsigned short werti=0;
  unsigned char i;

  cbi(RF_PORT, CS);
  for (i=0; i<16; i++)
  {  if (wert&32768)
      sbi(RF_PORT, SDI);
    else
      cbi(RF_PORT, SDI);
    werti<<=1;
    if (RF_PIN&(1<<SDO))
      werti|=1;
    sbi(RF_PORT, SCK);
    wert<<=1;
    _delay_us(0.3);
    cbi(RF_PORT, SCK);
  }
  sbi(RF_PORT, CS);
  return werti;
}

void rf12_init(void)
{       // Auskommentiert weil bereits in der int main geschehen
  //RF_DDR=(1<<SDI)|(1<<SCK)|(1<<CS);
  RF_PORT=(1<<CS);

  //for (unsigned char i=0; i<10; i++)
    _delay_ms(100);      // wait until POR done

  rf12_trans(0xC0E0);      // AVR CLK: 10MHz
  rf12_trans(0x80D7);      // Enable FIFO
  rf12_trans(0xC2AB);      // Data Filter: internal
  rf12_trans(0xCA81);      // Set FIFO mode
  rf12_trans(0xE000);      // disable wakeuptimer
  rf12_trans(0xC800);      // disable low duty cycle
  rf12_trans(0xC4F7);      // AFC settings: autotuning: -10kHz...+7,5kHz
}

void rf12_setbandwidth(unsigned char bandwidth, unsigned char gain, unsigned char drssi)
{
  rf12_trans(0x9400|((bandwidth&7)<<5)|((gain&3)<<3)|(drssi&7));
}

void rf12_setfreq(unsigned short freq)
{  if (freq<96)        // 430,2400MHz
    freq=96;
  else if (freq>3903)      // 439,7575MHz
    freq=3903;
  rf12_trans(0xA000|freq);
}

void rf12_setbaud(unsigned short baud)
{
  if (baud<663)
    return;
  if (baud<5400)          // Baudrate= 344827,58621/(R+1)/(1+CS*7)
    rf12_trans(0xC680|((43104/baud)-1));
  else
    rf12_trans(0xC600|((344828UL/baud)-1));
}

void rf12_setpower(unsigned char power, unsigned char mod)
{  
  rf12_trans(0x9800|(power&7)|((mod&15)<<4));
}

void rf12_ready(void)
{  cbi(RF_PORT, CS);
  while (!(RF_PIN&(1<<SDO))); // wait until FIFO ready
  //_delay_ms(10);
}

void rf12_txdata(unsigned char *data, unsigned char number)
{  unsigned char i;
  rf12_trans(0x8238);      // TX on
  rf12_ready();
  rf12_trans(0xB8AA);
  rf12_ready();
  rf12_trans(0xB8AA);
  rf12_ready();
  rf12_trans(0xB8AA);
  rf12_ready();
  rf12_trans(0xB82D);
  rf12_ready();
  rf12_trans(0xB8D4);
  for (i=0; i<number; i++)
  {    rf12_ready();
    rf12_trans(0xB800|(*data++));
  }
  rf12_ready();
  rf12_trans(0x8208);      // TX off
}

void rf12_rxdata(unsigned char *data, unsigned char number)
{  unsigned char i;
  rf12_trans(0x82C8);      // RX on
  rf12_trans(0xCA81);      // set FIFO mode
  rf12_trans(0xCA83);      // enable FIFO
  for (i=0; i<number; i++)
  {  rf12_ready();
    *data++=rf12_trans(0xB000);
  }
  rf12_trans(0x8208);      // RX off
}








unsigned char * receive(void)
{  
  unsigned char test[32];  
  rf12_rxdata(test,32);  
  // daten verarbeiten
  return test;
}

void send(void)
{  unsigned char test[]="Dies ist ein 433MHz Test !!!\n   ";  
  rf12_txdata(test,32);
}








// Testfunktionen

void funk_sendetest(void){


  rf12_init();          // ein paar Register setzen (z.B. CLK auf 10MHz)
  rf12_setfreq(RF12FREQ(433.92));  // Sende/Empfangsfrequenz auf 433,92MHz einstellen
  rf12_setbandwidth(4, 1, 4);    // 200kHz Bandbreite, -6dB Verstärkung, DRSSI threshold: -79dBm 
  rf12_setbaud(19200);      // 19200 baud
  rf12_setpower(0, 6);      // 1mW Ausgangangsleistung, 120kHz Frequenzshift

  
  //unsigned char i=0;
  unsigned char i=0;


  // Displayausgabe
  lcd_clear();
  set_cursor(0,1);

  uart_puts("\r\n\r\n   Funktest Senden: \r\n");      // Ausgabe UART
  lcd_string("Funktest Senden:   ESC=exit");  // Ausgabe LCD
   
  set_cursor(0,2);

  while(uart_ask() != 27){   // kein Escape gedrückt  ??

    if(!ENCODERTAST) {
        
      beep_short();    // Kurz piepen
      _delay_ms(500);
      return;      // Programmabbruch
    }
  

    if(i>10){
      set_cursor(0,2);
      lcd_string("                ");// Zeile löschen
      set_cursor(0,2);
      i=0;
    }
    
    i++;

      
      lcd_string("-");
      send();
      _delay_ms(1000);


                    

    }




}







// 

void funk_empfangtest(void){


  rf12_init();          // ein paar Register setzen (z.B. CLK auf 10MHz)
  rf12_setfreq(RF12FREQ(433.92));  // Sende/Empfangsfrequenz auf 433,92MHz einstellen
  rf12_setbandwidth(4, 1, 4);    // 200kHz Bandbreite, -6dB Verstärkung, DRSSI threshold: -79dBm 
  rf12_setbaud(19200);      // 19200 baud
  rf12_setpower(0, 6);      // 1mW Ausgangangsleistung, 120kHz Frequenzshift

  
  //unsigned char i=0;
  unsigned char i=0;
  unsigned char * Text;


  // Displayausgabe
  lcd_clear();
  set_cursor(0,1);

  uart_puts("\r\n\r\n   Funktest Empfang: \r\n");      // Ausgabe UART
  lcd_string("Funktest Empfang:  ESC=exit");  // Ausgabe LCD
   
  set_cursor(0,2);

  while(uart_ask() != 27){   // kein Escape gedrückt  ??

    if(!ENCODERTAST) {
        
      beep_short();    // Kurz piepen
      _delay_ms(500);
      return;      // Programmabbruch
    }
  

    if(i>10){
      set_cursor(0,2);
      lcd_string("                ");// Zeile löschen
      set_cursor(0,2);
      i=0;
    }
    
    i++;

      
    Text = receive();
    set_cursor(0,3);
    lcd_string(Text);
      


                    

    }




}



so das wars denke ich

Autor: Urs (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Urs (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Achso, hatte ihr schon. Na dann vergesst mein Posting.

Autor: Sonke A. (soeni)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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)

Autor: Jean Player (fubu1000)
Datum:

Bewertung
0 lesenswert
nicht 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ß

Autor: Sonke A. (soeni)
Datum:

Bewertung
0 lesenswert
nicht 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:
 /*
Das SPCR wird nun mit dem Bitmuster  01010001b konfiguriert. Damit ist der 
Mikrocontroller als Master, SPI enable, Interrupt Disable, CPU-Takt durch 16, Polarität auf 
null und Datenübernahme bei der ersten Taktflanke konfiguriert. */

SPCR = 0b01010001;

//SPSR (Statusregister)

if(SPCR == 0b01010001){
set_cursor(0,4);
lcd_string("Statusregister: 0b01010001");
_delay_ms(1000);
}


Das Register wurd einwandfrei beschrieben und kann ausgelesen werden.

Autor: Jean Player (fubu1000)
Datum:

Bewertung
0 lesenswert
nicht 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ß

Autor: Sonke A. (soeni)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Sonke A. (soeni)
Datum:

Bewertung
0 lesenswert
nicht 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 ??

Autor: Sonke A. (soeni)
Datum:

Bewertung
0 lesenswert
nicht 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?

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.