Forum: Mikrocontroller und Digitale Elektronik RFM12 Senden und Empfangen funktioniert teilweise


von Marian S. (ramsem2)


Angehängte Dateien:

Lesenswert?

Hallo,

ich hab das Problem dass ich habe in einem Beitrag bereits erläutert. 
Unter anderem lag das Problem in einem defekten RFM12 Modul.

Ich habe ein Platine, die einen Befehl über die serielle Schnittstelle 
vom Raspberry Pi erhält, etwas über Funk auszusenden. Danach soll etwas 
über Funk empfangen werden und zum Schluss das Empfangene über eine 
serielle Schnittstelle an das Raspberry Pi zurückgesendet werden.

Der Interrupt und im Anschluss senden funktioniert ohne Probleme.

Etwas empfangen und im Anschluss an die serielle Schnittstelle zu senden 
funktioniert auch ohne Probleme.

Beides hintereinander geht jedoch nicht! Und das ist mir ein Rätsel.

Wenn ich etwas sende und danach etwas empfangen will, empfange ich 
scheinbar nur etwas "leeres". Das kann aber nicht sein.

Ich vermute den Fehler irgendwo im init(), komme aber nicht auf ihn.

Im Anhang habe ich die Beschaltung beigefügt.

Vielleicht ist jemand in der Lage den Fehler zu finden.

Hier ist der Code:

/*Zunächst die RF12.C-Datei*/
/*=========================*/

#include <avr/io.h>
#include <avr/interrupt.h>
#include "global.h"
#include "rf12.h"

#define F_CPU 1000000UL
#include <util/delay.h>

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

#define SDI    5
#define SCK    7
#define CS    4
#define SDO    6

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)
{
  RF_DDR=(1<<SDI)|(1<<SCK)|(1<<CS);
  RF_PORT=(1<<CS);

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

  rf12_trans(0xC0E0);      // AVR CLK: 10MHz
  //rf12_trans(0x80D7);      // Enable FIFO
  rf12_trans(0x80EF);      // Enable FIFO ; 868 MHz ; 16pF
  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
  rf12_trans(0xC4E7);      // AFC settings: autotuning: 
-20kHz...+17,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 in diesem Fall aber 868Min
  freq=96;
  else if (freq>3903)      // 439,7575MHz in diesem Fall aber 868Max
  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
}

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(0xB800); // Dummy 1
  rf12_ready();
  rf12_trans(0xB800); // Dummy 2
  rf12_ready();
  rf12_trans(0x8208);      // TX off
}

void rf12_rxdata(char *data,  char number)
{   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
}


/*Hier kommt Uarts.c*/
/*==================*/
#include <avr/io.h>

#include "uarts.h"

void initUarts(void)
{
    //9600 N,8,1 fuer Uart0
    //fosc = 10MHz

    UBRR0L = 64;
    UCSR0B = (1<<TXEN0) | (1<<RXEN0);
  UCSR0C = (0<<USBS0) | (3<<UCSZ00);

}

void charUart0(char ch)
{
    UDR0 = ch;

    while(!(UCSR0A&(1<<UDRE0)))
        ;
}

void strUart0(char *str)
{
    while(*str)
    {
        charUart0(*str++);
    }
}

bool isUart0(void)
{
    return UCSR0A & (1<<RXC0);
}

char getUart0(void)
{
    while(!isUart0())
        ;

    return UDR0;
}

/*Zum Schluss das Hauptprogramm, welches auch das Init beinhaltet*/
/*===============================================================*/

#define F_CPU 10000000UL

//Includes
#include <avr/io.h>
#include <util/delay.h>
#include <stdbool.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <avr/interrupt.h>
#include "Uarts.h"
#include "global.h"
#include "rf12.h"

//Variablendeklaration
volatile int id = 1;
volatile int hilfe;
volatile int ms;
volatile int strPosition = 0;
volatile char strEmpfaenger[3];
volatile bool strFinish = false;
volatile bool intFlag=false;

//Defines
#define isBit(port, bit)  (port&(1<<(bit)))
#define setBit(port, bit) (port |= (1<<(bit)))
#define clrBit(port, bit) (port&=~(1<<(bit)))
#define invBit(port, bit) (port^=(1<<(bit)))

//Funktionsköpfe
void init(void);
void send2(unsigned char feld[]);
void delay(int ms);
void receive2(char feld[]);

//Interrupt vector
ISR(USART0_RX_vect)
{
  char send = getUart0();
  if(send == '\n' || send == '\r')
  {
    strEmpfaenger[strPosition] = '\0';
    strPosition = 0;
    strFinish = true;
  }
  else
  {
  strEmpfaenger[strPosition++] = send;
  strFinish=false;
  }
}

ISR(PCINT3_vect)
{
  intFlag=true;
}


//Hauptrorgramm
int main(void)
{
  init();  //Rufe Init auf
  char empfang[32];
  char daten[32];
  unsigned char gesendet[32]="Gesendet\n";

  while(1)
  {
    PORTA = 0xFF;
    if(intFlag==true)    //Ist der ankommende String von der seriellen 
Schnittstelle zu ende?
    {
      send2(gesendet);  //Etwas aussenden,
      delay(10);
      PORTA = 0xF7;      //Led leuchten lassen.
      delay(500);

      /*********************************************************************** 
*/
      /* Leuchten die zwei ersten LEDs, ist bei der Sendeplatine ein 
Taster zu drücken, um etwas auszusenden und hier etwas zu empfangen*/
      /*********************************************************************** 
*/

      PORTA = 0xFC;    //Wenn was ankommt leuchtet
      strcpy(empfang,"");  //String leeren, zur Sicherheit
      receive2(empfang);  //Empfange etwas
      delay(10);
      strcpy(daten,empfang);  //Empfangsstring in Datenstring kopieren
      strcpy(empfang,"");    //Empfangsstring leeren
      PORTA = 0xF3;      //Led leuchten lassen
      delay(500);      //Verzögerung notwendig

      strUart0(daten);  //Sende an Serielle Schnittstelle
      PORTA = 0xF1;    //Led leuchten lassen
      delay(500);
      strcpy(daten,"");  //Datenstring leeren

      intFlag=false;    //Bedingung zurücksetzen
    }
  }
}


void init(void)
{
DDRA = 0xFF;  //Als Ausgang definieren
PORTA=0xFF;    //Pullups ein

DDRD = 0xFE;  //Serielle Schnittstelle

rf12_init();  //Ein paar Register setzten, z.B. (Clock auf 10MHz)
rf12_setfreq(RF12FREQ(869.4)); 
// Sende und Empfangsfrequenz auf 869.4 MHz   einstellen
rf12_setbandwidth(4, 1, 4);                                        //200 
kHz Bandbreite, -6dB Verstärkung, DRSSI threshold: -79dBm
rf12_setbaud(19200); //Baudrate auf 19200 einstellen
rf12_setpower(0, 6);//1mW Ausgangsleistung, 120 kHz Frequenzshift

initUarts();          //InitUarts aufrufen

setBit(PCMSK3,PCINT24); //PinChange Interrupt 24 enabled
setBit(PCICR,PCIE3);  //enable PCINT3_vect für PCINT24-31

sei();  //Interrupt freigeben
}


void send2(unsigned char feld[])
{
  rf12_txdata(feld,32);    //Sende den Inhalt von feld
}

void delay(int ms)
{
  int i;
  for(i=0;i<ms;i++)
  {
    _delay_ms(1);
  }
}

void receive2(char feld[])
{
  rf12_rxdata(feld,32);    //Empfange Daten und speichere sie im Feld ab
}

von Christian K. (the_kirsch)


Lesenswert?

Bitte Quellcode immer in [ c ] [ /c ] Tags einschließen, und bei so 
langen Code besser als Anhang.


Was mir jetzt beim schnellen überfliegen aufgefallen ist, zwischen 
senden und empfangen hast du sehr viele delays drin. Was ist wenn die 
Antwort bereits gesendet wurden ist, bevor du überhaut in die 
Empfangsroutine rein gehst.

: Bearbeitet durch User
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.