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