Hallo Leute,

ich hab ein Problem bei der Initialisierung eines RFM 02 Empfänger Funkmodules (Pollin) mit einem ATMEGA 8.
Die erste Initialisierung im Hauptprogramm funktioniert die meiste Zeit nicht, ab und zu schon.
Als Sicherheit wurde im Programmcode eine Zyklische Initialisierung eingebaut, die das Funkmodul nach 3 Sekunden Untätigkeit neu Initialisiert.
Die funktioniert so gut wie immer.
Das Fehlerbild:
Nach dem Einschalten der Betriebsspannung wird nichts Empfangen. Nach 3 Sekunden bekomm ich dann die ersten Werte.
Möchte mal einer von Euch mal über den Quellcode drüberschauen, wo ich da einen Fehler gemacht hab. Mir fällt einfach nichts mehr dazu ein.
Am Sender kann es meiner Meinung nach nicht liegen, der sendet alle Sekunde ein neues Paket ab und wurde zum Testen nicht abgeschaltet.
Code:
#include <mega8.h>
// Standard Input/Output functions
#include <stdio.h>
#include <string.h>
#include <delay.h>
#asm
.equ portb=0x18
.equ portd=0x12
.equ sdi=0     ;PortB,0
.equ sck=1     ;PortB,1
.equ nsel=2    ;PortB,2
.equ sdo=3     ;PortB,3
.equ nirq=2    ;PortD,2
#endasm

// Declare your global variables here
bit newstring=0; /* Ein neuer gültiger Datenstring wurde empfangen */
flash unsigned int ui_frequ[32]={1240,1270,1300,1330,1360,1390,1420,1450,1480,1510,1540,1570,1600,1630,1660,1690,1720,1750,1780,1810,1840,1870,1900,1900,1900,1900,1900,1900,1900,1900,1900,1900};
volatile unsigned char uc_receivebuffer[127];/* Empfangspuffer */
volatile unsigned char uc_receivebyte=0;/* Zeiger aktuelles Sendebyte */
volatile unsigned char uc_timeout=0;
volatile unsigned char uc_kanal; /* gewählter Kanal */

// Sende ein Byte zum RFM 01
void sendbyte(volatile unsigned char uc_byte)
{   
    #asm
    push r26        ;Register retten
    in r26,sreg
    push r26
    push r27
    ldi r26,8       ;Schleifenzähler mit 8 laden
    ld r27,y        ;uc_Byte vom Ram holen
    
    sendloop:
        tst r26     ;Schleifenzähler eins runterzählen
        breq endsend
        dec r26
        clc
        rol r27     ;High Byte ins Carry schieben
        brcs send1  ;Bei 1 -> High ausgeben
        cbi portb,sdi     ;Bei 0 -> Low ausgeben
        rcall clockpulse
        rjmp sendloop
    
    send1:
        sbi portb,sdi
        rcall clockpulse
        rjmp sendloop
    
    clockpulse:
        nop
        nop
        nop
        sbi portb,sck     ;Clock Port auf 1 setzen
        nop
        nop
        nop
        nop
        nop
        nop
        cbi portb,sck     ;Clock Port auf 0 setzen
        nop
        nop
        nop
        ret         ;Zurück zur aufrufenden Routine
    
    endsend:
        cbi portb,sdi ;SDI Port auf 0 setzen zwecks kosmetik
        pop r27
        pop r26
        out sreg,r26
        pop r26
   #endasm
}

 // XOR Verknüpfung Code Vision kann kein EXOR
#pragma warn- // this will prevent warnings
unsigned char funk_xor (unsigned char uc_wert1,unsigned char uc_wert2)
 {
    #asm
    push r26
    in r26,sreg
    push r26
    ld r26,y        ;uc_wert2 holen
    ldd r30,y+1     ;uc_wert1 holen
    eor r30,r26     ;Rückgabewert im Register r30
    pop r26
    out sreg,r26
    pop r26
    #endasm
 
 }
#pragma warn+ // enable warnings

// Checksumme berechnen
unsigned char checksum (void)
{
    volatile unsigned char uc_check[2]={0,0}; /* (Checksummenpuffer)*/
    volatile unsigned char uc_i=0;
    uc_check[0]=uc_receivebuffer[uc_receivebyte-4]; /* High nibble einlesen */
    uc_check[1]=uc_receivebuffer[uc_receivebyte-3]; /* Low nibble einlesen */
    if (uc_check[0]>0x39)
    {
        uc_check[0]=uc_check[0]-0x37; /*ASCII Code A...F */
    }
    else
    {
        uc_check[0]=uc_check[0]-0x30; /*ASCII Code 0...9 */
    }    
    if (uc_check[1]>0x39)
    {
        uc_check[1]=uc_check[1]-0x37;
    }
    else
    {
        uc_check[1]=uc_check[1]-0x30;
    }    
    uc_check[0]=uc_check[0]<<4;         /* Checksummen zusammenführen */
    uc_check[0]=uc_check[0]|uc_check[1];
    
    for (uc_i=0;uc_i<(uc_receivebyte-4);uc_i++)
    {
        uc_check[0]=funk_xor(uc_check[0],uc_receivebuffer[uc_i]); /* XOR Verknüpfung */
    }
    return uc_check[0]; /* Rückgabe der Checksumme, sollte wenn richtig 0 sein */
}

//FIFO Puffer initialisieren bei Fehlern und Datensatzende
void reset_fifo (void)    
{
    /* FIFO Command: Enable FIFO, IT level=8, Sync. Patt + VDI, stop FIFO  */
    #asm ("cbi portb,nsel");
    sendbyte(0b11001110);
    sendbyte(0b10001001);
    #asm ("sbi portb,nsel");
    #asm ("nop");
    
    /* FIFO Command: Enable FIFO, IT level=8, Sync. Patt + VDI, start FIFO  */
    #asm ("cbi portb,nsel");
    sendbyte(0b11001110);
    sendbyte(0b10001011);
    #asm ("sbi portb,nsel");
    #asm ("nop");
    uc_receivebyte=0;
}

// Einen Taktimpuls erzeugen 
void clockpulse(void)
{
    #asm
        nop
        nop
        nop
        sbi portb,sck     ;Clock Port auf 1 setzen
        nop
        nop
        nop
        nop
        nop
        nop
        cbi portb,sck     ;Clock Port auf 0 setzen
        nop
        nop
        nop
        
    
    #endasm
}

// Empfange Daten vom RFM 01
interrupt [EXT_INT0] void ext_int0_isr(void)
{
    unsigned char uc_i=0;
    unsigned char uc_buffer=0;
    unsigned char uc_check=0;
    
    uc_timeout=0; /* Timeout Zähler zurücksetzen */
    
    /* Die ersten 16 Bit des Statuswortes übergehen */
    #asm ("cbi portb,nsel");
    sendbyte(0b00000000);
    sendbyte(0b00000000); 
    
    for(uc_i=0;uc_i<8;uc_i++)/* 8 Bits auslesen */
    {
        
        
        if ((PINB&(1<<3))!=0) /* SDO abfragen = PortB,3 */
        {
            uc_buffer=(uc_buffer<<1)| 0x01;
        }
        else
        {
            uc_buffer=(uc_buffer<<1);     
        }
        clockpulse();
    }
    #asm ("sbi portb,nsel"); /* nSel Leitung abschalten */
    #asm ("nop");
    
        
    uc_receivebuffer[uc_receivebyte]=uc_buffer;
    uc_receivebyte++;
         
    if (uc_buffer==10) /* Line Feed wurde empfangen*/ 
    {
        uc_receivebuffer[uc_receivebyte]=0;
        reset_fifo();
        uc_check=checksum();
        uc_receivebyte=0;
                        
        if (uc_check==0);
        {
            newstring=1;
        }
    }
}   




#define RXB8 1
#define TXB8 0
#define UPE 2
#define OVR 3
#define FE 4
#define UDRE 5
#define RXC 7

#define FRAMING_ERROR (1<<FE)
#define PARITY_ERROR (1<<UPE)
#define DATA_OVERRUN (1<<OVR)
#define DATA_REGISTER_EMPTY (1<<UDRE)
#define RX_COMPLETE (1<<RXC)

// USART Transmitter buffer
#define TX_BUFFER_SIZE 127
char tx_buffer[TX_BUFFER_SIZE];

#if TX_BUFFER_SIZE<256
unsigned char tx_wr_index,tx_rd_index,tx_counter;
#else
unsigned int tx_wr_index,tx_rd_index,tx_counter;
#endif

// USART Transmitter interrupt service routine
interrupt [USART_TXC] void usart_tx_isr(void)
{
if (tx_counter)
   {
   --tx_counter;
   UDR=tx_buffer[tx_rd_index];
   if (++tx_rd_index == TX_BUFFER_SIZE) tx_rd_index=0;
   };
}

#ifndef _DEBUG_TERMINAL_IO_
// Write a character to the USART Transmitter buffer
#define _ALTERNATE_PUTCHAR_
#pragma used+
void putchar(char c)
{
while (tx_counter == TX_BUFFER_SIZE);
#asm("cli")
if (tx_counter || ((UCSRA & DATA_REGISTER_EMPTY)==0))
   {
   tx_buffer[tx_wr_index]=c;
   if (++tx_wr_index == TX_BUFFER_SIZE) tx_wr_index=0;
   ++tx_counter;
   }
else
   UDR=c;
#asm("sei")
}
#pragma used-
#endif


//RFM01 initialisieren
void init_rfm01(void)
{
    volatile unsigned char uc_frequ[2]; /* Frequenz tuningword */
    /* Frequenzwortermittlung aus der Kanalangabe */
    uc_frequ[1]=ui_frequ[uc_kanal]/256;
    uc_frequ[1]|=0b10100000;
    uc_frequ[0]=ui_frequ[uc_kanal]%256;
    
    /* Configuration Setting: 433MHz, CLK on, 11,5pf Kapaz., 67kHz */
    #asm ("cbi portb,nsel");
    sendbyte(0b10001001);
    sendbyte(0b01101100); 
    #asm ("sbi portb,nsel");
    #asm ("nop");
    
    /* Low Batt Clock Divider Command: clock 5MHz */
    #asm ("cbi portb,nsel");
    sendbyte(0b11000010);
    sendbyte(0b11000000); 
    #asm ("sbi portb,nsel");
    #asm ("nop");
    
    /* Frequency Setting: 434MHz (je nach Kanal) */
    #asm ("cbi portb,nsel");
    sendbyte(uc_frequ[1]);
    sendbyte(uc_frequ[0]); 
    #asm ("sbi portb,nsel");
    #asm ("nop");
    
    /* Receiver Setting Command: VDI= Digital RSSI Out, -103dB, receiver disabled */
    #asm ("cbi portb,nsel");
    sendbyte(0b11000000);
    sendbyte(0b10000000);
    #asm ("sbi portb,nsel");
    #asm ("nop");
    
    /* Receiver Setting Command: VDI= Digital RSSI Out, -103dB receiver enabled */
    #asm ("cbi portb,nsel");
    sendbyte(0b11000000);
    sendbyte(0b10000001);
    #asm ("sbi portb,nsel");
    #asm ("nop");
       
    /* FIFO Command: Enable FIFO, IT level=8, Sync. Patt + VDI, stop FIFO  */
    #asm ("cbi portb,nsel");
    sendbyte(0b11001110);
    sendbyte(0b10001001);
    #asm ("sbi portb,nsel");
    #asm ("nop");
    
    /* FIFO Command: Enable FIFO, IT level=8, Sync. Patt + VDI, start FIFO  */
    #asm ("cbi portb,nsel");
    sendbyte(0b11001110);
    sendbyte(0b10001011);
    #asm ("sbi portb,nsel");
    #asm ("nop");
    
    
    /* Data Filter Command:  */
    #asm ("cbi portb,nsel");
    sendbyte(0b11000100);
    sendbyte(0b10101100); 
    #asm ("sbi portb,nsel");
    #asm ("nop");
    
    
    /* Data Rate Command: 2400 bit/s */
    #asm ("cbi portb,nsel");
    sendbyte(0b11001000);
    sendbyte(0b10010001);
    #asm ("sbi portb,nsel");
    #asm ("nop");
    
    
    /* AFC Command: Enable AFC, +3/-4, offset at VDI high */
    #asm ("cbi portb,nsel");
    sendbyte(0b11000110);
    sendbyte(0b10111111); 
    #asm ("sbi portb,nsel");
    #asm ("nop");
       
}

// Timer 1 output compare A interrupt service routine
interrupt [TIM1_COMPA] void timer1_compa_isr(void)
{
/* 1 Sekunde */
uc_timeout++;

if (uc_timeout>3)/* Wenn 3 Sekunden kein Bit mehr Empfangen wurde wird der FiFo resetet */
{
    init_rfm01();
    reset_fifo();
    uc_timeout=0;
}
}

// Declare your global variables here

void main(void)
{
// Declare your local variables here
unsigned char uc_i=0;
// Input/Output Ports initialization
// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=Out Func1=Out Func0=Out 
// State7=T State6=T State5=T State4=T State3=T State2=0 State1=0 State0=0 
PORTB=0x00;
DDRB=0x07;

// Port C initialization
// Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
// State6=T State5=P State4=P State3=P State2=P State1=P State0=P 
PORTC=0x3F;
DDRC=0x00;

// Port D initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T 
PORTD=0x00;
DDRD=0x00;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
TCCR0=0x00;
TCNT0=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 31,250 kHz
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer 1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: On
// Compare B Match Interrupt: Off
// CTC Mode : On
TCCR1A=0x00;
TCCR1B=0x0C;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x7A; /* Comparematch Register mit 31250 laden = 1 Sekunde */
OCR1AL=0x11;
OCR1BH=0x00;
OCR1BL=0x00;

// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer 2 Stopped
// Mode: Normal top=FFh
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;

// External Interrupt(s) initialization
// INT0: On
// INT0 Mode: Falling Edge
// INT1: Off
GICR|=0x40;
MCUCR=0x02;
GIFR=0x40;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x10;

// USART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART Receiver: Off
// USART Transmitter: On
// USART Mode: Asynchronous
// USART Baud Rate: 38400
UCSRA=0x00;
UCSRB=0x48;
UCSRC=0x86;
UBRRH=0x00;
UBRRL=0x0C;

// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;

// Kanalauswahl
uc_kanal=(PINC&0b00111111);

// RFM 01 initialisieren
delay_ms(200);
init_rfm01();
reset_fifo();

// Testroutinen
/*strcpyf (uc_receivebuffer,"$123456789ABCDEF#31");
uc_receivebyte=strlen(uc_receivebuffer);
uc_receivebuffer[uc_receivebyte]=13;
uc_receivebuffer[uc_receivebyte+1]=10;
uc_receivebuffer[uc_receivebyte+2]=0;

uc_receivebyte=strlen(uc_receivebuffer);
checksum();*/
// Ende der Testroutinen

// Global enable interrupts
#asm("sei")

while (1)
      {
      /*newstring=1;*/ /* zu Testzwecken */
      
      if (newstring==1)
      {
        for (uc_i=0;uc_i<strlen(uc_receivebuffer);uc_i++)
        {
        putchar (uc_receivebuffer[uc_i]);
        }
        newstring=0;
      }  
      };
}