Gast
#1296754
Hallo, ich habe mir inwzischen ein Funkmodul das Funkmodul RFM12 von Pollin zugelegt und komme irgendwie noch nicht so richtig damit zurecht. Einerseits habe ich jetzt eine Platine als Fertigbausatz (Funkmodulbausatz von Pollin mit einem RFM12) und andererseits von Rowalt ein AVR Mikrokontroller Board mit SIL Sockelleisten woran ich mein zweites RFM12 angeschlossen habe. Ich habe mir gedacht das ich als erstes das Rowalt Board ständig durch die gegend funken lasse und das gefunkte per Pollin Funkevaluationsboard empfange und danach auf die RS232 Schnittstelle ausgebe. Da ich das Datenblatt von Pollin gerade als Klopapier vieleicht noch gute Zwecke leistet hab ich den Rat im Forum befolgt und mir direkt vom Hersteller das Datenblatt von HOPE angesehen. Ich weiß es gibt schon fertige Funkstacks usw. aber ich möchte das ganze erstmal so simpel wie möglich machen und durch den Äther senden und empfangen. Da ich auf der Empfangsseite angeblich nur 00er Bytes bekomme (zumindest sagt mir das die RS232) stelle ich mir nun folgende Fragen: Wie kann ich a) erstmal überprüfen ob mein Rowalt Sendemodul überhaupt sendet? und b) das mein Empfangsmodull empfängt? Als Antennen verwende ich bisher 2 ca 17cm lange verlötete Drahtstücke. Ist das ok soweit? Ich will damit momentan noch keine Reichweitenrekorde aufstellen, mir gehts nurmal ums Prinzip. Als Quellcode für das ganze habe ich den Code im Datenblatt von Hoppe verwendet: Das Sendemodul hängt dabei wie folgt am Atmega8 // NIRQ -> PD2 // SCK -> PB5 // SDO -> PB4 // SDI -> PB3 // NSEL -> PD2 // FSK/DATA/NFFS -> PD7 // DLCK -> PD3 // NINT -> PB0 Der Takt des Prozessors beträgt wie man sieht 8Mhz (interner Oszilator) Sender: #define F_CPU 8000000UL #include <avr/io.h> #include <compat/ina90.h> //#include <avr/interrupt.h> #include <stdint.h> #include <stdbool.h> // #include <avr/eeprom.h> #include <util/delay.h> #include <avr/interrupt.h> // #include "rf12.h" #define DDR_IN 0 #define DDR_OUT 1 #define PORT_SEL PORTB #define PIN_SEL PINB #define DDR_SEL DDRB #define PORT_SDI PORTB #define PIN_SDI PINB #define DDR_SDI DDRB #define PORT_SCK PORTB #define PIN_SCK PINB #define DDR_SCK DDRB #define PORT_SDO PORTB #define PIN_SDO PINB #define DDR_SDO DDRB #define PORT_DATA PORTD #define PIN_DATA PIND #define DDR_DATA DDRD #define PB7 7// -- #define PB6 6// | #define RFXX_SCK 5// | #define RFXX_SDO 4// |RF_PORT #define RFXX_SDI 3// | #define RFXX_SEL 2// | #define NC 1// | #define PBO 0//--/ #define SEL_OUTPUT() DDR_SEL|= (1<<RFXX_SEL) #define HI_SEL() PORT_SEL|= (1<<RFXX_SEL) #define LOW_SEL() PORT_SEL&=~(1<<RFXX_SEL) #define SDI_OUTPUT() DDR_SDI|= (1<<RFXX_SDI) #define HI_SDI() PORT_SDI|= (1<<RFXX_SDI) #define LOW_SDI() PORT_SDI&=~(1<<RFXX_SDI) #define SDO_INPUT() DDR_SDO&= ~(1<<RFXX_SDO) #define SDO_HI() PIN_SDO&(1<<RFXX_SDO) #define SCK_OUTPUT() DDR_SCK|= (1<<RFXX_SCK) #define HI_SCK() PORT_SCK|= (1<<RFXX_SCK) #define LOW_SCK() PORT_SCK&=~(1<<RFXX_SCK) #define RF12_DATA 4//PD4 #define DATA_OUT DDR_DATA|=1<<RF12_DATA #define HI_DATA PORT_DATA|=1<<RF12_DATA #define LEDG_OUTPUT() DDRD|=~(1<<6) #define LEDR_OUTPUT() DDRD|=~(1<<7) #define LEDG_ON() PORTD|=(1<<6) #define LEDG_OFF() PORTD&=~(1<<6) #define LEDR_ON() PORTD|=(1<<7) #define LEDR_OFF() PORTD&=~(1<<7) void RFXX_PORT_INIT(void) { HI_SEL(); HI_SDI(); LOW_SCK(); SEL_OUTPUT(); SDI_OUTPUT(); SDO_INPUT(); SCK_OUTPUT(); } unsigned int RFXX_WRT_CMD(unsigned int aCmd) { unsigned char i; unsigned int temp; LOW_SCK(); LOW_SEL(); for(i=0;i<16;i++) { temp<<=1; if (SDO_HI()) { temp |=0x0001; } LOW_SCK(); if(aCmd&0x8000) { HI_SDI(); }else { LOW_SDI(); } HI_SCK(); aCmd<<=1; }; LOW_SCK(); HI_SEL(); return (temp) ; } void RF12_INIT(void) { RFXX_WRT_CMD(0x80D7) ;//EL,EF, 433band, l2.0pF RFXX_WRT_CMD(0x8239) ;//!er, !ebb, ET, ES, EX, !eb, !ew,DC RFXX_WRT_CMD(0xA640) ;//A140=430.8MHz 434Mhz? RFXX_WRT_CMD(0xC647) ;//19.2kbps RFXX_WRT_CMD(0x94A0) ;//VDI,FAST, l34kHz,OdBm,-103dBm RFXX_WRT_CMD(0xC2AC) ;//AL, !ml,DIG,DQD4 RFXX_WRT_CMD(0xCA81) ;//FIFO8,SYNC, !ff,DR RFXX_WRT_CMD(0xC483) ;//@PWR,NO RSTRIC, !st, !fi,OE,EN RFXX_WRT_CMD(0x9850) ;//!mp,9810=30kHz,MAX OUT RFXX_WRT_CMD(0xE000) ;//NOT USE RFXX_WRT_CMD(0xC800) ;//NOT USE RFXX_WRT_CMD(0xC400) ;//1.66MHz, 2.2V } void RF12_SEND(unsigned char aByte) { while(PIND&(1<<2)) ;//wait for previously TX over RFXX_WRT_CMD(0xB800+aByte) ; } #define LEDG_OUTPUT() DDRD|=~(1<<6) #define LEDR_OUTPUT() DDRD|=~(1<<7) #define LEDG_ON() PORTD|=(1<<6) #define LEDG_OFF() PORTD&=~(1<<6) #define LEDR_ON() PORTD|=(1<<7) #define LEDR_OFF() PORTD&=~(1<<7) void send(void); void receive(void); void ledTest(void){ for (int i=0;i<3;i++){ LEDR_ON(); LEDG_ON(); _delay_ms(200); LEDR_OFF(); LEDG_OFF(); _delay_ms(200); } } int main(void){ // -------------- unsigned int i, j; unsigned char ChkSum; asm volatile ("cli") ; DDRB=0x00;//PB INPUT; DDRD=0x00;//PD INPUT; //POWER ON indication: both LEDR and LEDG blink 3 times LEDG_OFF(); LEDR_OFF(); LEDG_OUTPUT(); LEDR_OUTPUT(); for(i=0;i<3;i++) { _delay_ms(200) ; LEDG_ON(); LEDR_ON(); _delay_ms(200) ; LEDG_OFF(); LEDR_OFF(); } bool redWasLast = true; RFXX_PORT_INIT(); RF12_INIT(); DDRD|= (1<<RF12_DATA) ; PORTD|= (1<<RF12_DATA) ;// SET nFFS pin HI when using TX register DDRD&=~(1<<2); //PD2(INTO) while(1) { RFXX_WRT_CMD(0x0000) ;//read status register RFXX_WRT_CMD(0x8239) ;//!er, !ebb,ET,ES, EX, !eb, !ew,DC ChkSum=0; RF12_SEND(0xAA) ;//PREAMBLE RF12_SEND(0xAA) ;//PREAMBLE RF12_SEND(0xAA) ;//PREAMBLE RF12_SEND(0x2D) ;//SYNC HI BYTE RF12_SEND(0xD4) ;//SYNC LOW BYTE RF12_SEND(0x30) ;//DATA BYTE 0 ChkSum+=0x30; RF12_SEND(0x31) ;//DATA BYTE 1 ChkSum+=0x31; RF12_SEND(0x32) ; ChkSum+=0x32; RF12_SEND(0x33) ; ChkSum+=0x33; RF12_SEND(0x34) ; ChkSum+=0x34; RF12_SEND(0x35) ; ChkSum+=0x35; RF12_SEND(0x36) ; ChkSum+=0x36; RF12_SEND(0x37) ; ChkSum+=0x37; RF12_SEND(0x38) ; ChkSum+=0x38; RF12_SEND(0x39) ; ChkSum+=0x39; RF12_SEND(0x3A) ; ChkSum+=0x3A; RF12_SEND(0x3B) ; ChkSum+=0x3B; RF12_SEND(0x3C) ; ChkSum+=0x3C; RF12_SEND(0x3D) ; ChkSum+=0x3D; RF12_SEND(0x3E) ; ChkSum+=0x3E; RF12_SEND(0x3F); //DATA BYTE 15 ChkSum+=0x3F; RF12_SEND(ChkSum); //send chek sum RF12_SEND(0xAA) ;//DUMMY BYTE RF12_SEND(0xAA) ;//DUMMY BYTE RF12_SEND(0xAA) ;//DUMMY BYTE RFXX_WRT_CMD(0x8201) ; //LEDG_ON(); if (redWasLast==true){ LEDG_ON(); _delay_ms(200); LEDG_OFF(); _delay_ms(200); redWasLast=false; } else{ redWasLast=true; LEDR_ON(); _delay_ms(200); LEDR_OFF(); _delay_ms(200); } } ; } Die Empfängerseite ist wie gesagt das Pollin Evaluationsboard mit nem verlöteten RFM12 Modul Empfänger: /* * Main.cpp * * Created on: 07.06.2009 * Author: procrash */ #define F_CPU 8000000UL #include <avr/io.h> #include <compat/ina90.h> //#include <avr/interrupt.h> #include <stdint.h> #include <stdbool.h> // #include <avr/eeprom.h> #include <util/delay.h> /* In neueren Version der WinAVR/Mfile Makefile-Vorlage kann F_CPU im Makefile definiert werden, eine nochmalige Definition hier wuerde zu einer Compilerwarnung fuehren. Daher "Schutz" durch #ifndef/#endif Dieser "Schutz" kann zu Debugsessions führen, wenn AVRStudio verwendet wird und dort eine andere, nicht zur Hardware passende Taktrate eingestellt ist: Dann wird die folgende Definition nicht verwendet, sondern stattdessen der Defaultwert (8 MHz?) von AVRStudio - daher Ausgabe einer Warnung falls F_CPU noch nicht definiert: */ #ifndef F_CPU #warning "F_CPU war noch nicht definiert, wird nun nachgeholt mit 4000000" #define F_CPU 12000000UL // Systemtakt in Hz - Definition als unsigned long beachten >> Ohne ergeben Fehler in der Berechnung #endif #define BAUD 19200UL // Baudrate // Berechnungen #define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1) // clever runden #define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1))) // Reale Baudrate #define BAUD_ERROR ((BAUD_REAL*1000)/BAUD) // Fehler in Promille, 1000 = kein Fehler. #if ((BAUD_ERROR<990) || (BAUD_ERROR>1010)) #error Systematischer Fehler der Baudrate grösser 1% und damit zu hoch! #endif void uartInit(void){ //UCR |= (1<<TXEN); UCSRB |= (1<<TXEN); // UART TX einschalten UCSRC |= (1<<URSEL)|(1 << UCSZ1)|(1 << UCSZ0); // Asynchron 8N1 UBRRH = UBRR_VAL >> 8; UBRRL = UBRR_VAL & 0xFF; } /* copyright Ce) 2006 ;Title RF12 TX simple example based on AVR C ;Company: Hope microelectronic Co.,Ltd. ;Author: Tank ;Current version: vl.O ;Date: 2006-11-13 ;processor ATMEGA48 ;Clock: ;Contact: ;E-MAIL: 10MHz Crystal +86-0755-86106557 hopefsk@hoperf.com Connections ATMEGA48 SIDE RF12 SIDE SCK---------------)SCK MISO---------------)SDO MOSI---------------)SDI SS---------------)nSEL INTO<---------------nIRQ PD6: LED GREEN PD7: LED RED */ // #include <mega48.h> // NIRQ -> PD2 // SCK -> PB5 // SDO -> PB4 // SDI -> PB3 // NSEL -> PD2 // FSK/DATA/NFFS -> PD7 // DLCK -> PD3 // NINT -> PB0 #define DDR_IN 0 #define DDR_OUT 1 #define PORT_SEL PORTB #define PIN_SEL PINB #define DDR_SEL DDRB #define PORT_SDI PORTB #define PIN_SDI PINB #define DDR_SDI DDRB #define PORT_SCK PORTB #define PIN_SCK PINB #define DDR_SCK DDRB #define PORT_SDO PORTB #define PIN_SDO PINB #define DDR_SDO DDRB #define PORT_DATA PORTD #define PIN_DATA PIND #define DDR_DATA DDRD #define PB7 7//--\ #define PB6 6// | #define RFXX_SCK 5// | #define RFXX_SDO 4// |RF_PORT #define RFXX_SDI 3// | #define RFXX_SEL 2// | #define NC 1// | #define PBO 0//--/ #define SEL_OUTPUT() DDR_SEL|= (1<<RFXX_SEL) #define HI_SEL() PORT_SEL|= (1<<RFXX_SEL) #define LOW_SEL() PORT_SEL&=~(1<<RFXX_SEL) #define SDI_OUTPUT() DDR_SDI|= (1<<RFXX_SDI) #define HI_SDI() PORT_SDI|= (1<<RFXX_SDI) #define LOW_SDI() PORT_SDI&=~(1<<RFXX_SDI) #define SDO_INPUT() DDR_SDO&= ~(1<<RFXX_SDO) #define SDO_HI() PIN_SDO&(1<<RFXX_SDO) #define SCK_OUTPUT() DDR_SCK|= (1<<RFXX_SCK) #define HI_SCK() PORT_SCK|= (1<<RFXX_SCK) #define LOW_SCK() PORT_SCK&=~(1<<RFXX_SCK) #define RF12_DATA 4//PD4 #define DATA_OUT DDR_DATA|=1<<RF12_DATA #define HI_DATA PORT_DATA|=1<<RF12_DATA #define RF12_IRQ 2 #define IRQ_IN() DDR_IRQ &=~(1<<RF12_IRQ) #define WAIT_IRQ_LOW() while(PIND&(1<<RF12_IRQ)) #define LEDG_OUTPUT() DDRD|=~(1<<6) #define LEDR_OUTPUT() DDRD|=~(1<<7) #define LED1_OUTPUT() DDRD|=~(1<<5) #define LED2_OUTPUT() DDRD|=~(1<<6) #define LEDG_ON() PORTD|=(1<<6) #define LEDG_OFF() PORTD&=~(1<<6) #define LED1_ON() PORTD|=(1<<5) #define LED1_OFF() PORTD&=~(1<<5) #define LED2_ON() PORTD|=(1<<6) #define LED2_OFF() PORTD&=~(1<<6) #define LEDR_ON() PORTD|=(1<<7) #define LEDR_OFF() PORTD&=~(1<<7) void RFXX_PORT_INIT(void) { HI_SEL(); HI_SDI(); LOW_SCK(); SEL_OUTPUT(); SDI_OUTPUT(); SDO_INPUT(); SCK_OUTPUT(); } unsigned int RFXX_WRT_CMD(unsigned int aCmd) { unsigned char i; unsigned int temp; LOW_SCK(); LOW_SEL(); for(i=0;i<16;i++) { temp<<=1; if (SDO_HI()) { temp |=0x0001; } LOW_SCK(); if(aCmd&0x8000) { HI_SDI(); }else { LOW_SDI(); } HI_SCK(); aCmd<<=1; }; LOW_SCK(); HI_SEL(); return (temp) ; } void RF12_INIT(void) { RFXX_WRT_CMD(0x80D7) ;//EL,EF, 433band, l2.0pF RFXX_WRT_CMD(0x8239) ;//!er, !ebb, ET, ES, EX, !eb, !ew,DC //82D) RFXX_WRT_CMD(0xA640) ;//A140=430.8MHz 434Mhz? RFXX_WRT_CMD(0xC647) ;//19.2kbps //C647 RFXX_WRT_CMD(0x94A0) ;//VDI,FAST, l34kHz,OdBm,-103dBm RFXX_WRT_CMD(0xC2AC) ;//AL, !ml,DIG,DQD4 RFXX_WRT_CMD(0xCA81) ;//FIFO8,SYNC, !ff,DR RFXX_WRT_CMD(0xC483) ;//@PWR,NO RSTRIC, !st, !fi,OE,EN RFXX_WRT_CMD(0x9850) ;//!mp,9810=30kHz,MAX OUT RFXX_WRT_CMD(0xE000) ;//NOT USE RFXX_WRT_CMD(0xC800) ;//NOT USE RFXX_WRT_CMD(0xC400) ;//1.66MHz, 2.2V } void RF12_SEND(unsigned char aByte) { while(PIND&(1<<2)) ;//wait for previously TX over RFXX_WRT_CMD(0xB800+aByte) ; } unsigned char RF12_RECV(void){ unsigned int FIFO_data; WAIT_IRQ_LOW(); RFXX_WRT_CMD(0x0000); FIFO_data=RFXX_WRT_CMD(0xB000); return(FIFO_data&0x00FF); } void sendUART(unsigned char b){ // bei neueren AVRs steht der Status in UCSRA/UCSR0A/UCSR1A, hier z.B. fuer ATmega16: // b=255; unsigned char hexMSB = b / 16; unsigned char hexLSB = b % 16; if (hexMSB<10) hexMSB+='0'; else hexMSB+=55; if (hexLSB<10) hexLSB+='0'; else hexLSB+=55; while (!(UCSRA & (1<<UDRE))) // warten bis Senden moeglich { } UDR = hexMSB; // schreibt das Zeichen x auf die Schnittstelle while (!(UCSRA & (1<<UDRE))) // warten bis Senden moeglich { } UDR = hexLSB; // schreibt das Zeichen x auf die Schnittstelle while (!(UCSRA & (1<<UDRE))) // warten bis Senden moeglich { } UDR = ' '; // schreibt das Zeichen x auf die Schnittstelle } int main(void){ uartInit(); unsigned char i; unsigned char ChkSum; asm volatile ("cli") ; DDRB=0x00;//PB INPUT; DDRD=0x00;//PD INPUT; //POWER ON indication: both LEDR and LEDG blink 3 times LED1_OUTPUT(); LED2_OUTPUT(); for(i=0;i<3;i++) { _delay_ms(200) ; LED1_ON(); LED2_ON(); _delay_ms(200) ; LED1_OFF(); LED2_OFF(); } bool redWasLast = true; RFXX_PORT_INIT(); RF12_INIT(); DDRD|= (1<<RF12_DATA) ; PORTD|= (1<<RF12_DATA) ;// SET nFFS pin HI when using TX register DDRD&=~(1<<2); //PD2(INTO) RFXX_WRT_CMD(0xCA81); unsigned char recvd; while(1) { RFXX_WRT_CMD(0xCA83); ChkSum=0; for (i=0;i<16;i++){ recvd=RF12_RECV(); sendUART(recvd); ChkSum+=recvd; } recvd=RF12_RECV(); i = recvd; sendUART(recvd); RFXX_WRT_CMD(0xCA81) ;//read status register if (ChkSum==i){ LED2_ON(); _delay_ms(200); LED2_OFF(); } else { LED1_ON(); _delay_ms(200); LED1_OFF(); } } ; }