/*****************************************************
This program was produced by the
CodeWizardAVR V1.25.5 Standard
Automatic Program Generator
© Copyright 1998-2007 Pavel Haiduc, HP InfoTech s.r.l.
http://www.hpinfotech.com

Project : Telemetrie Sender
Version : 1,1
Date    : 07.05.2009
Author  : Wilhelm Krug                    
Company : 92345 Dietfurt, Germany         
Comments: 


Chip type           : ATmega8
Program type        : Application
Clock frequency     : 8,000000 MHz
Memory model        : Small
External SRAM size  : 0
Data Stack size     : 256
*****************************************************/

/****************************************************
Dieses Programm liest 2 Spannungswerte + 2 Temperaturwerte + Drehzahl
mittels A/D Wandler ein und sendet diese Daten mittels eines RFM 02 Funkmoduls
(Sender) von Pollin aus. Die berechnete Checksumme wird dem Signal angehängt.
Das Sendesignal hat das Format:
Ein Startframe lautet 0xAA 0xAA 0xAA 0x2D 0xD4
Dieses Startframe wird vor den eigentlichen Daten gesendet
und vom FiFo Puffer des Empfängers ausgeblendet.
Jetzt folgen die eigentlichen Daten:
$x1,x2,x3,...xn#cscs<cr><lf>
Das '$' ist das Startzeichen einer Zeile.
x1... Sind die übertragenen Werte
'#' Kennzeichnet das Ende des Datenbereiches
cs cs ist das High und Low Nibble der Checksumme in ASCII Codierung
Die Checksumme ist das Ergebnis einer EXOR Verknüpfung
aller Bytes von '$' bis '#'  
Das Ende einer Übertragung wird durch die Sequenz <CR><LF> gekennzeichnet.

Ab Dip Fix Stellung 22 wird immer der gleiche Kanal gesendet!
Zuordnung: Dip Fix - Kanäle - Frequenz
Dip Fix:Kanal:Frequenz
Dip Kanal	Frequenz
xxx 01	433.075 MHz
00  02	433.100 MHz
xxx 03	433.125 MHz
xxx 04	433.150 MHz
01  05	433.175 MHz
xxx 06	433.200 MHz
xxx 07	433.225 MHz
02  08	433.250 MHz
xxx 09	433.275 MHz
xxx 10	433.300 MHz
03  11	433.325 MHz
xxx 12	433.350 MHz
xxx 13	433.375 MHz
04  14	433.400 MHz
xxx 15	433.425 MHz
xxx 16	433.450 MHz
05  17	433.475 MHz
xxx 18	433.500 MHz
xxx 19	433.525 MHz
06  20	433.550 MHz
xxx 21	433.575 MHz
xxx 22	433.600 MHz
07  23	433.625 MHz
xxx 24	433.650 MHz
xxx 25	433.675 MHz
08  26	433.700 MHz
xxx 27	433.725 MHz
xxx 28	433.750 MHz
09  29	433.775 MHz
xxx 30	433.800 MHz
xxx 31	433.825 MHz
10  32	433.850 MHz
xxx 33	433.875 MHz
xxx 34	433.900 MHz
11  35	433.925 MHz
xxx 36	433.950 MHz
xxx 37	433.975 MHz
12  38	434.000 MHz
xxx 39	434.025 MHz
xxx 40	434.050 MHz
13  41	434.075 MHz
xxx 42	434.100 MHz
xxx 43	434.125 MHz
14  34	434.150 MHz
xxx 45	434.175 MHz
xxx 46	434.200 MHz
15  47	434.225 MHz
xxx 48	434.250 MHz
xxx 49	434.275 MHz
16  50	434.300 MHz
xxx 51	434.325 MHz
xxx 52	434.350 MHz
17  53	434.375 MHz
xxx 54	434.400 MHz
xxx 55	434.425 MHz
18  56	434.450 MHz
xxx 57	434.475 MHz
xxx 58	434.500 MHz
19  59	434.525 MHz
xxx 60	434.550 MHz
xxx 61	434.575 MHz
20  62	434.600 MHz
xxx 63	434.625 MHz
xxx 64	434.650 MHz
21  65	434.675 MHz
xxx 66	434.700 MHz
xxx 67	434.725 MHz
22  68	434.750 MHz
xxx 69	434.775 MHz
Alle DIP FIX mit gültigen Werten versehen !
23  68	434.750 MHz
24  68	434.750 MHz
25  68	434.750 MHz
26  68	434.750 MHz
27  68	434.750 MHz
28  68	434.750 MHz
29  68	434.750 MHz
30  68	434.750 MHz
31  68	434.750 MHz
****************************************************/


#include <mega8.h>
#include <stdlib.h>
#include <string.h>
#include <delay.h>
#asm
.equ tcnt0=0x32
.equ portb=0x18
.equ portd=0x12
.equ sdi=0     ;PortB,0
.equ sck=1     ;PortB,1
.equ nsel=2    ;PortB,2
.equ fsk=1     ;PortD,1
.equ nirq=2    ;PortD,2
#endasm

// Declare your global variables here
// Frequenzwert für das RFM 02
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};
eeprom signed int ee_tempzero[2]={0,0}; /* (249) A/D Wandlerwert für 0°C "(A/D Wandler - X) *290 / tempfakt" */
eeprom signed int ee_tempfakt[2]={290,290}; /* (461) Teilerfaktor für Temperatursteilheit "(A/D Wandler - tempzero) *290 / X" */
eeprom unsigned int ee_voltfakt=360;       /* (500) Multiplikator für Spannungsmessung "A/D Wandler * X / 360" */
eeprom unsigned int ee_voltfakt2=360;       /* (590) Multiplikator für Spannungsmessung "A/D Wandler * X / 360" */

bit new_sec=0;
bit new_value=0;
bit new_drimp=0;                           /* Eine neue Drehzahlmessung liegt vor */
bit sendung_aktiv=0;
volatile unsigned int ui_time=0;           /* Anzahl der Datentelegramme jede Sekunde = +1*/
volatile unsigned long int li_voltage1;    /* Spannung 1 = Akkuspannung */
volatile unsigned long int li_voltage2;    /* Spannung 2 = minimale Akkuspannung */
volatile unsigned long int li_voltage3;    /* Spannung 3 = Externe Spannungsmessung */

volatile signed long int li_temp1;        /* Temperatur 1 max 300°C */
volatile signed long int li_temp2;        /* Temperatur 2 max 300°C */

volatile signed int si_tempzero[2];       /* Korrekturfaktor für Temperatur 1+2 Nullpunkt siehe EEPROM */
volatile signed int si_tempfakt[2];       /* Korrekturfaktor für Temperatur 1+2 Steiheit siehe EEPROM */

volatile unsigned int ui_voltfakt;        /* Speichervariable für Spannungsmessung */
volatile unsigned int ui_voltfakt2;       /* Speichervariable für Spannungsmessung ext. */

volatile unsigned long int li_timer;     /* Timer für Drehzahlbestimmung */
volatile unsigned long int li_oldtimer;  /* Alte Timerwerte für Subtraktion */
volatile unsigned long int li_drwert=0;  /* Berechneter Drehzahlwert */
volatile unsigned long int li_drmittel=0; /* Gemittelte Drehzahlwerte Periodendauermessung */
volatile unsigned char uc_stellen;         /* Anzahl der in die Berechnung eingeflossenen Messwerte */

volatile unsigned long int li_drehzahl;     /* Drehzahlwert */
volatile unsigned int ui_intpulses=0;       /* Impulszähler im Interrupt (Drehzahlmessung) */
volatile unsigned int ui_drpulses=0;        /* Impulszähler im Hauptprogramm (Drehzahlmessung) */
volatile unsigned char uc_blatt=1;          /* Impulse pro umdrehung (1...4)*/

volatile unsigned char uc_sendbuffer[127];  /* Sendepuffer */
volatile unsigned char uc_sendbyte=0;       /* Zeiger aktuelles Sendebyte */
volatile unsigned char uc_sendbit=0;        /* Zeiger aktuelles Sendebit */
volatile unsigned char uc_overflow=0;       /* overflow Zähler - Resettet RFM 02 */
volatile unsigned char uc_kanal;            /* gewählter Kanal */
volatile unsigned int ui_timer;             /* Überlaufzähler für Timer 1 - 1 Sekunde */


// Sende ein Byte zum RFM 02
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
}

// External Interrupt 0 service routine sende Bits zum RFM 02
interrupt [EXT_INT0] void ext_int0_isr(void)
{
volatile unsigned char uc_buffer;
uc_sendbit--;
uc_buffer=(uc_sendbuffer[uc_sendbyte])&(1<<uc_sendbit);
if (uc_buffer == 0)
{
    #asm ("cbi portb,sdi");/*Eine 0 wird gesendet*/
}
else
{
    #asm ("sbi portb,sdi");/*Eine 1 wird gesendet*/
}


/* Alle 8 Bits schon übertragen ? */
if (uc_sendbit==0)
{
    uc_sendbyte++;
    uc_sendbit=8;
}
if (uc_sendbyte>(strlen (uc_sendbuffer)))
{
    /* Ende der Übertragung */
    uc_sendbyte=0;
    uc_sendbit=8;
    GICR&=0b10111111;/*Interrupt 0 sperren*/
    /* Übertragung durch setzen des nSEL Ports beenden */
    #asm ("sbi portb,nsel");
    #asm ("nop");
    /* Power Managment Command= Enable Clock; disable Synthesizer; disable pow. Ampl. */
    #asm ("cbi portb,nsel");
    sendbyte(0b11000000);
    sendbyte(0b00100000); 
    #asm ("sbi portb,nsel");
    sendung_aktiv=0;
    uc_overflow=0; /* Zeitüberwachung zurücksetzen */
}
}


/* Turn registers saving off */
#pragma savereg-
// External Interrupt 1 service routine Drehzahlmesser impulseingang
interrupt [EXT_INT1] void ext_int1_isr(void)
{
    new_drimp=1;
    #asm
    PUSH r26
    IN r26,SREG
    PUSH r26
    PUSH r27
    SEI
    ;*** Erste Phase der Drehzahlermittlung mittels Timerabfrage = Periodendauermessung ***
    IN r26,TCNT0            ;Aktuelle Zeit holen
    CLI
    LDS r27,(_li_oldtimer)  ;Vorherigen Wert holen
    STS (_li_oldtimer),r26  ;Vorheriger alten Wert überschreiben
    SUB r26,r27             ;Unterschied berechnen
    STS (_li_drwert),r26    ;Die berechnung als Wert abspeichern
    
    LDS r26,(_li_timer+1)     ;Das gleiche für die 2te Stelle _li_timer+1 ist der überlauf des TCNT0
    LDS r27,(_li_oldtimer+1)
    STS (_li_oldtimer+1),r26
    SBC r26,r27
    STS (_li_drwert+1),r26
    
    LDS r26,(_li_timer+2)       ;Das gleiche für die 3te Stelle
    LDS r27,(_li_oldtimer+2)
    STS (_li_oldtimer+2),r26
    SBC r26,r27
    STS (_li_drwert+2),r26
    
    LDS r26,(_li_timer+3)      ;Das gleiche für die 4te Stelle
    LDS r27,(_li_oldtimer+3)
    STS (_li_oldtimer+3),r26
    SBC r26,r27
    STS (_li_drwert+3),r26
    
    ;*** Zweite Phase der Drehzahlermittlung mittels Pulszählung ***    
    LDS r26,(_ui_intpulses)
    INC r26
    STS (_ui_intpulses),r26
    BRNE ENDINT1
    LDS r27,(_ui_intpulses+1)
    INC r27
    STS (_ui_intpulses+1),r27
    ENDINT1:
    POP r27
    POP r26
    OUT SREG,r26
    POP r26
    #endasm;
}



// Timer 0 overflow interrupt service routine Drehzahlmesser Pulsdauermessung
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
    #asm
    PUSH r26
    IN r26,SREG
    PUSH r26
    LDS r26,(_li_timer+1)
    INC r26
    STS (_li_timer+1),r26
    BRNE ENDINT0
    LDS r26,(_li_timer+2)
    INC r26
    STS (_li_timer+2),r26
    BRNE ENDINT0
    LDS r26,(_li_timer+3)
    INC r26
    STS (_li_timer+3),r26
    ENDINT0:
    POP r26
    OUT SREG,r26
    POP r26
    #endasm
}
/* re-enable register saving for the other interrupts */
#pragma savereg+


// Timer 1 output compare A interrupt service routine
interrupt [TIM1_COMPA] void timer1_compa_isr(void)
{
/* 1 Sekunde */
ui_timer++;
if (new_drimp>0)
    {
    li_drmittel+=li_drwert;      /* Aufaddierung für Drehzahlmittelwertbildung */
    uc_stellen++;                /* Aufaddierung der Stützstellen */
    new_drimp=0;                 /* Neue Drehzahl Flag löschen*/
    };                             
if (ui_timer>19)
{
    ui_drpulses=ui_intpulses;
    ui_intpulses=0;
    ui_timer=0;
    new_sec=1;
    uc_overflow++;
}
}

#define ADC_VREF_TYPE 0xC0

// Read the AD conversion result
unsigned int read_adc(unsigned char adc_input)
{
ADMUX=adc_input | (ADC_VREF_TYPE & 0xff);
// Delay needed for the stabilization of the ADC input voltage
delay_us(10);
// Start the AD conversion
ADCSRA|=0x40;
// Wait for the AD conversion to complete
while ((ADCSRA & 0x10)==0);
ADCSRA|=0x10;
return ADCW;
}


// Das Sendemodul RFM 02 initialisieren
void init_rfm02(void)
{   
    volatile unsigned char uc_frequ[2]; /* Frequenz tuningword */
    uc_frequ[1]=ui_frequ[uc_kanal]/256;
    uc_frequ[1]|=0b10100000;
    uc_frequ[0]=ui_frequ[uc_kanal]%256;
    /* Configuration Setting: 433MHz, CLK 5MHz, 11,5pf Kapaz., +/-60kHz */
    #asm ("cbi portb,nsel");
    sendbyte(0b10001110);
    sendbyte(0b01100000); 
    #asm ("sbi portb,nsel");
    #asm ("nop");
    
    /* Frequency Setting: eingestellter Kanal*/
    #asm ("cbi portb,nsel");
    sendbyte(uc_frequ[1]);
    sendbyte(uc_frequ[0]); 
    #asm ("sbi portb,nsel");
    #asm ("nop");
    
    /* Output Power Command: Max Power */
    #asm ("cbi portb,nsel");
    sendbyte(0b10110000);
    #asm ("sbi portb,nsel");
    #asm ("nop");
       
    /* Data Rate Command: 2400 bit/s */
    #asm ("cbi portb,nsel");
    sendbyte(0b11001000);
    sendbyte(0b10001111); 
    #asm ("sbi portb,nsel");
    #asm ("nop");
    
    /* Low Batt + Sync Command: enable Sync Circuit */
    #asm ("cbi portb,nsel");
    sendbyte(0b11000010);
    sendbyte(0b00100000); 
    #asm ("sbi portb,nsel");
    #asm ("nop");
    
    /* PLL Setting Command: 0xD240 up to 19,2kbit/s*/
    #asm ("cbi portb,nsel");
    sendbyte(0b11010010);
    sendbyte(0b01000000); 
    #asm ("sbi portb,nsel");
    #asm ("nop");
        
    /* Power Managment Command= Enable Clock; disable Synthesizer; disable pow. Ampl. */
    #asm ("cbi portb,nsel");
    sendbyte(0b11000000);
    sendbyte(0b00100000); 
    #asm ("sbi portb,nsel");
    
}

// Eine Sendung eines Strings starten
void sendbuffer (void)
{
    sendung_aktiv=1; /* Flag für Sendung läuft setzen */
    uc_sendbit=8;
    uc_sendbyte=0;
    GIFR=0x40; /*Anstehende Interrupts 0 löschen*/
    /* Power Managment Command= Enable Clock; enable Synthesizer; enable pow. Ampl. */
    #asm ("cbi portb,nsel");
    sendbyte(0b11000000);
    sendbyte(0b00111000); 
    #asm ("sbi portb,nsel");
    #asm ("nop");
    /*Sender Start Byte senden*/
    #asm ("cbi portb,nsel");
    sendbyte(0b11000110);
    GICR|=(1<<6);/*Interrupt 0 freigeben*/
/* Der Rest der Sendung läuft nun in der Interupt 0 Routine ab */
}

// Werte ermitteln
void get_value (void)
{
li_voltage1=read_adc(0);
li_voltage2=read_adc(1);
li_voltage3=read_adc(6);
li_temp1=read_adc(2);
li_temp2=read_adc(3);
//Drehzahlermittlung
if (ui_drpulses<3)      /* Drehzahlen unter 120 U/min werden ignoriert */
{
    li_drehzahl=0;
}
else
{
    if (ui_drpulses<350) /* Entscheidung welches Drehzahlermittlungsverfahren angewendet wird bei 21000 U/min*/
    {
        li_drmittel=li_drmittel/uc_stellen;        /* Mittelwert der Drehzahlmessungen errechnen */
        li_drehzahl=7500000/(li_drmittel*uc_blatt);  /* Periodendauermessung */
    }
    else
    {
        li_drehzahl=ui_drpulses;                   /* Pulszählung in Torzeit ( 1Sekunde )*/
        li_drehzahl=(li_drehzahl*60)/uc_blatt;
    }
}
ui_drpulses=0;   /* Pulszählung zurücksetzen */
li_drmittel=0;   /* Mittelwertbildner zurücksetzen */
uc_stellen=0;    /* Stützstellenzähler zurücksetzen */

// Werteberechnung 2x Spannung 2x Temperatur
li_voltage1=(li_voltage1*ui_voltfakt)/360;
li_voltage2=(li_voltage2*ui_voltfakt)/360;
li_voltage3=(li_voltage3*ui_voltfakt2)/360;

if (li_temp1==1023)
    {
    li_temp1=0;
    }
else        
    {
    #asm("cli");
    li_temp1=((li_temp1-si_tempzero[0])*290)/si_tempfakt[0];
    #asm("sei");
    }
if (li_temp2==1023)
    {
    li_temp2=0;
    }
else
    {
    #asm("cli");
    li_temp2=((li_temp2-si_tempzero[1])*290)/si_tempfakt[1];
    #asm("sei");
    }
}


// Checksumme berechnen - EXOR Verfahren
void checksum (void)
{
    volatile unsigned char uc_check[3]={0,0,0}; /* (Checksummenpuffer)*/
    volatile unsigned char uc_stringlengh;
    volatile unsigned char uc_i=0;
    uc_stringlengh=strlen(uc_sendbuffer);
    for (uc_i=5; uc_i<uc_stringlengh ;uc_i++) /* Die relevanten Bytes für Checksumme ermitteln */
    {
        uc_check[0]^=uc_sendbuffer[uc_i]; /* Checksumme errechnen */
    }
    // Checksumme in ASCII umwandeln
    uc_check[1]=uc_check[0];
    
    uc_check[0]&=0xF0;          /* Higher Nibble to ASCII */
    uc_check[0]=(uc_check[0]>>4);
    
    if (uc_check[0]>9)
    {
        uc_check[0]=uc_check[0]+0x37;
    }
    else
    {
        uc_check[0]|=0x30;
    }
    uc_check[1]&=0x0F;          /* Lower Nibble to ASCII */
    
    if (uc_check[1]>9)
    {
        uc_check[1]=uc_check[1]+0x37;
    }
    else
    {    
        uc_check[1]|=0x30;
    }
    
    uc_check[2]=0;              /* Einfügen wegen Stringverarbeitung */
    strcat (uc_sendbuffer,uc_check); /* Checksumme anhängen */
}

// Sendestring vorbereiten
void builtstring (void)
{
unsigned char uc_stringbuffer[10];
volatile unsigned char uc_stringlengh;

uc_sendbuffer[0]=0xAA;
uc_sendbuffer[1]=0xAA;
uc_sendbuffer[2]=0xAA;
uc_sendbuffer[3]=0x2D;
uc_sendbuffer[4]=0xD4;
uc_sendbuffer[5]='$';
uc_sendbuffer[6]='3';
uc_sendbuffer[7]=';';
uc_sendbuffer[8]='1';
uc_sendbuffer[9]=';';
uc_sendbuffer[10]=0x00;

itoa (ui_time,uc_stringbuffer);
strcat (uc_sendbuffer,uc_stringbuffer);
strcatf (uc_sendbuffer,";");

ltoa (li_voltage1,uc_stringbuffer);
strcat (uc_sendbuffer,uc_stringbuffer);
strcatf (uc_sendbuffer,";");

ltoa (li_voltage2,uc_stringbuffer);
strcat (uc_sendbuffer,uc_stringbuffer);
strcatf (uc_sendbuffer,";");

ltoa (li_voltage3,uc_stringbuffer);
strcat (uc_sendbuffer,uc_stringbuffer);
strcatf (uc_sendbuffer,";0;0;0;0;");

ltoa (li_temp1,uc_stringbuffer);
strcat (uc_sendbuffer,uc_stringbuffer);
strcatf (uc_sendbuffer,";");

ltoa (li_temp2,uc_stringbuffer);
strcat (uc_sendbuffer,uc_stringbuffer);
strcatf (uc_sendbuffer,";");

ltoa (li_drehzahl,uc_stringbuffer);
strcat (uc_sendbuffer,uc_stringbuffer);
strcatf (uc_sendbuffer,";");

checksum(); /* Checksumme ermitteln und anfügen */

// Stringendebytes anfügen
uc_stringlengh=strlen(uc_sendbuffer);
uc_sendbuffer[uc_stringlengh]=13;    /* Carriage Return 13*/
uc_sendbuffer[uc_stringlengh+1]=10;    /* Line Feed 10 */
uc_sendbuffer[uc_stringlengh+2]=0;     /* Stringende anfügen */
}

// Hauptprogramm
void main(void)
{
// Declare your local variables here
li_timer=0;
li_oldtimer=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=P State4=P State3=P State2=1 State1=0 State0=0 
PORTB=0x3C;
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=T State2=T State1=T State0=T 
PORTC=0x30;
DDRC=0x00;

// Port D initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=Out Func0=In 
// State7=P State6=P State5=P State4=T State3=T State2=T State1=0 State0=T 
PORTD=0xE0;
DDRD=0x02;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 125,000 kHz
TCCR0=0x03;
TCNT0=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 1000,000 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=0x0A;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0xC3;
OCR1AL=0x4F;
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: Off
// INT0 Mode: Falling Edge
// INT1: On
// INT1 Mode: Falling Edge
GICR|=0x80;
MCUCR=0x0A;
GIFR=0xC0;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x11;

// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;

// ADC initialization
// ADC Clock frequency: 156,250 kHz
// ADC Voltage Reference: Int., cap. on AREF
ADMUX=ADC_VREF_TYPE & 0xff;
ADCSRA=0x85;

// EEPROM Werte ins RAM laden
ui_voltfakt=ee_voltfakt;
ui_voltfakt2=ee_voltfakt2;
si_tempzero[0]=ee_tempzero[0];
si_tempzero[1]=ee_tempzero[1];
si_tempfakt[0]=ee_tempfakt[0];
si_tempfakt[1]=ee_tempfakt[1];


uc_blatt=((PINC>>4)&0b00000011)+1; /* Blattzahl für Drehzahlmessung ermitteln */
uc_kanal=(PINB>>3)&0b00000111;     /* Eingestellten Sendekanal ermitteln */
uc_kanal=uc_kanal|((PIND>>2)&00011000);


init_rfm02();
/*
// Testroutines
strcpyf(uc_sendbuffer,"AAA2d$3;0;0;1029;649;0;0;0;0;0;25;24;0;"); // Check = 1C
checksum();*/

// Global enable interrupts
#asm("sei");

while (1)
      {
      if (new_sec==1&&sendung_aktiv==0)/* Nach einer Sekunde neue Messwerte erkunden */
      {
        get_value();    /* Werte berechnen */
        builtstring();  /* Sendestring bilden */
        new_sec=0;      /* Sekundenmarker auf 0 setzen */
        ui_time++;      /* Sendezeit erhöhen */
        new_value=1;    /* Marker - Neue Werte zum senden bereit */
      }
      
      if (sendung_aktiv==0&new_value==1)/* Die Messwerte versenden */
      {
        sendbuffer();   /* Sendung (interruptgesteuert) starten */
        new_value=0;    /* Neue Werte werden gesendet */
      }
      if (uc_overflow>2)/* Schlägt zu wenn eine Übertragung länger als 3 sek dauert */
      {
        // Aktive Sendung beenden Interrupts sperren
        #asm ("cli");
        uc_sendbyte=0;
        uc_sendbit=8;
        GICR&=0b10111111;/*Interrupt 0 sperren*/
        GIFR|=0b01000000;/*Interrupt 0 flag löschen */
        /* Übertragung durch setzen des nSEL Ports beenden */
        #asm ("sbi portb,nsel");
        #asm ("nop");
        // Sender abschalten
        /* Power Managment Command= Enable Clock; disable Synthesizer; disable pow. Ampl. */
        #asm ("cbi portb,nsel");
        sendbyte(0b11000000);
        sendbyte(0b00100000); 
        #asm ("sbi portb,nsel");
        
        sendung_aktiv=0; /* Flag für aktive Sendung löschen */
        uc_overflow=0; /* Zeitüberwachung zurücksetzen */
        
        // RFM 02 neu initialisieren
        init_rfm02();
        
        // Nächsten Zyklus abwarten - 1 Sekunde
        new_sec=0;
        new_value=0;
        
        // Interrupts freigeben
        #asm ("sei");
      }
      
      };
}
