/*****************************************************
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 : LiPo Voltmeter
Version : 2.2
Date    : 23.03.2010
Author  : Wilhelm Krug                    
Company : 92345 Dietfurt, Germany         
Comments: 


Chip type           : ATmega32
Program type        : Application
Clock frequency     : 16,000000 MHz
Memory model        : Small
External SRAM size  : 0
Data Stack size     : 512
*****************************************************/

/****************************************************
Dieses Programm liest die Daten eines RFM 01 Funkmoduls
(Empfänger) von Pollin aus und berechnet anhand der mitgelieferten
Checksumme ob das Signal Fehler enthielt.
Fehlerfreie Frames werden an die serielle Schnittstelle im Format
38400,8,N,1 übertragen.
Das Empfangssignal hat das Format:
Ein Startframe lautet 0xAA 0xAA 0xAA 0x2D 0xD4
Dieses Startframe wird vor den eigentlichen Daten gesendet
und vom FiFo Puffer dieses 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
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 letzter Datensatz  
Die Berechnung der Checksumme und die Sendung an die
serielle Schnittstelle wird durch das Zeichen <lf> getriggert.
Nur fehlerfreie Frames werden an die serielle Schnittstelle gesendet

Zuordnung Kanäle - Dip Fix - 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 <mega32.h>

#include <stdio.h>
#include <string.h>
#include <delay.h>
#include <stdlib.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 sdo=3     ;PortB,3
.equ nirq=3    ;PortD,3
#endasm

#define ad7795_cs PORTB.5
#define ad7795_clock PORTB.7
#define ad7795_din PORTA.7

#define ad7795_dout PINB.6

#define logging PORTA.6


// Alphanumeric LCD Module functions
#asm
   .equ __lcd_port=0x15 ;PORTC
#endasm
#include <lcd4x40.h>

typedef unsigned char byte;

/* table for the user defined character
   arrow that points to the top */
flash byte char1[8]={
0b0000100,
0b0001110,
0b0011111,
0b0010101,
0b0000100,
0b0000100,
0b0000100,

0b0000100};

/* invers arrow that points to the top */
flash byte char2[8]={
0b0011011,
0b0010001,
0b0000000,
0b0001010,
0b0011011,
0b0011011,
0b0011011,

0b0011011};

/* arrow that points to the bottom */
flash byte char3[8]={
0b0000100,
0b0000100,
0b0000100,
0b0000100,
0b0010101,
0b0011111,
0b0001110,

0b0000100};

/* invers arrow that points to the bottom */
flash byte char4[8]={
0b0011011,
0b0011011,
0b0011011,
0b0011011,
0b0001010,
0b0000000,
0b0010001,

0b0011011};
 
/* invers star */
flash byte char5[8]={
0b0011111,
0b0011011,
0b0001010,
0b0010001,
0b0001010,
0b0011011,
0b0011111,

0b1111111};

/* function used to define user characters */
void define_char(byte flash *pc,byte char_code)
{
byte i,a;
a=(char_code<<3) | 0x40;
for (i=0; i<8; i++) lcd_write_byte(a++,*pc++);
}



// 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_receivedata[127]; /* Zwischenpuffer der Telemetrie Empfangsdaten zur internen Weiterverarbeitung */
volatile unsigned char uc_sendbuffer[127]; /* Sendepuffer */
volatile unsigned char uc_receivebyte=0;/* Zeiger aktuelles Sendebyte */
volatile unsigned char uc_timeout=0;
volatile unsigned char uc_kanal; /* gewählter Kanal */
volatile unsigned char uc_aderror=0; /* Fehlerzähler für den AD 7795 */
volatile unsigned char uc_startmenu; /* Hilfsvariable für Startmenüauswahl */
volatile unsigned char uc_tast,uc_oldtast; /* Puffer für Tastenabfrage */

volatile unsigned int ui_timer;          /* Overflow Zähler für Timer1 Comparematch Routine */ 
bit new_sec;                             /* Eine Skekunde ist verstrichen */
bit uc_datalog=0;                        /* Marker - Datenlogging auf Speicherchip*/
bit ub_logging=0;                        /* 0 = keine serielle Datenübertragung, 1 = serielle Datenübertragung an */
bit new_drimp=0;                         /* Flag neuer Drehzahlimpuls*/

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 int ui_time;           /* Aktueller Zeitstempel */
volatile unsigned char uc_overflow;      /* Überlaufzähler für drehzahlroutine */
volatile unsigned char uc_stellen;       /* Anzahl der Stützstellen Drehzahlermittlung */

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 int ui_blatt=100;         /* Impulse pro umdrehung (1...4)*/
volatile unsigned char uc_lowblatt=0;       /* Nachkommastellen Blattzahl */
volatile unsigned char uc_highblatt=1;      /* Blattzahl Stellen vor dem Komma*/

volatile unsigned int ui_7795[6];           /* Speicher für 6 A/D Werte vom AD7795 */
volatile unsigned int ui_old7795[6];        /* Speicher für 6 A/D alte Werte vom AD7795 */
volatile unsigned char uc_cells;            /* Aktuelle Zellenanzahl */

volatile signed int si_currl;               /* Speicher für den 5A Strommessbereich */
volatile signed int si_currh;               /* Speicher für den 50A Strommessbereich */
volatile signed long int li_curr;           /* Speicherplatz für den Stromwert */
volatile signed int si_currcor;             /* Korrekturfaktor für den Strom H - Messbereich (200)*/
volatile signed int si_currnull;            /* Korrekturfaktor für den Strom H - Messbereich (500)*/
volatile signed int si_currlcor;            /* Korrekturfaktor für den Strom L - Messbereich (200)*/
volatile signed int si_currlnull;           /* Korrekturfaktor für den Strom L - Messbereich (500)*/
volatile signed int si_tempzero[2];         /* (249) A/D Wandlerwert für 0°C "(A/D Wandler - X) *290 / tempfakt" */
volatile signed int si_tempfakt[2];         /* (461) Teilerfaktor für Temperatursteilheit "(A/D Wandler - tempzero) *290 / X" */
volatile unsigned int ui_ufaktor;           /* Variable für den Spannungsmesser (A/D Wandler 4)org 141 A/D*ui_ufaktor/512 */

// *** Telemetrie Daten Puffer
volatile unsigned int ui_teletimer=0;           /* Puffer für Telemetrie Spannung 1*/
volatile unsigned int ui_televolt1=0;           /* Puffer für Telemetrie Spannung 1*/
volatile unsigned int ui_televoltmin=0;         /* Puffer für Telemetrie Minimalspannung*/
volatile unsigned int ui_televolt2=0;           /* Puffer für Telemetrie Spannung 2*/
volatile signed int si_teletemp1=0;             /* Puffer für Telemetrie Temperatur 1*/
volatile signed int si_teletemp2=0;             /* Puffer für Telemetrie Temperatur 2*/
volatile unsigned long int li_teledrehzahl=0;   /* Puffer für Telemetrie Drehzahlmesser*/
volatile unsigned char uc_alive=0;              /* Zähler für Lebensanzeige */

// *** EEPROM Speicherplätze
eeprom signed int ee_currcor=200;           /* Korrekturfaktor für den Strom H - Messbereich (200)*/
eeprom signed int ee_currnull=493;          /* Korrekturfaktor für den Strom H - Messbereich (500)*/
eeprom signed int ee_currlcor=200;          /* Korrekturfaktor für den Strom L - Messbereich (200)*/
eeprom signed int ee_currlnull=500;         /* Korrekturfaktor für den Strom L - Messbereich (500)*/
eeprom signed int ee_tempzero[2]={240,240}; /* (249) A/D Wandlerwert für 0°C "(A/D Wandler - X) *290 / tempfakt" */
eeprom signed int ee_tempfakt[2]={390,390}; /* (461) Teilerfaktor für Temperatursteilheit "(A/D Wandler - tempzero) *290 / X" */
eeprom unsigned int ee_ufaktor=142;         /* Variable für den Spannungsmesser (A/D Wandler 4)org 141 */
eeprom unsigned char ee_startmenu=1;        /* Startmenüauswahl */
eeprom unsigned int ee_blatt=100;           /* Startwert für Blattzahl / 100 */
eeprom unsigned char ee_kanal=0;            /* Startwert für Empfangskanal */


volatile signed long int ul_voltage[7];     /* 6 Speicherstellen für die absolute Spannung der Zellen */ 
volatile signed long int ul_diffvoltage[7]; /* 6 Speicherstellen für die differenz Spannung der Zellen */
volatile signed long int ul_oldvoltage[6];  /* 6 Speicherstellen für die vorherigen Spannungswerte */
volatile signed long int ul_maxvoltage=0;   /* maximale Einzelzellenspannung */
volatile unsigned char uc_maxcell=0;        /* Zelle mit der maximalen Spannung */
volatile signed long int li_temp1;          /* Speicherplatz für Temperatur 1*/
volatile signed long int li_temp2;          /* Speicherplatz für Temperatur 2*/

volatile unsigned char uc_dispmode;         /* Gewünschter Displaymode 0 = Differentiell, 1 = Summiert, 2 = Antriebsvermessung, 3 = Telemetrie, 4 = Logging, 5 = Einstellungen, 6 = Kalibrierung */

/* Turn registers saving off */
#pragma savereg-
// 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
}
/* re-enable register saving for the other interrupts */
#pragma savereg+

/* Turn registers saving off */
#pragma savereg-
// 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
}
/* re-enable register saving for the other interrupts */
#pragma savereg+

//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;
}

// Checksumme beim senden berechnen
void tchecksum (void)
{
    volatile unsigned char uc_check[3]={0,0,0}; /* (Checksummenpuffer)*/
    volatile unsigned char uc_i=0;
    
    for (uc_i=0; uc_i<strlen(uc_sendbuffer); uc_i++) /* Die relevanten Bytes für Checksumme ermitteln */
    {
        uc_check[0]=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 */
}
    


// Checksumme Funkmodul Empfang berechnen
unsigned char checksum (void)
{
    volatile unsigned char uc_check[2]={0,0}; /* (Checksummenpuffer)*/
    volatile unsigned char uc_i=0;
    volatile unsigned char uc_stringlengh=0;
    uc_stringlengh=strlen(uc_receivebuffer);
    uc_check[0]=uc_receivebuffer[uc_stringlengh-4]; /* High nibble einlesen */
    uc_check[1]=uc_receivebuffer[uc_stringlengh-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]&=0x0F;
    uc_check[1]&=0x0F;
    uc_check[0]=uc_check[0]*16;         /* Checksummen zusammenführen */
    uc_check[0]=uc_check[0]|uc_check[1];
    
    for (uc_i=0;uc_i<(uc_stringlengh-4);uc_i++)
    {
        uc_check[0]^=uc_receivebuffer[uc_i]; /* XOR Verknüpfung */
    };
    return uc_check[0]; /* Rückgabe der Checksumme, sollte wenn richtig 0 sein */
}


/* re-enable register saving for the other interrupts */
#pragma savereg+

// External Interrupt 1 service routine - FiFo Puffer des RFM01 voll
interrupt [EXT_INT1] void ext_int1_isr(void)
{
    unsigned char uc_i=0;
    unsigned char uc_rbuffer=0;
    unsigned char uc_check=0;
        
    
    uc_timeout=0; /* Timeout Zähler zurücksetzen */
    
    /* Die ersten 16 Bit des Statuswortes übergehen */
    #asm ("cbi portb,sdi");
    #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_rbuffer=(uc_rbuffer<<1)| 0x01;
        }
        else
        {
            uc_rbuffer=(uc_rbuffer<<1);     
        }
        clockpulse();
    }
    #asm ("sbi portb,nsel"); /* nSel Leitung abschalten */
    #asm ("nop");
    
            
    // Hingen noch Reste im Puffer ? oder Puffer Überlauf -> Dann löschen    
    if((uc_rbuffer=='$')||(uc_receivebyte>125))
    {
        uc_receivebyte=1;
        uc_receivebuffer[0]='$';     /* Das Erste Byte des Empfangspuffers mit $ beschreiben*/
        uc_receivebuffer[1]=0;             /* Ein Stringende anfügen*/
    }
    else
        {
        uc_receivebuffer[uc_receivebyte]=uc_rbuffer;
        uc_receivebyte++;
        uc_receivebuffer[uc_receivebyte]=0; /* Stringende anfügen */
        };
         
    if (uc_rbuffer==10) /* Line Feed wurde empfangen*/ 
    {
        reset_fifo();
        uc_check=checksum();
                               
                
        if (uc_check==0)
        {
            strcpy(uc_receivedata,uc_receivebuffer);
            newstring=1;
        };
        uc_receivebyte=0;   
    }
}

/* Turn registers saving off */
#pragma savereg-
// External Interrupt 0 service routine Drehzahlmesser impulseingang
interrupt [EXT_INT0] void ext_int0_isr(void)
{
    #asm
    PUSH r26
    IN r26,TCNT0            ;Aktuelle Zeit so früh wie möglich holen
    PUSH r27
    IN r27,SREG
    PUSH r27
        
    ;*** Erste Phase der Drehzahlermittlung mittels Timerabfrage = Periodendauermessung ***
    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
    OUT SREG,r27
    POP r27
    POP r26
    #endasm;
    new_drimp=1;
}
/* re-enable register saving for the other interrupts */
#pragma savereg+

/* Turn registers saving off */
#pragma savereg-
// 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+


#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 256
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

// Standard Input/Output functions
#include <stdio.h>

//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 */
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>39)
    {
    ui_drpulses=ui_intpulses;    /* Die Impulse aus dem Interrupt werden an das Rechenregister übergeben */
    ui_intpulses=0;              /* Der Interruptzähler wird resettet */
    ui_timer=0;                  /* Der Überlaufzähler für 1 sek wird auf 0 gesetzt */
    new_sec=1;
    uc_overflow++;
    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;
        };
    };
}


#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;
}



/* Einen Clockimpuls für den AD7795 generieren */
void clock_ad7795 (void)
{
#asm("nop");
#asm("nop");
ad7795_clock=0;
#asm("nop");
#asm("nop");
#asm("nop");
#asm("nop");
ad7795_clock=1;
#asm("nop");
#asm("nop");
}

// Auslesen der Tasten
unsigned char read_tast(void)
{
unsigned char uc_buffer[2];
uc_buffer[0]=PIND&0b11110000;   /* Port B einlesen und Tasten separieren */
delay_ms(10);                   /* 10ms warten */
uc_buffer[1]=PIND&0b11110000;   /* Port B nochmals einlesen und Tasten separieren */
if(uc_buffer[0]==uc_buffer[1])  /* Sind beide Tasten gleich -> Werte zurückgeben */
{
    return(uc_buffer[0]);
}
else
{
    return (0);                 /* Verschieden = Fehler = 0 zurückgeben */
}
};

/* 8Bit in den AD7795 schreiben */
void write_ad7795 (unsigned char uc_byte)
{
unsigned char i=0;
for(i=0;i<8;i++)
{
    if((uc_byte&(1<<7))==(1<<7))
    {
        ad7795_din=1;
    }
    else
    {
        ad7795_din=0;
    }
    clock_ad7795();
    uc_byte=uc_byte<<1;
}
ad7795_din=1;
}

/* AD Wandlerwert holen AD7795 */
unsigned int read_ad7795 (unsigned char uc_channel)
{
    unsigned char uc_i;
    unsigned int ad_value=0;
    
    uc_channel=uc_channel&0b00000111; /* Höherwertige Bits abtrennen */
    
    // Init Configutation Register for Channel X
    ad7795_din=1;
    ad7795_cs=0;
    write_ad7795(0b00010000);   /* Write to Configutation Register */
    write_ad7795(0b00011000);   /* Write value to Configutation Register high = VBIAS=OFF, Unipolar=1, Boost=On, Gain=1,*/
    write_ad7795((0b10010000|uc_channel));   /* Write value to Configutation Register low = RefSel=1,17V int, Buf=ON, CH=X */
    ad7795_cs=1;
    #asm("nop");
    
    // Init Mode Register = Read selected AD Channel
    ad7795_cs=0;
    write_ad7795(0b00001000);   /* Write to Mode Register */
    write_ad7795(0b00100000);   /* Write value to Mode Register high = Single Conversation=On, AMP_CM=OFF*/
    write_ad7795(0b00000100);   /* Write value to Mode Register low = CLK=int 64kHz,CHOP=en,UPD_Rate=62Hz*/
    
    uc_tast=read_tast();        /* Tastatur während der A/D Wandlerabfrage abfragen, damit kein Druck verloren geht */
        if(uc_tast!=uc_oldtast)
            {
            uc_oldtast=uc_tast;
            switch (uc_tast)
                {
                case 0xD0 :
                uc_dispmode++;
                if (uc_dispmode>4){uc_dispmode=0;};
                break;
            
                case 0xB0 :
                uc_dispmode--;
                if ((uc_dispmode+1)==0){uc_dispmode=4;};
                break;
            
                };
            };
    
    delay_ms(40);               /* Auf A/D Wandler warten - Wegen Tastaturabfrage auf 40ms verkürzt normal 50!*/
    if (ad7795_dout==1)
    {
        delay_ms(50);          /* Nochmal warten */
    }
    if (ad7795_dout==1)
    {
        ad_value=0;             /* Fehlerzähler hochzählen */
        uc_aderror++;
    }
    else                        /* A/D Wandler auslesen */
    {
        write_ad7795(0b01011000);  /* Readout Dataregister Command */
        for (uc_i=0;uc_i<16;uc_i++)
        {
            if (ad7795_dout==1)
            {
                ad_value=ad_value|0x0001;
            };
        ad_value=(ad_value<<1);
        clock_ad7795();
        }
    };
    
    ad7795_cs=1;
    #asm("nop");
    
    return (ad_value);
}

/* Reset für den AD7795 */
void reset_ad7795 (void)
{
    unsigned char uc_i;
    ad7795_cs=0;
    #asm("nop");
    ad7795_din=1;
    for(uc_i=0;uc_i<34;uc_i++) /* eigentlich 32 */
    {          
        clock_ad7795();
    }
    ad7795_cs=1;
    #asm("nop");
}


/* Initialisieren des AD7795 */
void init_ad7795 (void)
{
    volatile unsigned char uc_i;
    for(uc_i=0;uc_i<4;uc_i++)
    {
        // Init Configutation Register Ch X
        ad7795_cs=0;
        write_ad7795(0b00010000);   /* Write to Configutation Register */
        write_ad7795(0b00011000);   /* Write value to Configutation Register high = VBIAS=OFF, Unipolar=1, Boost=On, Gain=1,*/
        write_ad7795(0b10010000|uc_i);   /* Write value to Configutation Register low = RefSel=1,17V int, Buf=ON, CH=AIN X */
        ad7795_cs=1;
        #asm("nop");
    
        // Init Mode Register = Init Zero Calibration Ch X
        ad7795_cs=0;
        write_ad7795(0b00001000);   /* Write to Mode Register */
        write_ad7795(0b10000000);   /* Write value to Mode Register high = Zero Calibration=On, AMP_CM=OFF*/
        write_ad7795(0b00000100);   /* Write value to Mode Register low = CLK=int 64kHz,CHOP=en,UPD_Rate= 62Hz */
        delay_ms(50);
        if (ad7795_dout==1)
        {
            delay_ms(100);
            uc_aderror++;
        }
        ad7795_cs=1;
        #asm("nop");
        
        // Init Mode Register = Init Full Scale Calibration Ch X
        ad7795_cs=0;
        write_ad7795(0b00001000);   /* Write to Mode Register */
        write_ad7795(0b10100000);   /* Write value to Mode Register high = Full Scale Calibration=On, AMP_CM=OFF*/
        write_ad7795(0b00000100);   /* Write value to Mode Register low = CLK=int 64kHz,CHOP=en,UPD_Rate=62Hz*/
        delay_ms(50);
        if (ad7795_dout==1)
        {
            delay_ms(100);
            uc_aderror++;
        }
        
        ad7795_cs=1;
        #asm("nop");
    }
};

/* 6 A/D Werte aus dem AD7795 auslesen und abspeichern */
void read6_ad7795 (void)
{
    unsigned char uc_i;
    for (uc_i=0;uc_i<6;uc_i++)
    {
        ui_old7795[uc_i]=ui_7795[uc_i];
        ui_7795[uc_i]=read_ad7795(uc_i);
    }

}

// LiPo Voltmeter kalibrieren
void calibrate(void)
{
unsigned char uc_i=0;
signed int si_buffer1=0;
signed int si_buffer2=0;
signed long int li_calc=0;
unsigned char uc_stringbuffer[20];
unsigned char uc_string[6];
uc_oldtast=uc_tast;
lcd_clear();
lcd_gotoxy(0,0);
lcd_putsf("Kalibrierung");
lcd_gotoxy(0,1);
lcd_putsf("  -     ENT");

while ((uc_tast==uc_oldtast)||(uc_tast==0)||(uc_tast==0xF0)){uc_tast=read_tast();}; /* Ständig Tasten abfragen */

if (uc_tast==0x70)
    {
    lcd_clear();
    lcd_gotoxy(0,0);
    lcd_putsf("Stromsensor Nullabgleich");
    delay_ms(1000);
    uc_tast=0xF0;
    uc_oldtast=uc_tast;
    while (uc_tast!=0x70)           /* A/D Wandler für Stromsensor auslesen und anzeigen */
        {
        si_currlnull=0;
        si_currnull=0;
        for (uc_i=0;uc_i<10;uc_i++)
            {
            si_buffer1=read_adc(0);
            si_buffer2=read_adc(1);
            si_currlnull=si_currlnull+si_buffer1;
            si_currnull=si_currnull+si_buffer2;
            
            };

        si_currlnull=si_currlnull/10;
        si_currnull=si_currnull/10;
        lcd_gotoxy(5,1);
        itoa(si_currlnull,uc_stringbuffer);
        strcatf(uc_stringbuffer," ADC low   ");
        lcd_puts(uc_stringbuffer);
        lcd_gotoxy(5,2);
        itoa (si_currnull,uc_stringbuffer);
        strcatf(uc_stringbuffer," ADC high   ");
        lcd_puts(uc_stringbuffer);
        uc_tast=read_tast();
        };
    
    if((ee_currlnull!=si_currlnull)||(ee_currnull!=si_currnull))
        {
        ee_currlnull=si_currlnull;
        ee_currnull=si_currnull;
        };
    lcd_clear();
    lcd_gotoxy(0,0);
    lcd_putsf(" Werte gespeichert ");
    delay_ms(1000);
            
        
    // Kalibrierung Strom Low Meßbereich
    lcd_clear();
    lcd_gotoxy(0,0);
    lcd_putsf("Strom Low Kalibr.");
    delay_ms(1000);
    uc_tast=read_tast();
    uc_oldtast=uc_tast;
    while (uc_tast!=0x70)           /* A/D Wandler für Stromsensor auslesen und anzeigen */
        {
        uc_tast=read_tast();
        if(uc_tast!=uc_oldtast)
            {
            if(uc_tast==0xD0)
                {
                si_currlcor++;
                };
            if(uc_tast==0xB0)
                {
                si_currlcor--;
                };
            uc_oldtast=uc_tast;
            };
        li_calc=read_adc(0);
        li_calc=li_calc-si_currlnull;
        li_calc=li_calc*si_currlcor;
        li_calc=li_calc/160;
        
        lcd_gotoxy(5,1);
        itoa(si_currlcor,uc_stringbuffer);
        strcatf(uc_stringbuffer," Korr.   ");
        lcd_puts(uc_stringbuffer);
        lcd_gotoxy(5,2);
        if (li_calc<0)
            {
            lcd_putsf("-");
            li_calc=li_calc*(-1);
            }
        else
            {
            lcd_putsf(" ");
            };
        si_buffer2=li_calc/100;
        lcd_gotoxy(6,2);
        if(si_buffer2<9)
            {
            lcd_gotoxy(7,2);
            };
        itoa(si_buffer2,uc_string);
        strcpy(uc_stringbuffer,uc_string);
        strcatf(uc_stringbuffer,",");
        si_buffer2=li_calc%100;
        if(si_buffer2<10)
            {
            strcatf(uc_stringbuffer,"0");
            };
        itoa (si_buffer2,uc_string);
        strcat(uc_stringbuffer,uc_string);
        
        strcatf(uc_stringbuffer," A   ");
        lcd_puts(uc_stringbuffer);
        };
    
    if(ee_currlcor!=si_currlcor)
        {
        ee_currlcor=si_currlcor;
        };
    lcd_clear();
    lcd_gotoxy(0,0);
    lcd_putsf(" Werte gespeichert ");
    delay_ms(1000);
    
    // Kalibrierung Strom High Meßbereich
    lcd_clear();
    lcd_gotoxy(0,0);
    lcd_putsf("Strom High Kalibr.");
    delay_ms(1000);
    uc_tast=read_tast();
    uc_oldtast=uc_tast;
    while (uc_tast!=0x70)           /* A/D Wandler für Stromsensor auslesen und anzeigen */
        {
        uc_tast=read_tast();
        if(uc_tast!=uc_oldtast)
            {
            if(uc_tast==0xD0)
                {
                si_currcor++;
                };
            if(uc_tast==0xB0)
                {
                si_currcor--;
                };
            uc_oldtast=uc_tast;
            };
        li_calc=read_adc(1);
        li_calc=li_calc-si_currnull;
        li_calc=li_calc*si_currcor;
        li_calc=li_calc/16;
        
        lcd_gotoxy(5,1);
        itoa(si_currcor,uc_stringbuffer);
        strcatf(uc_stringbuffer," Korr.   ");
        lcd_puts(uc_stringbuffer);
        lcd_gotoxy(5,2);
        if (li_calc<0)
            {
            lcd_putsf("-");
            li_calc=li_calc*(-1);
            }
        else
            {
            lcd_putsf(" ");
            };
        si_buffer2=li_calc/100;
        lcd_gotoxy(6,2);
        if(si_buffer2<9)
            {
            lcd_gotoxy(7,2);
            };
        itoa(si_buffer2,uc_string);
        strcpy(uc_stringbuffer,uc_string);
        strcatf(uc_stringbuffer,",");
        si_buffer2=li_calc%100;
        if(si_buffer2<10)
            {
            strcatf(uc_stringbuffer,"0");
            };
        itoa (si_buffer2,uc_string);
        strcat(uc_stringbuffer,uc_string);
        
        strcatf(uc_stringbuffer," A   ");
        lcd_puts(uc_stringbuffer);
        };
    
    if(ee_currcor!=si_currcor)
        {
        ee_currcor=si_currcor;
        };
    lcd_clear();
    lcd_gotoxy(0,0);
    lcd_putsf(" Werte gespeichert ");
    delay_ms(1000);
    
    // Kalibrierung der Versorgungsspannung
    lcd_clear();
    lcd_gotoxy(0,0);
    lcd_putsf("Spannungs Kalibr.");
    delay_ms(1000);
    uc_tast=read_tast();
    uc_oldtast=uc_tast;
    while (uc_tast!=0x70)           /* A/D Wandler für Stromsensor auslesen und anzeigen */
        {
        uc_tast=read_tast();
        if(uc_tast!=uc_oldtast)
            {
            if(uc_tast==0xD0)
                {
                ui_ufaktor++;
                };
            if(uc_tast==0xB0)
                {
                ui_ufaktor--;
                };
            uc_oldtast=uc_tast;
            };
        li_calc=read_adc(4);
        li_calc=li_calc*ui_ufaktor;
        li_calc=li_calc/512;
        
        lcd_gotoxy(5,1);
        itoa(ui_ufaktor,uc_stringbuffer);
        strcatf(uc_stringbuffer," Korr.   ");
        lcd_puts(uc_stringbuffer);
        
        si_buffer2=li_calc/10;
        lcd_gotoxy(6,2);
        if(si_buffer2<10)
            {
            lcd_putsf(" ");
            lcd_gotoxy(7,2);
            };
        itoa(si_buffer2,uc_string);
        strcpy(uc_stringbuffer,uc_string);
        strcatf(uc_stringbuffer,",");
        si_buffer2=li_calc%10;
        itoa (si_buffer2,uc_string);
        strcat(uc_stringbuffer,uc_string);
        
        strcatf(uc_stringbuffer," V   ");
        lcd_puts(uc_stringbuffer);
        };
    
    if(ee_ufaktor!=ui_ufaktor)
        {
        ee_ufaktor=ui_ufaktor;
        };
    lcd_clear();
    lcd_gotoxy(0,0);
    lcd_putsf(" Werte gespeichert ");
    delay_ms(1000);
    
    // Temperatursensoren 0 Abgleich
    lcd_clear();
    lcd_gotoxy(0,0);
    lcd_putsf("Temperaturs. 0'C");
    delay_ms(1000);
    uc_tast=0xF0;
    uc_oldtast=uc_tast;
    while (uc_tast!=0x70)           /* A/D Wandler für Temperaturanzeigen auslesen */
        {
        si_tempzero[0]=0;
        si_tempzero[1]=0;
        for (uc_i=0;uc_i<10;uc_i++)
            {
            si_buffer1=read_adc(2);
            si_buffer2=read_adc(3);
            si_tempzero[0]=si_tempzero[0]+si_buffer1;
            si_tempzero[1]=si_tempzero[1]+si_buffer2;
            
            };

        si_tempzero[0]=si_tempzero[0]/10;
        si_tempzero[1]=si_tempzero[1]/10;
        lcd_gotoxy(1,1);
        lcd_putsf(" ADC T1: ");
        itoa(si_tempzero[0],uc_stringbuffer);
        lcd_puts(uc_stringbuffer);
        lcd_putsf("    ");
        lcd_gotoxy(1,2);
        lcd_putsf(" ADC T2: ");
        itoa (si_tempzero[1],uc_stringbuffer);
        lcd_puts(uc_stringbuffer);
        lcd_putsf("    ");
        uc_tast=read_tast();
        };
    
    if((ee_tempzero[0]!=si_tempzero[0])||(ee_tempzero[1]!=si_tempzero[1]))
        {
        ee_tempzero[0]=si_tempzero[0];
        ee_tempzero[1]=si_tempzero[1];
        };
    lcd_clear();
    lcd_gotoxy(0,0);
    lcd_putsf(" Werte gespeichert ");
    delay_ms(1000);
    
    // Kalibrierung Temperatursensor 1
    lcd_clear();
    lcd_gotoxy(0,0);
    lcd_putsf("Temp1 Kalibr. 100'C");
    delay_ms(1000);
    uc_tast=read_tast();
    uc_oldtast=uc_tast;
    while (uc_tast!=0x70)           /* A/D Wandler für Stromsensor auslesen und anzeigen */
        {
        uc_tast=read_tast();
        if(uc_tast!=uc_oldtast)
            {
            if(uc_tast==0xD0)
                {
                si_tempfakt[0]--;
                };
            if(uc_tast==0xB0)
                {
                si_tempfakt[0]++;
                };
            uc_oldtast=uc_tast;
            };
        li_calc=read_adc(2);
        li_calc=li_calc-si_tempzero[0];
        li_calc=li_calc*290;
        li_calc=li_calc/si_tempfakt[0];
        
        
        lcd_gotoxy(5,1);
        itoa(si_tempfakt[0],uc_stringbuffer);
        strcatf(uc_stringbuffer," Korr.   ");
        lcd_puts(uc_stringbuffer);
        lcd_gotoxy(5,2);
        if (li_calc<0)
            {
            lcd_putsf("-");
            li_calc=li_calc*(-1);
            }
        else
            {
            lcd_putsf(" ");
            };
        lcd_gotoxy(6,2);
        itoa(li_calc,uc_string);
        strcpy(uc_stringbuffer,uc_string);
                        
        strcatf(uc_stringbuffer," 'C   ");
        lcd_puts(uc_stringbuffer);
        };
    
    if(ee_tempfakt[0]!=si_tempfakt[0])
        {
        ee_tempfakt[0]=si_tempfakt[0];
        };
    lcd_clear();
    lcd_gotoxy(0,0);
    lcd_putsf(" Werte gespeichert ");
    delay_ms(1000);
    
    // Kalibrierung Temperatursensor 2
    lcd_clear();
    lcd_gotoxy(0,0);
    lcd_putsf("Temp2 Kalibr. 100'C");
    delay_ms(1000);
    uc_tast=read_tast();
    uc_oldtast=uc_tast;
    while (uc_tast!=0x70)           /* A/D Wandler für Stromsensor auslesen und anzeigen */
        {
        uc_tast=read_tast();
        if(uc_tast!=uc_oldtast)
            {
            if(uc_tast==0xD0)
                {
                si_tempfakt[1]--;
                };
            if(uc_tast==0xB0)
                {
                si_tempfakt[1]++;
                };
            uc_oldtast=uc_tast;
            };
        li_calc=read_adc(3);
        li_calc=li_calc-si_tempzero[1];
        li_calc=li_calc*290;
        li_calc=li_calc/si_tempfakt[1];
        
        
        lcd_gotoxy(5,1);
        itoa(si_tempfakt[1],uc_stringbuffer);
        strcatf(uc_stringbuffer," Korr.   ");
        lcd_puts(uc_stringbuffer);
        lcd_gotoxy(5,2);
        if (li_calc<0)
            {
            lcd_putsf("-");
            li_calc=li_calc*(-1);
            }
        else
            {
            lcd_putsf(" ");
            };
        lcd_gotoxy(6,2);
        itoa(li_calc,uc_string);
        strcpy(uc_stringbuffer,uc_string);
                        
        strcatf(uc_stringbuffer," 'C   ");
        lcd_puts(uc_stringbuffer);
        };
    
    if(ee_tempfakt[1]!=si_tempfakt[1])
        {
        ee_tempfakt[1]=si_tempfakt[1];
        };
    lcd_clear();
    lcd_gotoxy(0,0);
    lcd_putsf(" Werte gespeichert ");
    delay_ms(1000);
    };            
    
};

// Anzeigen der Einstellparameter
void show_param(unsigned char uc_set)
{
unsigned char uc_buffer[4];
lcd_clear();
lcd_gotoxy(1,0);

//Datentransfer
lcd_putsf("Pc:  ");
if(ub_logging>0)
    {
    lcd_putsf("Ein");
    }
else
    {
    lcd_putsf("Aus");
    };

//Nullabgleich Stromsensor
lcd_gotoxy(11,0);
lcd_putsf("NullA:+");

//Anzeige Logging
lcd_gotoxy(1,1);
lcd_putsf("Log: ");
if(uc_datalog>0)
    {
    lcd_putsf("Ein");
    }
else
    {
    lcd_putsf("Aus");
    };

//Geloggte Daten übertragen
lcd_gotoxy(11,1);
lcd_putsf("Future   ");

//Blattzahl Einstellung
lcd_gotoxy(1,2);
lcd_putsf("Blatt: 1:");
if (uc_highblatt<10){lcd_putsf(" ");};               /* Leerstellen einfügen */
itoa(uc_highblatt,uc_buffer);
lcd_puts(uc_buffer);
lcd_putsf(",");
if (uc_lowblatt<10){lcd_putsf("0");};                /* Leerstellen einfügen */
itoa(uc_lowblatt,uc_buffer);
lcd_puts(uc_buffer);

//Funk Kanaleinstellung
lcd_gotoxy(1,3);
lcd_putsf("Kan: ");
itoa(uc_kanal,uc_buffer);
lcd_puts(uc_buffer);

//Start Menüeinstellung
lcd_gotoxy(11,3);
lcd_putsf("StartM:");
itoa(uc_startmenu,uc_buffer);
lcd_puts(uc_buffer);

switch (uc_set)
    {
    case 0:
    lcd_gotoxy(0,0);
    break;
    case 1:
    lcd_gotoxy(10,0);
    break;
    case 2:
    lcd_gotoxy(0,1);
    break;
    case 3:
    lcd_gotoxy(10,1);
    break;
    case 4:
    lcd_gotoxy(9,2);
    break;
    case 5:
    lcd_gotoxy(12,2);
    break;
    case 6:
    lcd_gotoxy(13,2);
    break;
    case 7:
    lcd_gotoxy(0,3);
    break;
    case 8:
    lcd_gotoxy(10,3);
    break;
    }; 
lcd_putsf(">");
};

void set_param (void)
{
unsigned char uc_set=0;
unsigned char uc_i=0;
signed int si_buffer1;
signed int si_buffer2;
while (uc_tast!=0xE0)
    {
    uc_tast=read_tast();
    if (uc_tast!=uc_oldtast)
        {
        uc_oldtast=uc_tast;
        if (uc_tast==0xD0)             /* Die Plus Taste wurde gedrückt */
            {
            switch (uc_set)
                {
                case 0:
                ub_logging=1;          /* Der Marker für die serielle Schnittstelle wurde gesetzt */
                ui_time=0;
                break;
                
                case 1:
                si_currlnull=0;                           /* Strom Korrekturwerte auf 0 setzen */
                si_currnull=0;
                for (uc_i=0;uc_i<10;uc_i++)
                    {
                    si_buffer1=read_adc(0);                   /* Strom Messwerte auslesen */
                    si_buffer2=read_adc(1);
                    si_currlnull=si_currlnull+si_buffer1;
                    si_currnull=si_currnull+si_buffer2;
                    };

                si_currlnull=si_currlnull/10;                 /* Im RAM ablegen */
                si_currnull=si_currnull/10;
                if(si_currlnull!=ee_currlnull){ee_currlnull=si_currlnull;}; /* EEPROM beschreiben */
                if(si_currnull!=ee_currnull){ee_currnull=si_currnull;};     /* EEPROM beschreiben */
                break;
                
                case 2:
                uc_datalog=1;
                logging=1;
                break;
                    
                case 3:
                //Transfer der Log Daten
                break;
                
                case 4:
                uc_highblatt++;
                if(uc_highblatt>20)
                {
                uc_highblatt=0;
                uc_lowblatt=1;
                };
                break;
                
                case 5:
                uc_lowblatt+=10;
                if(uc_lowblatt>99){uc_lowblatt=0;};
                break;
                
                case 6:
                uc_lowblatt++;
                if(uc_lowblatt>99){uc_lowblatt=0;};
                break;
                
                case 7:
                uc_kanal++;
                if(uc_kanal>22){uc_kanal=0;};
                break;
                
                case 8:
                uc_startmenu++;
                if(uc_startmenu>4){uc_startmenu=0;};
                break;
                }; 

            };
            
            if (uc_tast==0xB0)             /* Die Minus Taste wurde gedrückt */
            {
            switch (uc_set)
                {
                case 0:
                ub_logging=0;          /* Der Marker für die serielle Schnittstelle wurde gelöscht */
                ui_time=0;
                break;
                
                case 2:
                uc_datalog=0;
                logging=0;
                break;
                    
                case 4:
                uc_highblatt--;
                if(uc_highblatt==0){uc_lowblatt=99;};
                if(uc_highblatt+1==0)
                {
                uc_highblatt=20;
                uc_lowblatt=0;
                };
                break;
                
                case 5:
                uc_lowblatt-=10;
                if(uc_lowblatt>127){uc_lowblatt=99;};     /* negative Werte sind >127*/
                break;
                
                case 6:
                uc_lowblatt--;
                if(uc_lowblatt>127){uc_lowblatt=99;};     /* negative Werte sind >127*/
                break;
                
                case 7:
                uc_kanal--;
                if(uc_kanal+1==0){uc_kanal=22;};
                break;
                
                case 8:
                uc_startmenu--;
                if(uc_startmenu+1==0){uc_startmenu=4;};
                break;
                }; 

            };
            if (uc_tast==0x70)             /* Die Enter Taste wurde gedrückt */
            {
            switch (uc_set)
                {
                case 0:
                uc_set++;          /* Nächstes Menue auswählen */
                break;
                
                case 1:
                uc_set++;
                break;
                
                case 2:
                uc_set++;
                break;
                    
                case 3:
                uc_set++;
                break;
                
                case 4:
                case 5:
                case 6:
                uc_set++;
                ui_blatt=uc_highblatt;
                ui_blatt=ui_blatt*100+uc_lowblatt;
                if(ui_blatt!=ee_blatt){ee_blatt=ui_blatt;};    /* Blattzahl im EEPROM speichern */
                break;
                
                case 7:
                uc_set++;
                if(uc_kanal!=ee_kanal){ee_kanal=uc_kanal;};    /* Empfangskanal im EEPROM speichern */
                break;
                
                case 8:
                uc_set=0;
                if(uc_startmenu!=ee_startmenu){ee_startmenu=uc_startmenu;};  /* Startmenueinstellung im EEPROM speichern */
                break;
                }; 
            };
        show_param(uc_set);
        };
    };
};                                

//Messwerte berechnen 
void calc_value (void)
{
    volatile unsigned char uc_i=0;
    ul_maxvoltage=0;
    uc_cells=0;                        /* Zellenanzahl auf 0 setzen */
    /* Spannungswerte übertragen */
    for(uc_i=0;uc_i<6;uc_i++)                           
    {
        ul_voltage[uc_i]=ui_7795[uc_i];
        ul_diffvoltage[uc_i]=ui_7795[uc_i];
        ul_oldvoltage[uc_i]=ui_old7795[uc_i];
    }
       
    /* Differenzwerte bilden */
    for(uc_i=6;uc_i>0;uc_i--)                          
    {
        if(ul_diffvoltage[uc_i-1]>ul_diffvoltage[uc_i])
        {
            ul_diffvoltage[uc_i]=0;
        }
        else
        {
            ul_diffvoltage[uc_i]=ul_diffvoltage[uc_i]-ul_diffvoltage[uc_i-1];
        }
        
        if(ul_oldvoltage[uc_i-1]>ul_oldvoltage[uc_i])
        {
            ul_oldvoltage[uc_i]=0;
        }
        else
        {
            ul_oldvoltage[uc_i]=ul_oldvoltage[uc_i]-ul_oldvoltage[uc_i-1];
        }
    }
        
    /* Spannungen aus A/D Wert berechnen */
    for(uc_i=0;uc_i<6;uc_i++)                           
    {
        #asm("CLI");            //Interrupts zur Berechnung sperren - sonst Anzeigefehler
        ul_diffvoltage[uc_i]=(ul_diffvoltage[uc_i]* 27175)/32768;
        ul_voltage[uc_i]=(ul_voltage[uc_i]*27175)/32768;
        ul_oldvoltage[uc_i]=(ul_oldvoltage[uc_i]*27175)/32768;
        if(ul_diffvoltage[uc_i]>ul_maxvoltage)
        {
            ul_maxvoltage = ul_diffvoltage[uc_i];
            uc_maxcell=uc_i;
        }
        if(ul_diffvoltage[uc_i]>500)                        /* Zellenanzahl bestimmen */
        {
            uc_cells=uc_i;
        }
        #asm("SEI");
    }
    /* Temperaturen berechnen */
    li_temp1=read_adc(2);
    if(li_temp1==1023)                                  /* Offenen Eingänge abfangen */
        {
        li_temp1=0;
        }
    else
        {
        #asm ("CLI");
        li_temp1=((li_temp1-si_tempzero[0])*290)/si_tempfakt[0];
        #asm ("SEI");
        };
    
    li_temp2=read_adc(3);
    if(li_temp2==1023)                                   /* Offenen Eingänge abfangen */
        {
        li_temp2=0;
        }
    else
        {
        #asm ("CLI");
        li_temp2=((li_temp2-si_tempzero[1])*290)/si_tempfakt[1];
        #asm ("SEI");
        }


    //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=1500000000/(li_drmittel*ui_blatt);  /* Periodendauermessung */
            }
        else
            {
            li_drehzahl=ui_drpulses;                   /* Pulszählung in Torzeit ( 1Sekunde )*/
            li_drehzahl=(li_drehzahl*6000)/ui_blatt;
            }
        }
ui_drpulses=0;   /* Pulszählung zurücksetzen */
li_drmittel=0;   /* Mittelwertbildner zurücksetzen */
uc_stellen=0;    /* Stützstellenzähler zurücksetzen */
}

/* Strom H berechnen */
signed long int calc_curr (signed int si_adccurr)
{
signed long int li_currhelp, li_adccurr;
li_adccurr=si_adccurr;
li_currhelp=((li_adccurr-si_currnull)*si_currcor)/16;       /* Durch /8 bei ACS750-100 /16 bei ACS750-50 */
return (li_currhelp);
}

/* Strom L berechnen */
signed long int calc_currl (signed int si_adccurr)
{
signed long int li_currhelp, li_adccurr;
li_adccurr=si_adccurr;
li_currhelp=((li_adccurr-si_currlnull)*si_currlcor)/160;    /* Durch /80 bei ACS750-100 /160 bei ACS750-50 */
return (li_currhelp);
}

/* Telemetriedaten in Puffer schreiben */
void calc_telemetrie (void)
{
unsigned char uc_i=0;                            /* Schleifenvariable */
unsigned char uc_buffcount=0;                   /* Zähler für Puffer */
unsigned char uc_semicount=0;                   /* Zähler für semikolons */
unsigned char uc_buffer[10];                    /* Zwischenpuffer */
while(uc_i<=strlen(uc_receivedata))
    {
    //Timer
    if(uc_semicount==2)
        {
        if(uc_receivedata[uc_i]!=';')
            {
            uc_buffer[uc_buffcount]=uc_receivedata[uc_i];
            uc_buffcount++;
            }
        else
            {
            uc_buffer[uc_buffcount]=0;
            ui_teletimer=atoi(uc_buffer);
            uc_buffcount=0;
            };
                
        };
    //Volt 1    
    if(uc_semicount==3)
        {
        if(uc_receivedata[uc_i]!=';')
            {
            uc_buffer[uc_buffcount]=uc_receivedata[uc_i];
            uc_buffcount++;
            }
        else
            {
            uc_buffer[uc_buffcount]=0;
            ui_televolt1=atoi(uc_buffer);
            uc_buffcount=0;
            };
                
        };
    //Volt min    
    if(uc_semicount==4)
        {
        if(uc_receivedata[uc_i]!=';')
            {
            uc_buffer[uc_buffcount]=uc_receivedata[uc_i];
            uc_buffcount++;
            }
        else
            {
            uc_buffer[uc_buffcount]=0;
            ui_televoltmin=atoi(uc_buffer);
            uc_buffcount=0;
            };
                
        };
    //Volt 2
    if(uc_semicount==5)
        {
        if(uc_receivedata[uc_i]!=';')
            {
            uc_buffer[uc_buffcount]=uc_receivedata[uc_i];
            uc_buffcount++;
            }
        else
            {
            uc_buffer[uc_buffcount]=0;
            ui_televolt2=atoi(uc_buffer);
            uc_buffcount=0;
            };
                
        };
    // Temp 1
    if(uc_semicount==10)
        {
        if(uc_receivedata[uc_i]!=';')
            {
            uc_buffer[uc_buffcount]=uc_receivedata[uc_i];
            uc_buffcount++;
            }
        else
            {
            uc_buffer[uc_buffcount]=0;
            si_teletemp1=atoi(uc_buffer);
            uc_buffcount=0;
            };
                
        };
     // Temp2
     if(uc_semicount==11)
        {
        if(uc_receivedata[uc_i]!=';')
            {
            uc_buffer[uc_buffcount]=uc_receivedata[uc_i];
            uc_buffcount++;
            }
        else
            {
            uc_buffer[uc_buffcount]=0;
            si_teletemp2=atoi(uc_buffer);
            uc_buffcount=0;
            };
                
        };
     // Drehzahl
     if(uc_semicount==12)
        {
        if(uc_receivedata[uc_i]!=';')
            {
            uc_buffer[uc_buffcount]=uc_receivedata[uc_i];
            uc_buffcount++;
            }
        else
            {
            uc_buffer[uc_buffcount]=0;
            li_teledrehzahl=atol(uc_buffer);
            li_teledrehzahl=(li_teledrehzahl*100)/ui_blatt;
            uc_buffcount=0;
            };
                
        };
       
    if ( uc_receivedata[uc_i]==';')
        {
        uc_semicount++;
        };
    
    
    
    uc_i++;
    };
uc_alive++;
if(uc_alive>2){uc_alive=0;};                  /* Lebenszeichenanzeige */
};

/* Messwerte auf der seriellen Schnittstelle übertragen */
void trans_value (void)
{
volatile unsigned char uc_stringbuffer[10];
volatile unsigned char uc_stringlengh;
volatile unsigned char uc_i;

uc_sendbuffer[0]='$';
uc_sendbuffer[1]='1';
uc_sendbuffer[2]=';';
uc_sendbuffer[3]='1';
uc_sendbuffer[4]=';';
uc_sendbuffer[5]=0x00;      /*Stringende definieren */

#asm("CLI");                //Interrupts sperren
itoa (ui_time,uc_stringbuffer);
#asm("SEI");                //Interrupts freigeben
strcat (uc_sendbuffer,uc_stringbuffer);
strcatf (uc_sendbuffer,";");

for (uc_i=0;uc_i<6;uc_i++)
{
    ltoa (ul_diffvoltage[uc_i],uc_stringbuffer);
    strcat (uc_sendbuffer,uc_stringbuffer);
    strcatf (uc_sendbuffer,";");
}
ltoa(li_curr,uc_stringbuffer);                   /* Strommesswerte anhängen */
strcat (uc_sendbuffer,uc_stringbuffer);
strcatf (uc_sendbuffer,";");

//* Temperaturmessung 1                          /* Temperaturmesswerte Sensor 1 anhängen */
ltoa (li_temp1,uc_stringbuffer);
strcat (uc_sendbuffer,uc_stringbuffer);
strcatf (uc_sendbuffer,";");

// Temperaturmessung 2                          /* Temperaturmesswerte Sensor 2 anhängen */
ltoa (li_temp2,uc_stringbuffer);
strcat (uc_sendbuffer,uc_stringbuffer);
strcatf (uc_sendbuffer,";");

// Drehzahl
ltoa (li_drehzahl,uc_stringbuffer);              /* Drehzahlmesswerte anhängen */
strcat (uc_sendbuffer,uc_stringbuffer);
strcatf (uc_sendbuffer,";");

tchecksum(); /* Checksumme zum senden ermitteln und anfügen */

// Stringendebytes anfügen
uc_stringlengh=strlen(uc_sendbuffer);
uc_sendbuffer[uc_stringlengh]=13; /* Carriage Return */
uc_sendbuffer[uc_stringlengh+1]=10; /* Line Feed */
uc_sendbuffer[uc_stringlengh+2]=0; /* Stringende */

for (uc_i=0;uc_i<strlen(uc_sendbuffer);uc_i++)
    {
    putchar(uc_sendbuffer[uc_i]);
    }
uc_sendbuffer[0]='$';
uc_sendbuffer[1]='2';
uc_sendbuffer[2]=';';
uc_sendbuffer[3]='1';
uc_sendbuffer[4]=';';
uc_sendbuffer[5]=0x00;      /*Stringende definieren */

#asm("CLI");                //Interrupts sperren
itoa (ui_time,uc_stringbuffer);
#asm("SEI");                //Interrupts freigeben
strcat (uc_sendbuffer,uc_stringbuffer);
strcatf (uc_sendbuffer,";");

for (uc_i=0;uc_i<6;uc_i++)
{
    ltoa (ul_voltage[uc_i],uc_stringbuffer);
    strcat (uc_sendbuffer,uc_stringbuffer);
    strcatf (uc_sendbuffer,";");
}
ltoa(li_curr,uc_stringbuffer);                   /* Strommesswerte anhängen */
strcat (uc_sendbuffer,uc_stringbuffer);
strcatf (uc_sendbuffer,";");

//* Temperaturmessung 1                          /* Temperaturmesswerte Sensor 1 anhängen */
ltoa (li_temp1,uc_stringbuffer);
strcat (uc_sendbuffer,uc_stringbuffer);
strcatf (uc_sendbuffer,";");

// Temperaturmessung 2                          /* Temperaturmesswerte Sensor 2 anhängen */
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,";");

tchecksum(); /* Checksumme zum senden ermitteln und anfügen */

// Stringendebytes anfügen
uc_stringlengh=strlen(uc_sendbuffer);
uc_sendbuffer[uc_stringlengh]=13; /* Carriage Return */
uc_sendbuffer[uc_stringlengh+1]=10; /* Line Feed */
uc_sendbuffer[uc_stringlengh+2]=0; /* Stringende */

for (uc_i=0;uc_i<strlen(uc_sendbuffer);uc_i++)
    {
    putchar(uc_sendbuffer[uc_i]);
    }
}


/* Werte auf dem Display anzeigen */
void write_display (void)
{
    volatile signed long int ul_calcvoltage=0,ul_maxvoltage=0,ul_calccurr=0;
    volatile unsigned char uc_linebuff[8][11];
    volatile unsigned char uc_buffer[7];
    volatile unsigned char uc_i;
    // Linienpuffer leeren
    for(uc_i=0;uc_i<8;uc_i++)
        {
        uc_linebuff[uc_i][0]=0;
        };
            
    if(uc_dispmode==0)
    {
        /* Differenz Spannungswerte Zelle X anzeigen */
        for(uc_i=0;uc_i<6;uc_i++)
        {
        if(uc_cells>=uc_i)
        {
            uc_linebuff[uc_i][0]=uc_i+0x31;                 /* Aktuellen Kanal einfügen */
            uc_linebuff[uc_i][1]=0;    
            if (ul_diffvoltage[uc_i]>(ul_oldvoltage[uc_i]+5)) /* Spannung wurde größer */
            {
                if(uc_maxcell==uc_i)
                {
                uc_linebuff[uc_i][1]=2;
                }
                else
                {
                uc_linebuff[uc_i][1]=1;
                }
            }
            if (ul_diffvoltage[uc_i]<(ul_oldvoltage[uc_i]-5)) /* Spannung wurde kleiner */
            {
                if(uc_maxcell==uc_i)
                {
                uc_linebuff[uc_i][1]=4;
                }
                else
                {
                uc_linebuff[uc_i][1]=3;
                }
            }
            if (ul_diffvoltage[uc_i]>=(ul_oldvoltage[uc_i]-5)&& ul_diffvoltage[uc_i]<=(ul_oldvoltage[uc_i]+5)) /* Spannung wurde kleiner */
            {
                if(uc_maxcell==uc_i)
                {
                uc_linebuff[uc_i][1]=5;
                }
                else
                {
                uc_linebuff[uc_i][1]=42;
                }
            }
            uc_linebuff[uc_i][2]=' ';
            uc_linebuff[uc_i][3]=0;
            ul_calcvoltage=ul_diffvoltage[uc_i]/1000;
            if(ul_calcvoltage<10)
            {
                uc_linebuff[uc_i][3]=' ';
                uc_linebuff[uc_i][4]=0;
            }
            ltoa(ul_calcvoltage,uc_buffer);
            strcat(uc_linebuff[uc_i],uc_buffer);
            strcatf(uc_linebuff[uc_i],",");
            ul_calcvoltage=ul_diffvoltage[uc_i]%1000;
            if (ul_calcvoltage < 100)
            {
                strcatf(uc_linebuff[uc_i],"0");
            }
            if (ul_calcvoltage < 10)
            {
                strcatf(uc_linebuff[uc_i],"0");
            }
            ltoa(ul_calcvoltage,uc_buffer);
            strcat(uc_linebuff[uc_i],uc_buffer);
        }
        else
        {
            uc_linebuff[uc_i][0]=uc_i+0x31;                 /* Aktuellen Kanal einfügen */
            uc_linebuff[uc_i][1]=0;
            strcatf(uc_linebuff[uc_i]," no Cell");
        }
    }
    strcpyf(uc_linebuff[6],"M");
    itoa(uc_dispmode,uc_buffer);
    strcat(uc_linebuff[6],uc_buffer);
    ul_voltage[6]=read_adc(4);
    ul_voltage[6]=(ul_voltage[6]*ui_ufaktor)/512;
    ul_calcvoltage=ul_voltage[6]/10;
    strcatf(uc_linebuff[6]," ");
    if(ul_calcvoltage<10){strcatf(uc_linebuff[6]," ");};
    ltoa(ul_calcvoltage,uc_buffer);
    strcat(uc_linebuff[6],uc_buffer);
    strcatf(uc_linebuff[6],",");
    ul_calcvoltage=ul_voltage[6]%10;
    ltoa(ul_calcvoltage,uc_buffer);
    strcat(uc_linebuff[6],uc_buffer);
    strcatf(uc_linebuff[6],"V");
    
    if (li_curr<0)                              /* Negative Werte abfangen */
    {
        if(li_curr>-10)
            {
            strcpyf(uc_linebuff[7]," ");
            };
        strcatf(uc_linebuff[7],"-");
        ul_calccurr=(li_curr*-1)/100;
        ltoa(ul_calccurr,uc_buffer);
        strcat(uc_linebuff[7],uc_buffer);
        strcatf (uc_linebuff[7],",");
        ul_calccurr=(li_curr*-1)%100;
        if (ul_calccurr<10){strcatf (uc_linebuff[7],"0");}    /* Bei Werten <10 eine 0 anfügen */
        ltoa(ul_calccurr,uc_buffer);
        strcat(uc_linebuff[7],uc_buffer);
    }
    else
    {
        if(li_curr<10)
            {
            strcpyf(uc_linebuff[7]," ");
            };
        
        strcatf(uc_linebuff[7]," ");
        ul_calccurr=li_curr/100;
        ltoa(ul_calccurr,uc_buffer);
        strcat(uc_linebuff[7],uc_buffer);
        strcatf (uc_linebuff[7],",");
        ul_calccurr=li_curr%100;
        if (ul_calccurr<10){strcatf (uc_linebuff[7],"0");}    /* Bei Werten <10 eine 0 anfügen */
        ltoa(ul_calccurr,uc_buffer);
        strcat(uc_linebuff[7],uc_buffer);
    }
    strcatf(uc_linebuff[7],"A");
    }

    
    if(uc_dispmode==1)
    {
        /* Absolute Spannungswerte Zelle X anzeigen */
        for(uc_i=0;uc_i<6;uc_i++)
        {
          /*  if(uc_cells>=uc_i)
            { */
                uc_linebuff[uc_i][0]=uc_i+0x31;                 /* Aktuellen Kanal einfügen */
                uc_linebuff[uc_i][1]=0;    
                if (ul_diffvoltage[uc_i]>(ul_oldvoltage[uc_i]+5)) /* Spannung wurde größer */
                {
                    if(uc_maxcell==uc_i)
                    {
                        uc_linebuff[uc_i][1]=2;
                    }
                    else
                    {
                        uc_linebuff[uc_i][1]=1;
                    }
                }
                if (ul_diffvoltage[uc_i]<(ul_oldvoltage[uc_i]-5)) /* Spannung wurde kleiner */
                {
                    if(uc_maxcell==uc_i)
                    {
                    uc_linebuff[uc_i][1]=4;
                    }
                    else
                    {
                    uc_linebuff[uc_i][1]=3;
                    }
                }
                if (ul_diffvoltage[uc_i]>=(ul_oldvoltage[uc_i]-5)&& ul_diffvoltage[uc_i]<=(ul_oldvoltage[uc_i]+5)) /* Spannung wurde kleiner */
                {
                    if(uc_maxcell==uc_i)
                    {
                        uc_linebuff[uc_i][1]=5;
                    }
                    else
                    {
                        uc_linebuff[uc_i][1]=42;
                    }
                }
            uc_linebuff[uc_i][2]=' ';
            uc_linebuff[uc_i][3]=0;
            ul_calcvoltage=ul_voltage[uc_i]/1000;
            if(ul_calcvoltage<10)
            {
                uc_linebuff[uc_i][3]=' ';
                uc_linebuff[uc_i][4]=0;
            }
            ltoa(ul_calcvoltage,uc_buffer);
            strcat(uc_linebuff[uc_i],uc_buffer);
            strcatf(uc_linebuff[uc_i],",");
            ul_calcvoltage=ul_voltage[uc_i]%1000;
            if (ul_calcvoltage < 100)
            {
                strcatf(uc_linebuff[uc_i],"0");
            }
            if (ul_calcvoltage < 10)
            {
                strcatf(uc_linebuff[uc_i],"0");
            }
            ltoa(ul_calcvoltage,uc_buffer);
            strcat(uc_linebuff[uc_i],uc_buffer);
            
      /*}
        else
        {
            uc_linebuff[uc_i][0]=uc_i+0x31;*/                 /* Aktuellen Kanal einfügen */
        /*    uc_linebuff[uc_i][1]=0;
            strcatf(uc_linebuff[uc_i]," no Cell");
        } */
    }
    strcpyf(uc_linebuff[6],"M");
    itoa(uc_dispmode,uc_buffer);
    strcat(uc_linebuff[6],uc_buffer);
    ul_voltage[6]=read_adc(4);
    ul_voltage[6]=(ul_voltage[6]*ui_ufaktor)/512;
    ul_calcvoltage=ul_voltage[6]/10;
    strcatf(uc_linebuff[6]," ");
    if(ul_calcvoltage<10){strcatf(uc_linebuff[6]," ");};
    ltoa(ul_calcvoltage,uc_buffer);
    strcat(uc_linebuff[6],uc_buffer);
    strcatf(uc_linebuff[6],",");
    ul_calcvoltage=ul_voltage[6]%10;
    ltoa(ul_calcvoltage,uc_buffer);
    strcat(uc_linebuff[6],uc_buffer);
    strcatf(uc_linebuff[6],"V");
    
    if (li_curr<0)                              /* Negative Werte abfangen */
    {
        if(li_curr>-10)
            {
            strcpyf(uc_linebuff[7]," ");
            };
        strcatf(uc_linebuff[7],"-");
        ul_calccurr=(li_curr*-1)/100;
        ltoa(ul_calccurr,uc_buffer);
        strcat(uc_linebuff[7],uc_buffer);
        strcatf (uc_linebuff[7],",");
        ul_calccurr=(li_curr*-1)%100;
        if (ul_calccurr<10){strcatf (uc_linebuff[7],"0");}    /* Bei Werten <10 eine 0 anfügen */
        ltoa(ul_calccurr,uc_buffer);
        strcat(uc_linebuff[7],uc_buffer);
    }
    else
    {
        if(li_curr<10)
            {
            strcpyf(uc_linebuff[7]," ");
            };
        
        strcatf(uc_linebuff[7]," ");
        ul_calccurr=li_curr/100;
        ltoa(ul_calccurr,uc_buffer);
        strcat(uc_linebuff[7],uc_buffer);
        strcatf (uc_linebuff[7],",");
        ul_calccurr=li_curr%100;
        if (ul_calccurr<10){strcatf (uc_linebuff[7],"0");}    /* Bei Werten <10 eine 0 anfügen */
        ltoa(ul_calccurr,uc_buffer);
        strcat(uc_linebuff[7],uc_buffer);
    }
    strcatf(uc_linebuff[7],"A");
    }
    
    
    // Displaymode 2 Maxiamle Werte - Antriebsvermessung
    if(uc_dispmode==2)
    {
        /* Maximale Spannung + Werte anzeigen */
        for(uc_i=0;uc_i<6;uc_i++)
        {
          if(ul_voltage[uc_i]>ul_maxvoltage)
            {
            ul_maxvoltage=ul_voltage[uc_i];
            uc_cells=uc_i;
            };
        };
        uc_linebuff[0][0]=uc_cells+0x31;                 /* Aktuellen Kanal einfügen */
        uc_linebuff[0][1]='C';
        uc_linebuff[0][2]='e';
        uc_linebuff[0][3]='l';
        uc_linebuff[0][4]='l';
        uc_linebuff[0][5]=0;    
        ul_calcvoltage=ul_maxvoltage/1000;
        ltoa(ul_calcvoltage,uc_buffer);
        strcpyf(uc_linebuff[1],"  ");
        if(ul_calcvoltage<10)
            {
                strcatf(uc_linebuff[1]," ");
            }
        strcat(uc_linebuff[1],uc_buffer);
        strcatf(uc_linebuff[1],",");
        ul_calcvoltage=ul_maxvoltage%1000;
        ltoa(ul_calcvoltage,uc_buffer);
        if (ul_calcvoltage < 100)
            {
                strcatf(uc_linebuff[1],"0");
            }
        if (ul_calcvoltage < 10)
            {
                strcatf(uc_linebuff[1],"0");
            }
        
        strcat(uc_linebuff[1],uc_buffer);
        strcatf(uc_linebuff[1],"V");
        // Strom berechnen
        if (li_curr<0)                              /* Negative Werte abfangen */
            {
            strcpyf(uc_linebuff[2],"-");
            ul_calccurr=(li_curr*-1)/100;
            if(ul_calccurr<10){strcatf(uc_linebuff[2]," ");};
            ltoa(ul_calccurr,uc_buffer);
            strcat(uc_linebuff[2],uc_buffer);
            strcatf (uc_linebuff[2],",");
            ul_calccurr=(li_curr*-1)%100;
            if (ul_calccurr<10){strcatf (uc_linebuff[2],"0");}    /* Bei Werten <10 eine 0 anfügen */
            ltoa(ul_calccurr,uc_buffer);
            strcat(uc_linebuff[2],uc_buffer);
            }
        else
            {
            strcpyf(uc_linebuff[2]," ");
            ul_calccurr=li_curr/100;
            if(ul_calccurr<10){strcatf(uc_linebuff[2]," ");};
            ltoa(ul_calccurr,uc_buffer);
            strcat(uc_linebuff[2],uc_buffer);
            strcatf (uc_linebuff[2],",");
            ul_calccurr=li_curr%100;
            if (ul_calccurr<10){strcatf (uc_linebuff[2],"0");}    /* Bei Werten <10 eine 0 anfügen */
            ltoa(ul_calccurr,uc_buffer);
            strcat(uc_linebuff[2],uc_buffer);
            }
        strcatf(uc_linebuff[2],"A");
        
        // Drehzahl anzeigen
        strcpyf(uc_linebuff[3]," ");
        if (li_drehzahl<100000){strcatf(uc_linebuff[3]," ");};
        if (li_drehzahl<10000){strcatf(uc_linebuff[3]," ");};
        if (li_drehzahl<1000){strcatf(uc_linebuff[3]," ");};
        if (li_drehzahl<100){strcatf(uc_linebuff[3]," ");};
        if (li_drehzahl<10){strcatf(uc_linebuff[3]," ");};
        ltoa (li_drehzahl,uc_buffer);
        strcat(uc_linebuff[3],uc_buffer);
        strcatf(uc_linebuff[3]," U");
    
        // Temperatur anzeigen Sensor 1
        strcpyf(uc_linebuff[4],"T1=");
        if(li_temp1>=0)
            {
            strcatf(uc_linebuff[4]," ");
            };
        if(li_temp1<100&&li_temp1>-100)
            {
            strcatf(uc_linebuff[4]," ");
            };
        if(li_temp1<10&&li_temp1>-10)
            {
            strcatf(uc_linebuff[4]," ");
            }
        ltoa(li_temp1,uc_buffer);
        strcat(uc_linebuff[4],uc_buffer);
        strcatf(uc_linebuff[4],"ßC");
        
        // Temperatur anzeigen Sensor 2
        strcpyf(uc_linebuff[5],"T2=");
        if(li_temp2>=0)
            {
            strcatf(uc_linebuff[5]," ");
            };
        if(li_temp2<100&&li_temp2>-100)
            {
            strcatf(uc_linebuff[5]," ");
            };
        if(li_temp2<10&&li_temp2>-10)
            {
            strcatf(uc_linebuff[5]," ");
            }
        ltoa(li_temp2,uc_buffer);
        strcat(uc_linebuff[5],uc_buffer);
        strcatf(uc_linebuff[5],"ßC");
        
        // Zellenspannung des internen Akkus anzeigen
        ul_voltage[6]=read_adc(4);
        ul_voltage[6]=(ul_voltage[6]*ui_ufaktor)/512;
        if(ul_voltage[6]<100)
            {
            strcpyf(uc_linebuff[6]," ");
            };
        strcpyf(uc_linebuff[6],"M");
        itoa(uc_dispmode,uc_buffer);
        strcat(uc_linebuff[6],uc_buffer);
        ul_voltage[6]=read_adc(4);
        ul_voltage[6]=(ul_voltage[6]*ui_ufaktor)/512;
        ul_calcvoltage=ul_voltage[6]/10;
        strcatf(uc_linebuff[6]," ");
        if(ul_calcvoltage<10){strcatf(uc_linebuff[6]," ");};
        ltoa(ul_calcvoltage,uc_buffer);
        strcat(uc_linebuff[6],uc_buffer);
        strcatf(uc_linebuff[6],",");
        ul_calcvoltage=ul_voltage[6]%10;
        ltoa(ul_calcvoltage,uc_buffer);
        strcat(uc_linebuff[6],uc_buffer);
        strcatf(uc_linebuff[6],"V");
        
        // Timerwert anzeigen
        strcpyf(uc_linebuff[7]," Ti:");
        if (ui_time<10000)
            {
            strcatf(uc_linebuff[7]," ");
            };
        if (ui_time<1000)
            {
            strcatf(uc_linebuff[7]," ");
            };
        if (ui_time<100)
            {
            strcatf(uc_linebuff[7]," ");
            };
        if (ui_time<10)
            {
            strcatf(uc_linebuff[7]," ");
            };
        itoa(ui_time,uc_buffer);
        strcat(uc_linebuff[7],uc_buffer);
    };       
    
    // Telemetriewerte anzeigen
    if(uc_dispmode==3)
        {
        /* Zellenspannung Volt 1 anzeigen */
        strcpyf(uc_linebuff[0],"V1 ");
        ul_calcvoltage=ui_televolt1/100;
        ltoa(ul_calcvoltage,uc_buffer);
        if(ul_calcvoltage<10)
            {
                strcatf(uc_linebuff[0]," ");
            }
        strcat(uc_linebuff[0],uc_buffer);
        strcatf(uc_linebuff[0],",");
        ul_calcvoltage=ui_televolt1%100;
        ltoa(ul_calcvoltage,uc_buffer);
        if (ul_calcvoltage < 10)
            {
                strcatf(uc_linebuff[0],"0");
            }
        strcat(uc_linebuff[0],uc_buffer);
        strcatf(uc_linebuff[0],"V");
        
        /* Zellenspannung Volt min anzeigen */
        strcpyf(uc_linebuff[1],"Vm ");
        ul_calcvoltage=ui_televoltmin/100;
        ltoa(ul_calcvoltage,uc_buffer);
        if(ul_calcvoltage<10)
            {
                strcatf(uc_linebuff[1]," ");
            }
        strcat(uc_linebuff[1],uc_buffer);
        strcatf(uc_linebuff[1],",");
        ul_calcvoltage=ui_televoltmin%100;
        ltoa(ul_calcvoltage,uc_buffer);
        if (ul_calcvoltage < 10)
            {
                strcatf(uc_linebuff[1],"0");
            }
        strcat(uc_linebuff[1],uc_buffer);
        strcatf(uc_linebuff[1],"V");
        
        /* Zellenspannung Volt 2 anzeigen */
        strcpyf(uc_linebuff[2],"V2 ");
        ul_calcvoltage=ui_televolt2/100;
        ltoa(ul_calcvoltage,uc_buffer);
        if(ul_calcvoltage<10)
            {
                strcatf(uc_linebuff[2]," ");
            }
        strcat(uc_linebuff[2],uc_buffer);
        strcatf(uc_linebuff[2],",");
        ul_calcvoltage=ui_televolt2%100;
        ltoa(ul_calcvoltage,uc_buffer);
        if (ul_calcvoltage < 10)
            {
                strcatf(uc_linebuff[2],"0");
            }
        strcat(uc_linebuff[2],uc_buffer);
        strcatf(uc_linebuff[2],"V");
        
        // Drehzahl anzeigen
        strcpyf(uc_linebuff[3]," ");
        if (li_teledrehzahl<100000){strcatf(uc_linebuff[3]," ");};
        if (li_teledrehzahl<10000){strcatf(uc_linebuff[3]," ");};
        if (li_teledrehzahl<1000){strcatf(uc_linebuff[3]," ");};
        if (li_teledrehzahl<100){strcatf(uc_linebuff[3]," ");};
        if (li_teledrehzahl<10){strcatf(uc_linebuff[3]," ");};
        ltoa (li_teledrehzahl,uc_buffer);
        strcat(uc_linebuff[3],uc_buffer);
        strcatf(uc_linebuff[3]," U");
    
        // Temperatur anzeigen Sensor 1
        strcpyf(uc_linebuff[4],"T1=");
        if(si_teletemp1>=0)
            {
            strcatf(uc_linebuff[4]," ");
            };
        if(si_teletemp1<100&&si_teletemp1>-100)
            {
            strcatf(uc_linebuff[4]," ");
            };
        if(si_teletemp1<10&&si_teletemp1>-10)
            {
            strcatf(uc_linebuff[4]," ");
            }
        ltoa(si_teletemp1,uc_buffer);
        strcat(uc_linebuff[4],uc_buffer);
        strcatf(uc_linebuff[4],"ßC");
        
        // Temperatur anzeigen Sensor 2
        strcpyf(uc_linebuff[5],"T2=");
        if(si_teletemp2>=0)
            {
            strcatf(uc_linebuff[5]," ");
            };
        if(si_teletemp2<100&&si_teletemp2>-100)
            {
            strcatf(uc_linebuff[5]," ");
            };
        if(si_teletemp2<10&&si_teletemp2>-10)
            {
            strcatf(uc_linebuff[5]," ");
            }
        ltoa(si_teletemp2,uc_buffer);
        strcat(uc_linebuff[5],uc_buffer);
        strcatf(uc_linebuff[5],"ßC");
        
        // Zellenspannung des internen Akkus anzeigen
        ul_voltage[6]=read_adc(4);
        ul_voltage[6]=(ul_voltage[6]*ui_ufaktor)/512;
        if(ul_voltage[6]<100)
            {
            strcpyf(uc_linebuff[6]," ");
            };
        strcpyf(uc_linebuff[6],"M");
        itoa(uc_dispmode,uc_buffer);
        strcat(uc_linebuff[6],uc_buffer);
        ul_voltage[6]=read_adc(4);
        ul_voltage[6]=(ul_voltage[6]*ui_ufaktor)/512;
        ul_calcvoltage=ul_voltage[6]/10;
        strcatf(uc_linebuff[6]," ");
        if(ul_calcvoltage<10){strcatf(uc_linebuff[6]," ");};
        ltoa(ul_calcvoltage,uc_buffer);
        strcat(uc_linebuff[6],uc_buffer);
        strcatf(uc_linebuff[6],",");
        ul_calcvoltage=ul_voltage[6]%10;
        ltoa(ul_calcvoltage,uc_buffer);
        strcat(uc_linebuff[6],uc_buffer);
        strcatf(uc_linebuff[6],"V");
        switch (uc_alive)
            {
            case 0:
            strcatf(uc_linebuff[6],(" -"));
            break;
            case 1:
            strcatf(uc_linebuff[6],(" |"));
            break;
            case 2:
            strcatf(uc_linebuff[6],(" /"));
            break;
        
        
        
        
        default:
            strcatf(uc_linebuff[6],(" -"));
            };

        
        // Timerwert anzeigen
        strcpyf(uc_linebuff[7]," Ti:");
        if (ui_teletimer<10000)
            {
            strcatf(uc_linebuff[7]," ");
            };
        if (ui_teletimer<1000)
            {
            strcatf(uc_linebuff[7]," ");
            };
        if (ui_teletimer<100)
            {
            strcatf(uc_linebuff[7]," ");
            };
        if (ui_teletimer<10)
            {
            strcatf(uc_linebuff[7]," ");
            };
        itoa(ui_teletimer,uc_buffer);
        strcat(uc_linebuff[7],uc_buffer);
        };
    // Parametereinstellungen aufrufen
    if(uc_dispmode==4)
        {
        strcpyf(uc_linebuff[0],"Parameter");
        strcpyf(uc_linebuff[2],"      ENT");
        strcpyf(uc_linebuff[6],"M");
        itoa(uc_dispmode,uc_buffer);
        strcat(uc_linebuff[6],uc_buffer);
        uc_tast=read_tast();
        if(uc_tast!=uc_oldtast&&uc_tast==0x70)
            {
            uc_oldtast=uc_tast;
            set_param();
            };
        };
/* Auf LCD Anzeigen */

lcd_gotoxy(0,0);
lcd_puts(uc_linebuff[0]);
for(uc_i=strlen(uc_linebuff[0]);uc_i<10;uc_i++)
    {
    lcd_putsf(" ");
    };
lcd_gotoxy(10,0);
lcd_puts(uc_linebuff[1]);
for(uc_i=strlen(uc_linebuff[1]);uc_i<10;uc_i++)
    {
    lcd_putsf(" ");
    };
lcd_gotoxy(0,1);
lcd_puts(uc_linebuff[2]);
for(uc_i=strlen(uc_linebuff[2]);uc_i<10;uc_i++)
    {
    lcd_putsf(" ");
    };
lcd_gotoxy(10,1);
lcd_puts(uc_linebuff[3]);
for(uc_i=strlen(uc_linebuff[3]);uc_i<10;uc_i++)
    {
    lcd_putsf(" ");
    };
lcd_gotoxy(0,2);
lcd_puts(uc_linebuff[4]);
for(uc_i=strlen(uc_linebuff[4]);uc_i<10;uc_i++)
    {
    lcd_putsf(" ");
    };
lcd_gotoxy(10,2);
lcd_puts(uc_linebuff[5]);
for(uc_i=strlen(uc_linebuff[5]);uc_i<10;uc_i++)
    {
    lcd_putsf(" ");
    };
lcd_gotoxy(0,3);
lcd_puts(uc_linebuff[6]);
for(uc_i=strlen(uc_linebuff[6]);uc_i<10;uc_i++)
    {
    lcd_putsf(" ");
    };
lcd_gotoxy(10,3);
lcd_puts(uc_linebuff[7]);
for(uc_i=strlen(uc_linebuff[7]);uc_i<10;uc_i++)
    {
    lcd_putsf(" ");
    };
}


    

void main(void)
{
// Declare your local variables here

unsigned char uc_i=0;
li_timer=0;
li_oldtimer=0;
// Input/Output Ports initialization
// Port A initialization
// Func7=OUT Func6=OUT Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
// State7=P State6=T State5=T State4=T State3=T State2=T State1=T State0=T 
PORTA=0x80;
DDRA=0xC0;

// Port B initialization
// Func7=Out Func6=In Func5=Out Func4=Out Func3=In Func2=Out Func1=Out Func0=Out 
// State7=1 State6=T State5=1 State4=0 State3=T State2=1 State1=0 State0=0 
PORTB=0xA4;  //0b10100100
DDRB=0xA7;   //0b10100111

// Port C initialization
// Func7=Out Func6=Out Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out 
// State7=0 State6=0 State5=0 State4=0 State3=0 State2=0 State1=0 State0=0 
PORTC=0x00;
DDRC=0xFF;

// Port D initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
// State7=R State6=R State5=R State4=R State3=T State2=T State1=T State0=T 
PORTD=0xF0;
DDRD=0x00;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 125.000
// Mode: Normal top=FFh
// OC0 output: Disconnected
// Overflow Interrupt: On
TCCR0=0x03;
TCNT0=0x00;
OCR0=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 1000,0 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: On
// INT0 Mode: Rising Edge
// INT1: On
// INT1 Mode: Falling Edge
// INT2: Off
GICR|=0xC0;
MCUCR=0x0B;
MCUCSR=0x00;
GIFR=0xC0;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x11;

// USART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART Receiver: On
// USART Transmitter: On
// USART Mode: Asynchronous
// USART Baud Rate: 38400
UCSRA=0x00;
UCSRB=0x58;
UCSRC=0x86;
UBRRH=0x00;
UBRRL=0x19;

// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;

// ADC initialization
// ADC Clock frequency: 1000,000 kHz
// ADC Voltage Reference: internal 2,56V
ADMUX=ADC_VREF_TYPE & 0xff;
ADCSRA=0x83;

/**************************/
/***** Testroutines *******/
/**************************/
 /* #asm ("sbi portb,nsel");
uc_kanal=0;
delay_ms(1);
init_rfm01();
reset_fifo();
#asm ("sei");
while (1)
    {
    if (newstring>0)
        {
        newstring=0;
        for (uc_i=0;uc_i<strlen(uc_receivedata);uc_i++)
            {
            putchar(uc_receivedata[uc_i]);
            };
        };
    };*/



/**************************/



// LCD module initialization
lcd_init();

_en1_msk=LCD_EN1;
/* define user character 1 */
define_char(char1,1);
/* define user character 2 */
define_char(char2,2);
/* define user character 3 */
define_char(char3,3);
/* define user character 4 */
define_char(char4,4);
/* define user character 5 */
define_char(char5,5);

_en1_msk=LCD_EN2;
/* define user character 1 */
define_char(char1,1);
/* define user character 2 */
define_char(char2,2);
/* define user character 3 */
define_char(char3,3);
/* define user character 4 */
define_char(char4,4);
/* define user character 5 */
define_char(char5,5);

/**************************/
/***** Testroutines *******/
/**************************/
 lcd_gotoxy(0,0);
 lcd_putsf("Initialisation in Progress");
 lcd_clear();
 
  


/**************************/

// EEPROM Werte holen
si_currcor=ee_currcor;              /* Korrekturfaktor für den Strom H - Messbereich (200)*/
si_currnull=ee_currnull;            /* Korrekturfaktor für den Strom H - Messbereich (500)*/
si_currlcor=ee_currlcor;            /* Korrekturfaktor für den Strom L - Messbereich (200)*/
si_currlnull=ee_currlnull;          /* Korrekturfaktor für den Strom L - Messbereich (500)*/
si_tempzero[0]=ee_tempzero[0];      /* (249) A/D Wandlerwert für 0°C "(A/D Wandler - X) *290 / tempfakt" */
si_tempzero[1]=ee_tempzero[1];      /* (249) A/D Wandlerwert für 0°C "(A/D Wandler - X) *290 / tempfakt" */
si_tempfakt[0]=ee_tempfakt[0];      /* (461) Teilerfaktor für Temperatursteilheit "(A/D Wandler - tempzero) *290 / X" */
si_tempfakt[1]=ee_tempfakt[1];      /* (461) Teilerfaktor für Temperatursteilheit "(A/D Wandler - tempzero) *290 / X" */
ui_ufaktor=ee_ufaktor;              /* Variable für den Spannungsmesser (A/D Wandler 4)org 141 */
ui_blatt=ee_blatt;                  /* Startwert für Blattzahl übernehmen*/
uc_highblatt=ui_blatt/100;          /* Blattzahl in Hilfsvariablen übergeben*/
uc_lowblatt=ui_blatt%100;
uc_kanal=ee_kanal;                  /* Startwert für Empfangskanal übernehmen*/
uc_startmenu=ee_startmenu;          /* Startmenü Auswahl Parameter Übernahme */
uc_dispmode=uc_startmenu;           /* Startmenü Auswahl Parameter Übernahme */

ub_logging=0;                       /* Datantransfer zum PC abschalten */

if (uc_dispmode>4){uc_dispmode=0;}; /* Fehlerhafte Displamodes abfangen */


// AD7795 Initialisieren
ad7795_cs=1;        /* /CS abschalten */
ad7795_clock=1;     /* CLK auf ruheposition =1 setzen */
ad7795_din=1;       /* DIN auf Ruheposition =1 setzen */
reset_ad7795();     /* AD 7795 resetten */
delay_ms(1);        /* 1ms warten */
init_ad7795();      /* Initialisierungsroutine aufrufen */

// RFM 01 initialisieren
#asm ("sbi portb,nsel");
delay_ms(1);
init_rfm01();
reset_fifo();

// Global enable interrupts
#asm("sei");

 lcd_gotoxy(3,0);
 lcd_putsf("LiPo Voltmeter");
 lcd_gotoxy(4,1);
 lcd_putsf("Telemetrie");
 lcd_gotoxy(4,2);
 lcd_putsf("Ver. 2.2");
 lcd_gotoxy(4,3);
 lcd_putsf("23.03.2010");
 delay_ms(1000);


uc_tast=read_tast();
if (uc_tast==0xE0)
    {
    calibrate();
    };

uc_tast=0xF0;
uc_oldtast=uc_tast;



while (1)
      {
      uc_tast=read_tast();
      if(uc_tast!=uc_oldtast)
        {
        uc_oldtast=uc_tast;
        switch (uc_tast)
            {
            case 0xD0 :
            uc_dispmode++;
            if (uc_dispmode>4){uc_dispmode=0;};
            break;
            
            case 0xB0 :
            uc_dispmode--;
            if ((uc_dispmode+1)==0){uc_dispmode=4;};
            break;
            
            };
         /*lcd_clear();*/
         write_display();
         }; 

      if (new_sec>0)
      {
        read6_ad7795();
        si_currh=read_adc(1);
        if (si_currh<564||si_currh>436)            /* Wenn der Strom unter +/- 4A ist den Verstärkten Strombereich verwenden*/
        {
            si_currl=read_adc(0);
            li_curr=calc_currl(si_currl);
        }
        else
        {
            li_curr=calc_curr(si_currh);
        }
      
        calc_value();
        /*lcd_clear();*/
        write_display();
        if (ub_logging>0)
            {
            trans_value();
            ui_time++;            /* Zeitstempel um 1 erhöhen */
            };
        new_sec=0;            /* Sekundenmarker wieder auf 0 setzen */
      }
      
            
      if (newstring>0)
        {
        newstring=0;
        for (uc_i=0;uc_i<strlen(uc_receivedata);uc_i++)
            {
            putchar(uc_receivedata[uc_i]);
            };
        calc_telemetrie();
        };
      if (uc_aderror > 1)
      {
        reset_ad7795();
        delay_ms(1);
        init_ad7795();
        uc_aderror=0;
      };
             
     /* #asm ("sbi portb,sdi");
      delay_ms(2);
      #asm ("cbi portb,sdi");
*/
// Place your code here

      };
};

