RFM 02 testen ob richtig angeschlossen
Hi,
ich habe mir eine Schaltung mit einem RFM02 868 Modul und einem Attiny2313 aufgebaut.
Nur leider funktioniert nicht alles wie ich möchte (eigentlich garnichts xD).
Daher möchte ich Schritt für Schritt die Fehlerquellen streichen.
Wie kann ich prüfen, ob der RFM überhaupt sendet?
Gibt es irgendwie sowas wie einen Statusbericht des Moduls?
Liste der Anhänge anzeigen (Anzahl: 1)
Ich benutze diesen Code
Code:
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <avr/eeprom.h>
#include <util/delay.h>
#include <stdlib.h>
#define BAUD 2400UL
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1) // clever runden
#define RFM02_CS PB5 // AVR MOSI
#define RFM02_SDI PB6 // AVR MISO
#define RFM02_SCK PB7 // AVR SCK
#define RFM02_IRQ PB0
#define RFM02_DDR DDRB
#define RFM02_PORT PORTB
#define RFM02_PIN PINB
void rfm02_init();
void rfm02_send_data(void);
uint8_t rfm02_send_cmd(uint16_t);
uint8_t rfm02_send_8bit(uint8_t);
void uart_putc(unsigned char c)
{
while (!(UCSRA & (1<<UDRE))); /* warten bis Senden moeglich */
UDR = c; /* sende Zeichen */
}
//######################################################################################################
void uart_puts( char * s )
{
while(*s)
{ /* so lange *s != '\0' also ungleich dem "String-Endezeichen" */
uart_putc(*s);
s++;
}
}
void uart_init()
{
UCSRB |= (1<<RXEN);
UCSRB |= (1<<TXEN);
UBRRH = UBRR_VAL >> 8;
UBRRL = UBRR_VAL;
}
char buffer = 'B';
void rfm02_init()
{
RFM02_PORT |= (1<<RFM02_IRQ) | (1<<RFM02_CS) | (1<<RFM02_SDI); // PullUp ein / Ausgang H
RFM02_DDR |= (1<<RFM02_CS) | (1<<RFM02_SCK) | (1<<RFM02_SDI); // Ausgänge
RFM02_DDR &= ~(1<<RFM02_IRQ); // Eingang
rfm02_send_cmd(0xCC00); // Status read
rfm02_send_cmd(0xC0E0); // Power Settings: Quarz ein, Synthesizer und PA ein bei Send-Command
rfm02_send_cmd(0xC220); //ENABLE BIT SYNC
rfm02_send_cmd(0x8883); // Control: 1MHz Clock Out, 12,5pF Last Quarz, 120kHz Shift
rfm02_send_cmd(0xA620); // Frequenz: 860MHz + (0,005 * 0x620) -> 867,84MHz
rfm02_send_cmd(0xB200); // Power 2 * -3dBm -> -6dBm
rfm02_send_cmd(0xD2C0); // Set PLL: set 33%
rfm02_send_cmd(0xC810); // Baudrate: 344827 / 19200 = 17 - 1 -> 0x10 // Status read
rfm02_send_cmd(0xE500 + 200); // WakeUp-Timer 2^7 *234ms ~ 30s ???!! nicht 1ms sondern 10ms !!???
rfm02_send_cmd(0xC002); // alles aus, WakeUp-Timer ein
rfm02_send_cmd(0xC440); // sleep, noch 64 Takte
}
uint8_t rfm02_send_cmd(uint16_t command)
{
uint8_t status;
RFM02_PORT &= ~(1<<RFM02_CS); // CS auf L
rfm02_send_8bit(command >> 8); // H-Byte senden
status = rfm02_send_8bit(command & 0xFF); // L-Byte senden
RFM02_PORT |= (1<<RFM02_CS); // CS auf H
return status;
}
//-----------------------------------------------------------------------------------------
uint8_t rfm02_send_8bit(uint8_t byte)
{
uint8_t i;
for (i=0; i<8; i++)
{
if (byte & 0x80)
{
RFM02_PORT |= (1<<RFM02_SDI); // DATA auf H als Ausgang
}
else
{
RFM02_PORT &= ~(1<<RFM02_SDI); // DATA auf L
}
asm("nop");
RFM02_PORT |= (1<<RFM02_SCK); // CLK auf H
asm("nop");
asm("nop");
byte = (byte << 1); // nächstes Bit nach oben
if (RFM02_PIN & (1<<RFM02_IRQ)) // unteres Bit Status einlesen, H?
{
byte |= 0x01; // DATA war H
}
else
{
byte &= ~(0x01); // DATA war L
}
asm("nop");
RFM02_PORT &= ~(1<<RFM02_SCK); // CLK auf L
}
return byte;
}
//-----------------------------------------------------------------------------------------
void rfm02_send_byte(uint8_t byte)
{
uint8_t i;
for (i=0; i<8; i++)
{
while (!(RFM02_PIN & (1<<RFM02_IRQ))) {
uart_putc('6');
} // warten bis IRQ L/H
while (RFM02_PIN & (1<<RFM02_IRQ)) {
uart_putc('7');
} // warten bis IRQ Impuls zuende H/L
if (byte & 0x80)
{
RFM02_PORT |= (1<<RFM02_SDI); // DATA auf H als Ausgang
}
else
{
RFM02_PORT &= ~(1<<RFM02_SDI); // DATA auf L
}
byte = (byte << 1); // Bit 7 rausschieben
}
uart_putc('1');
}
//-----------------------------------------------------------------------------------------
void rfm02_send_data()
{
uint8_t i;
rfm02_send_cmd(0xC0E0); // einschalten
RFM02_PORT &= ~(1<<RFM02_CS); // CS auf L
rfm02_send_8bit(0xC6); // Kommando Daten senden
rfm02_send_byte(0xAA); // Sync
rfm02_send_byte(0xAA);
rfm02_send_byte(0xAA);
rfm02_send_byte(0x2D); // Magic
rfm02_send_byte(0xD4);
rfm02_send_byte(buffer);
while (!(RFM02_PIN & (1<<RFM02_IRQ))) {
uart_putc('3');
}
// auf Ende sendes letztes Byte warten -> L/H
while (RFM02_PIN & (1<<RFM02_IRQ)) {
uart_putc('4');
} // erledigt, wenn IRQ wieder -> H/L
while (!(RFM02_PIN & (1<<RFM02_IRQ))) {
uart_putc('5');
} // auf Ende Power Off warten -> L/H
RFM02_PORT |= (1<<RFM02_CS); // CS auf H
rfm02_send_cmd(0xC002); // alles aus, WakeUp-Timer ein
rfm02_send_cmd(0xC440); // sleep, noch 64 Takte
}
int main(void) {
uart_init();
sei();
rfm02_init();
while(1) {
_delay_ms(100);
uart_putc('2');
rfm02_send_data();
}
return 0;
}
Eine Library die für das RFM02-868 nicht für das RFM12er Modul ist, hab ich bis jetzt nicht gefunden.
Hast du vielleicht einen Schaltplan von deinem µC+RFM?
Vielleicht sind bei mir da schon Fehler...
Im Anhang mal meiner.
Er bleibt bei mir immer in dieser Schleife hängen:
while (!(RFM02_PIN & (1<<RFM02_IRQ))) {
uart_putc('6');
} // warten bis IRQ L/H
Liste der Anhänge anzeigen (Anzahl: 1)
Falls es dich interessiert, das ist der originale RFM Thread im microcontroller.net Forum (ja ist ein bisschen viel zu lesen, geb ich zu ;D):
http://www.mikrocontroller.net/topic/67273
Diese Lib von Benedikt benutze ich auch zum Ansteuern.
Woran das liegt, dass nichts Übertragen wird, kann niemand sagen, das ist das gemeine an diesen Dingern, man braucht viel Geduld und Zeit, um dem Fehler auf der Spur zu kommen, evtl. bietet der Thread im microcontroller.net Forum aber Hilfe an.
Als Anhang, Schaltplan für RFM01