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
}
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.
