Zurück   (C) Christof Ermer, Regensburg Gästebuch (public. sonst besser Email)   ChristofErmer@gmail.com



01.12.2020


ATMega 8 bzw. ATmega328p IO-BOX

Quarz 8 MHz
Files:
Software ATM8-MinBoard_IO.zip
das HEX: main.hex
Eagle Schematic: AT8_MiniBord_V5.sch    Boarddatei: AT8_MiniBord_V5.brd
             

        Quarz 8MHz

Board:

  


LabView Steuersoftware (rein textbasiert)



Board +Gehause

AT8 MiniBoard-IO Doku & Manual

Christof Ermer, 16.11.2020,
Serieller USB  Anschluss:  Baud 9600,8,N,1,  mit FTDI232 USB TTL 5Volt
Mnemonic: ( Befehle )
FORMAT: Frage, Antwort {nur wenn gefordert}; Sonst Standardmäßig „OK“ 
Befehl[,long][,long]<13>
=> []=Optional.  long = +/-32Bit Wert:2= (2^32/2-1) = 2.147.483.647
Antwort ist oft nur ASCII Text als  Wert <13>        12345<13>
Immer gesendet mit “Carriage Return” = ASCII13 = <13> = <CR>
BSP. Device,-123,+123<CR>,    Ping<13>   Pong<13>
 AT Mega8 Pin Zuordnung
Interne Belegung:

Alle PINs sind reine TTL (5Volt). Aber intern über 560 Ohm  Schutzwiderstand nach außen geführt .
Belastung beachten.  Alle Pins sind als reine Input Outputs verwendbar. Oder:
PIN1 = PB1-OC1A    Frequenz Out 16 Bit
PIN2 = PB3-OC2    PWM Out 8 Bit
PIN3 = PD5-T1        Frequenz In. TTL
PIN4 = PC0-ADC0    ADC 10 Bit Resolution 0..5V   
PIN5 = PC1-ADC1     ADC 10 Bit Resolution 0..5V   
PIN6 = PC2-ADC2     ADC 10 Bit Resolution 0..5V   
PIN7 = PC3-ADC3     ADC 10 Bit Resolution 0..5V   
PIN8 = PC4-ADC4     ADC 10 Bit Resolution 0..5V   
    PB2= interne Toggle LED //Abschaltbar PB2= interne Toggle LED  “TGLON”, “TGLOFF”

Mnemonic Befehle. Empfehlung:  Test mit Modemsoftware: COMx,9600 Baud, 8Bit kein Handshake.
Format Pin Nummer bezogen.     Bsp: P4 = Pin4       Befehl: ADCP4<13> Antwort = Wert 0..1023<13>

OUTPx{0,1}  Output Oin[1..8],{0,1}  {x=1..8}   {0 oder1 auswählen 0=Default}
INPx  Input Pin[1..8] Ergebnis: 0=0V, 1=5V, {x=1..8}  {0 oder 1 auswählen 0=Default}
SETFRQ-P1, {Frequenz}                 SETPWM-P,12345
ADCP{4..8}   12Bit = 0 bis 1023 = 0 ..5V.  B7t/Volt = 5/1024 = 4.8828mV/Bit
SETPWM-P2,{Frequenz,PWM [0.255]}           SETPWM-P2,60,15
READFRQ_P3    Antwort nach 1 Sekunde

Zusätzliche Kommandos, aber nicht relevant:
PING    Pong,
Device     Aktuelle Info. Mehrere Zeilen
TT     Timer & Tick Counter +122.07803125 /Sekunde * Wert= vergangene Zeit
STOPFRQ-P1
STOPPWM-P2
LEDON, LEDOFF, LED,]0,1}     Toggle LED
TALKON, TALK OFF, TALK,{0,1} MCU Main-Loops/Sekunde  
GOCR1A  Register OCR1A,  GOCR1B  Register OCR1B
ADC,[0..5]  10 BIT = 0..1023 an  0..5V    RAW Kommando
GTCNT0 = Get TCNT0, usw. GTCCR0,
GTCNT1, GTCCR1A, GTCCR1B, GOCR1A, GOCR1B,
GTCNT2
BAUD,{Baudrate}

---------------------------------------

Aufkleber

[1]=Auswahlwert,  x{0..n} = Auswahl 0 bis n
USB BAUD= 9600, 8Stop, 0-Parity,
0-XONXOFF, 0-Handshake
OUTPx,[0,1]   x=1..8   0 oder 5V TTL
INPx x{1..8}      0 oder 1 =  1  oder 5V.
ADCPx {4..8}      0..1023= 0..5V
SETFRQ-P1, {Frequenz}     >~50Hz ~genau
SETPWM-P2, x={0..255}   PWM [0.255] bei 30Hz
READFRQ_P3 Antwort nach 1 Sekunde


main.c

//------------------------------------------------------------------------------
// Programmed by Christof Ermer
//------------------------------------------------------------------------------

/*
Quarz, BrownOut 4.0V, WatchDog, CKOPT, 8 MHZ
Low Fuse=0x7F   High Fuse= 0x89

TIMER 0 = TICK
TIMER 1 = 16 BIt PWM_T1
TIMER 2 = PWM

Processor 1 = links
#define UART_BAUD_RATE 9600

USBasp auf libusb-win32 driver mit Zadig einstellen, NICH!! WIN32

http://www.engbedded.com/fusecalc/
*/
//#define  TICK_USED
//#define UART_IS_USED

//alternate  Low Fuse=0x9E   High Fuse= 0xEF
#define SOFTWARE "Software: ATM8-MinBoard_IO"
#define AUTOR        "Christof Ermer"
#define DATUM        "30.11.2020"
#define HARDWARE    "AT8 8MHz MiniBoard-IO"
#define SHOW_BAUDRATE    "9600,8,N,1"

#include <ctype.h>
#include <inttypes.h>
#include <avr\io.h>
#include <avr\pgmspace.h> // <--#include <progmem.h>

#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <avr/interrupt.h>  // obsolete #include <avr\signal.h>

#include <avr/wdt.h>
//Produziert Fehler...
#include <util/delay.h>    //_delay_loop_1 _delay_loop_2 delay_ms

#include "main.h"        //witdh Hardware assigns
#include "uart328.h"
#include "TxtFunc.h"
#include "debug.h"



//CONSTANT ARRAYs IN .TEXT = ROM ARREA   .DATA IST SRAM !! .BSS SRAM
//const char MCA_DELIMTERSTR[] PROGMEM = { ',',0 };

volatile uint32_t gu32_Ticks; //T2 timeCounter, only NN_Counter for Keypressings
//uint8_t gu8Mode;
volatile uint8_t gu8Status;
volatile uint16_t gu16TCNT1;
volatile float gufT1_MeasureFRQ;

//proto
void READ_FRQ_Start( void );  //Frequenz MESSEN  MIT TICK TIME

//TCKcounter
// ****************************************
ISR( TIMER0_OVF_vect )    //ATMEGA8
// ****************************************
{
gu32_Ticks++;
if( !(gu32_Ticks % TICK_1000MS) )
    {
    if( gu8Status & FRQ_MEASURE_ACTIVE_FLAG ) // FequnqzMessung
        {
        TCCR1B = 0; //STOP T1
        gu16TCNT1 = TCNT1; // Hohle wert = Pulse/sec
        TCCR1A = 0;
        TCNT1=0;
        DDRD &= ~(1<< PD5);  // T1
        PORTD &= ~(1<< PD5);  // T1
        gufT1_MeasureFRQ = gu16TCNT1;  //* FRQ_FLOAT_FAKTOR;(1000.0/TICKTIME_FLOAT )   
        gu8Status &= ~FRQ_MEASURE_ACTIVE_FLAG;
        gu8Status |= FRQ_MEASURE_READY_FLAG;
        };
    gu8Status |= TICK_EVENT;
    }; // Tickcounter

if( gu32_Ticks & 0b111 )    //(2^n-1) binär jeder 2.te
    {
    UART_TXRX_Check();    //IMMER VORHANDEN !! IN ALLEN LOOPS DIE ZEIT BRAUCHEN
    }; // Tickcounter
};


// ************OVL*************************
void Start_TICK_T0(void)        //ATMEGA8//244 INT/Sec
// *************************************
{
// 8*10^6  / 256 / 256 = 122.0703125  pro sekunde
cli();
TCNT0= 0;
TIFR = (1 << TOV0);  //OVL
TIMSK |= (1 << TOIE0);  //OVL
TCCR0 = (1 << CS01);  //Scale 8//  = 31250
sei();
};


// ********************************************
//ATMEGA8 // MIT CTC MODUS
void SelectBestPreScaler_T1( uint32_t uxSollFrq ) // MIT CTC MODUS
// ********************************************
{
uxSollFrq*= 2;   // Toogle = / 2
if( (F_CPU / 1.0 / uxSollFrq ) > 0xFFFF)
    {
    if( (F_CPU / 8.0 / uxSollFrq ) > 0xFFFF)
        {
        if( (F_CPU / 64.0 / uxSollFrq ) > 0xFFFF)
            {
            if( (F_CPU / 256.0 / uxSollFrq )  > 0xFFFF)
                {
                OCR1A =  round(F_CPU / 1024 / uxSollFrq);
                TCCR1B = (1<< WGM12) | (1<<CS12) | (1<< CS10); //CTC 1024
                }
            else
                {               
                OCR1A =  round(F_CPU / 256 / uxSollFrq);
                TCCR1B = (1<< WGM12) | (1<<CS12); //CTC 256
                };
            }
        else
            {
            OCR1A =  round(F_CPU / 64 / uxSollFrq);
            TCCR1B = (1<< WGM12) | (1<<CS11) | (1<<CS10); //CTC 64
            };
        }
    else   
        {   
        OCR1A =  round(F_CPU / 8 / uxSollFrq);
        TCCR1B = (1<< WGM12) | (1<<CS11); //CTC 8
        };           
    }
else
    {
    OCR1A =  round(F_CPU / uxSollFrq); // /1
    TCCR1B = (1<< WGM12) | (1<<CS10); //CTC 1
    };
};


// ***********************************
void T1_CTC( uint32_t uxSollFrq )  //Frequenz Ausgeben
//ATMEGA8
// ***********************************
{
DDRB |= (1<< PB1);  //OCR1A
PORTB |= (1<< PB1); // OC1A
TCCR1B = 0;
TCNT1 = 0;
INIT_OC1A_PIN() ; 
TCCR1A = (1<< COM1A0);  // Toogle OC1A
//OCRx =  Quarz / Vorteiler / gewünschte Frequenz
SelectBestPreScaler_T1( uxSollFrq );
};


// ***********************************
// ATMEGA 8
void READ_FRQ_Start( void )  //Frequenz MESSEN  MIT TICK TIME
//ATMEGA8
// ***********************************
{ //ClockSOurce =  T1
TCCR1B = 0;
DDRD &= ~(1<< PD5);  // T1
PORTD &= ~(1<< PD5); // T1 Pullup off
OCR1A = 0xFF;
OCR1B = 0xFF;
TCCR1A = 0;
TCNT1 = 0;
cli();
gu32_Ticks = 0; // Stelle 1 Sec Time auf 0
gu8Status |= FRQ_MEASURE_ACTIVE_FLAG;
TCCR1B = (1<< CS12) | (1<< CS11); //T1 SOURCE Falling Edge 
sei();
};


// ***********************************
void T1_STOP_CTC(void )  //nix Frequenz
// ***********************************
{
TCCR1B = 0;
TCNT1 = 0;
CLR_T1_OC1A_PIN();
};


// ***********************************
void READ_FRQ_Stop( void )  //Frequenz MESSEN  MIT TICK TIME
//ATMEGA8
// ***********************************
{ //ClockSOurce =  T1
gu8Status &= ~FRQ_MEASURE_ACTIVE_FLAG;
DDRD &= ~(1<< PD5);  // T1
PORTD &= ~(1<< PD5); // T1
TCCR1B = 0;
TCCR1A = 0;
TCNT1 = 0;
};


// ********************************************
//ATMEGA8  PWM BASE FREQUENZ UND PWM 0..255
void SelectBestPreScaler_T2( uint16_t u16Frq, uint8_t u8PWM ) //FastPWM CLR OC2
// OHNE WGMxx MODUS
// ********************************************
{
TCCR2 = 0;
TCNT2 = 0;
if( (F_CPU / 1.0 / u16Frq) > 0xFF )
    {
    if( (F_CPU / 8.0 / u16Frq) > 0xFF )
        {
        if( (F_CPU /32.0 / u16Frq ) > 0xFF )
            {
            if( (F_CPU / 64.0 / u16Frq ) > 0xFF )
                {
                if( (F_CPU / 128.0 / u16Frq ) > 0xFF)
                    {
                    if( (F_CPU / 256.0 / u16Frq )  > 0xFF)
                        {
                        OCR2 =  round(F_CPU / 1024 / u16Frq);
                        TCCR2 = (1<<CS22) | (1<<COM21) | (1<< CS20); //CTC 1024
                        }
                    else
                        {               
                        OCR2 =  round(F_CPU / 256 / u8PWM);
                        TCCR2 = (1<<CS22) | (1<<CS21); //CTC 256
                        };
                    }
                else
                    {               
                    OCR2 =  round(F_CPU / 128 / u8PWM);
                    TCCR2 = (1<<CS22) | (1<<CS20); //CTC 128
                    };
                }
            else
                {
                OCR2 =  round(F_CPU / 64 / u8PWM);
                TCCR2 =  (1<<CS22); //CTC 64
                };
            }
        else               
            {
            OCR2 =  round(F_CPU / 32 / u8PWM);
            TCCR2 = (1<<CS21) | (1<<CS20); //CTC 32
            };
        }
    else   
        {   
        OCR2 =  round(F_CPU / 8 / u8PWM);
        TCCR2 = (1<<COM21); //CTC 8
        };           
    }
else
    {
    OCR2 =  round(F_CPU / u8PWM); // /1
    TCCR2 = (1<<CS20); //CTC 1
    };
};


// ***********************************
void T2_FastPWM( uint8_t u8SollPWM )
// ***********************************
{
TCCR2 = 0;
TCNT2 = 0;
INIT_OC2DIR();
//TCCR2 = COM21 WGM21  //FAST PWM CLEAR OC2
//OCRx =  Quarz / Vorteiler / gewünschte PWM 0..255
//SelectBestPreScaler_T2( u16Frq, u8SollPWM );//TCCR2 = COM21
OCR2 = u8SollPWM;
TCCR2 = (1<<CS22) | (1<<CS21) | (1<< CS20) | (1<< COM21) | (1<< WGM21) | (1<< WGM20); // Fast PWM; //CTC 1024 = 30 HZ
};


// ***********************************
void T2_STOPPWM( void )
// ***********************************
{
TCCR2 = 0;
TCNT2 = 0;
SET_OC2_LOW();
};



//****************************************************************
#define ADC_5V_AN_C_USED_ENABLED  //SETZE 5V
uint16_t ADC_AT8_10Bit(uint8_t u8Chan) // 0..7
//****************************************************************
{ //REFERENCE = VCC
DDRC &=    ~(1<< u8Chan);  //Bit loeschen
PORTC &= ~(1<< u8Chan); //Wegen Pullup abschalten
ADCSRA = (1<< ADEN) | (1<< ADPS2) | (1<< ADPS1) | (1<< ADPS0);   //ADC EIN UND PreScaler
#ifdef ADC_EXTERN_5V_USED_ENABLED
ADMUX =  u8Chan;    // ADMUX_REFS0 Select pin ADCx using MUX 
#endif
#ifdef ADC_5V_AN_C_USED_ENABLED
ADMUX =  (1<< REFS0) | u8Chan;    // VCC= REF. ADMUX_REFS0 Select pin ADCx using MUX 
#endif
#ifdef ADC_INTERN_BANDGAP_USED_ENABLED
ADMUX = (1<< REFS1) | (1<< REFS0) | u8Chan;    // ADMUX_REFS0 Select pin ADCx using MUX 
#endif
_delay_us(1);
ADCSRA |= (1<< ADSC);    //ADCSRA |= _BV(ADSC);    //Start conversion
while( ADCSRA & (1<< ADSC) )    //wait until _BV(ADSC)=0 =converstion completed
    {
    wdt_reset();
    };   
return ADC;    //ADCW; //get converted value
};


#ifdef UART_USE_ENABLED   
// *******************************************************************
void CheckOrder(char *pcStrOrder) //von gcaRxStr
// *******************************************************************
{
// zerlege UART RX Str inseine Delimitrer Bestandteile
TokensRXStr( pcStrOrder ); //und lege diese in gsCmd.ucaCmd ab

if( !strcasecmp_P( gsCmd.ucaCmd, PSTR("STOPFRQ-P1") )  ) //B1
    {   
    T1_STOP_CTC();
    return;
    };   

if( !strcasecmp_P( gsCmd.ucaCmd, PSTR("STOPPWM-P2") )  ) //B3
    {   
    T2_STOPPWM();
    return;
    };   

if( !strcasecmp_P( gsCmd.ucaCmd, PSTR("SETFRQ-P1") )  )  //B1
    {   
    T1_CTC( (uint32_t)gsCmd.ixCmdVal_1 );
    return;
    };   

if( !strcasecmp_P( gsCmd.ucaCmd, PSTR("SETPWM-P2") )  )   // 30HZ  B3 Base Frequenz 0..255VLaue 0..255
    {   
    T2_FastPWM( (uint8_t)gsCmd.ixCmdVal_1 );
    return;
    };   

if( !strcasecmp_P( gsCmd.ucaCmd, PSTR("READFRQ_P3") )  )   // B1 Timebase
    {   
    READ_FRQ_Start();
    // Ab Hier EINE GanzeE SEKUNDE WARTEN, dann kommt automaisch Antwort
    //     FRQ_MEASURE_READY_FLAG-->
    return;
    };   

if( !strcasecmp_P( gsCmd.ucaCmd, PSTR("OUTP1") )  ) //B1
    {   
    if(TCCR1B)
        {
        T1_STOP_CTC();
        READ_FRQ_Stop();
        };
   
    DDRB |= (1<< PB1);
    if( gsCmd.ixCmdVal_1 )
        {
        PORTB |= (1<< PB1);
        }
    else
        {
        PORTB &= ~(1<< PB1);
        };
    return;
    };

if( !strcasecmp_P( gsCmd.ucaCmd, PSTR("OUTP2") )  ) //B3
    {   
    if( TCCR2 )    T2_STOPPWM();
    DDRB |= (1<< PB3);
    if( gsCmd.ixCmdVal_1 )
        {
        PORTB |= (1<< PB3);
        }
    else
        {
        PORTB &= ~(1<< PB3);
        };   
    return;
    };

if( !strcasecmp_P( gsCmd.ucaCmd, PSTR("OUTP3") )  ) //D5 = T1 INPUT
    {   
    if( TCCR1B ) {READ_FRQ_Stop();};
    DDRD |= (1<< PD5);
    if( gsCmd.ixCmdVal_1 )
        {
        PORTD |= (1<< PD5);
        }
    else
        {
        PORTD &= ~(1<< PD5);
        };   
    return;
    };

if( !strcasecmp_P( gsCmd.ucaCmd, PSTR("OUTP4") )  ) //PC0
    {   
    DDRC |= (1<< PC0);
    if( gsCmd.ixCmdVal_1 )
        {
        PORTC |= (1<< PC0);
        }
    else
        {
        PORTC &= ~(1<< PC0);
        };   
    return;
    };

if( !strcasecmp_P( gsCmd.ucaCmd, PSTR("OUTP5") )  ) //PC1
    {       
    DDRC |= (1<< PC1);
    if( gsCmd.ixCmdVal_1 )
        {
        PORTC |= (1<< PC1);
        }
    else
        {
        PORTC &= ~(1<< PC1);
        };   
    return;
    };

if( !strcasecmp_P( gsCmd.ucaCmd, PSTR("OUTP6") )  ) //PC2
    {   
    DDRC |= (1<< PC2);
    if( gsCmd.ixCmdVal_1 )
        {
        PORTC |= (1<< PC2);
        }
    else
        {
        PORTC &= ~(1<< PC2);
        };   
    return;
    };

if( !strcasecmp_P( gsCmd.ucaCmd, PSTR("OUTP7") )  ) //PC3
    {   
    DDRC |= (1<< PC3);
    if( gsCmd.ixCmdVal_1 )
        {
        PORTC |= (1<< PC3);
        }
    else
        {
        PORTC &= ~(1<< PC3);
        };   
    return;
    };

if( !strcasecmp_P( gsCmd.ucaCmd, PSTR("OUTP8") )  ) //PC4
    {   
    DDRC |= (1<< PC4);
    if( gsCmd.ixCmdVal_1 )
        {
        PORTC |= (1<< PC4);
        }
    else
        {
        PORTC &= ~(1<< PC4);
        };   
    return;
    };
// ------------------------------------------
if( !strcasecmp_P( gsCmd.ucaCmd, PSTR("INP3") )  ) //PD5   
    {   
    if( TCCR1B )
        {
        READ_FRQ_Stop();
        };
    DDRD &= ~(1<<PD5);
    PORTD &= ~(1<<PD5);
    if( PIND & (1<<PD5) )
        {
        uart_putc('1');
        }
    else
        {
        uart_putc('0');
        };
    PrintCR();
    return;
    };

if( !strcasecmp_P( gsCmd.ucaCmd, PSTR("INP1") )  ) //PB1
    {
    T1_STOP_CTC();
    DDRB &= ~(1<<PB1);
    PORTB &= ~(1<<PB1);
    if( PINB & (1<<PB1) )
        {
        uart_putc('1');
        }
    else
        {
        uart_putc('0');
        };
    PrintCR();
    return;
    };

if( !strcasecmp_P( gsCmd.ucaCmd, PSTR("INP2") )  ) //PB3   
    {   
    if( TCCR2 ) {T2_STOPPWM();};
    DDRB &= ~(1<<PB3);
    PORTB &= ~(1<<PB3);
    if( PINB & (1<<PB3) )
        {
        uart_putc('1');
        }
    else
        {
        uart_putc('0');
        };
    PrintCR();
    return;
    };

if( !strcasecmp_P( gsCmd.ucaCmd, PSTR("INP3") )  ) //PD5
    {   
    if( TCCR1B )
        {
        READ_FRQ_Stop();
        };
    DDRD &= ~(1<<PD5);
    PORTD &= ~(1<<PD5);
    if( PIND & (1<<PD5) )
        {
        uart_putc('1');
        }
    else
        {
        uart_putc('0');
        };
    PrintCR();
    return;
    };

if( !strcasecmp_P( gsCmd.ucaCmd, PSTR("INP4") )  ) //PC0
    {   
    DDRC &= ~(1<<PC0);
    PORTC &= ~(1<<PC0);
    if( PINC & (1<<PC0) )
        {
        uart_putc('1');
        }
    else
        {
        uart_putc('0');
        };
    PrintCR();
    return;
    };

if( !strcasecmp_P( gsCmd.ucaCmd, PSTR("INP5") )  ) //PC1
    {   
    DDRC &= ~(1<<PC1);
    PORTC &= ~(1<<PC1);
    if( PINC & (1<<PC1) )
        {
        uart_putc('1');
        }
    else
        {
        uart_putc('0');
        };
    PrintCR();
    return;
    };

if( !strcasecmp_P( gsCmd.ucaCmd, PSTR("INP6") )  ) //PC2
    {   
    DDRC &= ~(1<<PC2);
    PORTC &= ~(1<<PC2);
    if( PINC & (1<<PC2) )
        {
        uart_putc('1');
        }
    else
        {
        uart_putc('0');
        };
    PrintCR();
    return;
    };

if( !strcasecmp_P( gsCmd.ucaCmd, PSTR("INP7") )  ) //PC3
    {   
    DDRC &= ~(1<<PC3);
    PORTC &= ~(1<<PC3);
    if( PINC & (1<<PC3) )
        {
        uart_putc('1');
        }
    else
        {
        uart_putc('0');
        };
    PrintCR();
    return;
    };
   
if( !strcasecmp_P( gsCmd.ucaCmd, PSTR("INP8") )  ) //PC4
    {   
    DDRC &= ~(1<<PC4);
    PORTC &= ~(1<<PC4);
    if( PINC & (1<<PC4) )
        {
        uart_putc('1');
        }
    else
        {
        uart_putc('0');
        };
    PrintCR();
    return;
    };
       
if( !strcasecmp_P( gsCmd.ucaCmd, PSTR("ADCP4") )  ) 
    {   
    PrintULongCR( ADC_AT8_10Bit( 0 ) ); //Nur 6 Eingänge
    return;
    };   
if( !strcasecmp_P( gsCmd.ucaCmd, PSTR("ADCP5") )  ) 
    {   
    PrintULongCR( ADC_AT8_10Bit( 1 ) ); //Nur 6 Eingänge
    return;
    };   
if( !strcasecmp_P( gsCmd.ucaCmd, PSTR("ADCP6") )  ) 
    {   
    PrintULongCR( ADC_AT8_10Bit( 2 ) ); //Nur 6 Eingänge
    return;
    };   
if( !strcasecmp_P( gsCmd.ucaCmd, PSTR("ADCP7") )  ) 
    {   
    PrintULongCR( ADC_AT8_10Bit( 3 ) ); //Nur 6 Eingänge
    return;
    };   
if( !strcasecmp_P( gsCmd.ucaCmd, PSTR("ADCP8") )  ) 
    {   
    PrintULongCR( ADC_AT8_10Bit( 4 ) ); //Nur 6 Eingänge
    return;
    };

if( !strcasecmp_P( gsCmd.ucaCmd, PSTR("ADC") )  ) 
    {   
    PrintULongCR( ADC_AT8_10Bit( (uint8_t)gsCmd.ixCmdVal_1 %  6 ) ); //Nur 6 Eingänge
    return;
    };   

// ---------------------------------
/*
// INPUTS
if( !strcasecmp_P( gsCmd.ucaCmd, PSTR("IN-BITPB") )  )   //Format SETBITPx,Bitrnr,[0,1]   
    {   
    DDRB &= ~(1<<gsCmd.ixCmdVal_1);
    PORTB &= ~(1<<gsCmd.ixCmdVal_1);
    if(PINB & (1<<gsCmd.ixCmdVal_1))
        {
        uart_putc('1');
        }
    else
        {
        uart_putc('0');
        };
    PrintCR();
    return;
    };

// INPUTS
if( !strcasecmp_P( gsCmd.ucaCmd, PSTR("IN-BITPC") )  )   //Format SETBITPx,Bitrnr,[0,1]   
    {   
    DDRC &= ~(1<<gsCmd.ixCmdVal_1);
    PORTC &= ~(1<<gsCmd.ixCmdVal_1);
    if(PINC & (1<<gsCmd.ixCmdVal_1))
        {
        uart_putc('1');
        }
    else
        {
        uart_putc('0');
        };
    PrintCR();
    return;
    };

// INPUTS
if( !strcasecmp_P( gsCmd.ucaCmd, PSTR("IN-BITPD") )  )   //Format SETBITPx,Bitrnr,[0,1]   
    {   
    DDRD &= ~(1<<gsCmd.ixCmdVal_1);
    PORTD &= ~(1<<gsCmd.ixCmdVal_1);
    if(PIND & (1<<gsCmd.ixCmdVal_1))
        {
        uart_putc('1');
        }
    else
        {
        uart_putc('0');
        };
    PrintCR();
    return;
    };
   
// INPUT PORT   
if( !strcasecmp_P( gsCmd.ucaCmd, PSTR("IN_PORTB") )  )
    {   
    DDRB = 0;
    PORTB = 0;
    PrintULongCR( PINB );
    return;
    };

if( !strcasecmp_P( gsCmd.ucaCmd, PSTR("IN_PORTC") )  )
    {   
    DDRC = 0;
    PORTC = 0;
    PrintULongCR( PINC );
    return;
    };

if( !strcasecmp_P( gsCmd.ucaCmd, PSTR("IN_PORTD") )  )
    {   
    DDRC &= 0x3;
    PORTC &= 0x3;
    PrintULongCR( PIND );
    return;
    };
   

// SET BITS   
   

if( !strcasecmp_P( gsCmd.ucaCmd, PSTR("SETBITPB") )  )
    {   
    DDRB |= (1<<gsCmd.ixCmdVal_1);
    if( gsCmd.ixCmdVal_2 )
        {
        PORTB |= (1<<gsCmd.ixCmdVal_1);
        }
    else
        {
        PORTB &= ~(1<<gsCmd.ixCmdVal_1);
        };
    return;
    };


if( !strcasecmp_P( gsCmd.ucaCmd, PSTR("SETBITPC") )  )   //Format SETBITPx,Bitnr,[0,1]   
    {   
    DDRC |= (1<<gsCmd.ixCmdVal_1);
    if( gsCmd.ixCmdVal_2 )
        {
        PORTC |= (1<<gsCmd.ixCmdVal_1);
        }
    else
        {
        PORTC &= ~(1<<gsCmd.ixCmdVal_1);
        };
    return;
    };

if( !strcasecmp_P( gsCmd.ucaCmd, PSTR("SETBITPD") )  )   //Format SETBITPx,Bitnr, [0,1]   
    {   
    DDRD |= (1<<gsCmd.ixCmdVal_1);
    if( gsCmd.ixCmdVal_2 )
        {
        PORTD |= (1<<gsCmd.ixCmdVal_1);
        }
    else
        {
        PORTD &= ~(1<<gsCmd.ixCmdVal_1);
        };
    return;
    };


if( !strcasecmp_P( gsCmd.ucaCmd, PSTR("SETPB") )  )
    {   
    DDRB = 0xFF;
    PORTB= (uint8_t)gsCmd.ixCmdVal_1;   
    return;
    };

if( !strcasecmp_P( gsCmd.ucaCmd, PSTR("SETPC") )  )
    {   
    DDRC = 0xFF;
    PORTC = (uint8_t)gsCmd.ixCmdVal_1;   
    return;
    };

if( !strcasecmp_P( gsCmd.ucaCmd, PSTR("SETPD") )  )
    {   
    DDRD = 0xFF;
    PORTD= (uint8_t)gsCmd.ixCmdVal_1;   
    return;
    };
*/

// -----------------------------------------------------------
if( !strcasecmp_P( gsCmd.ucaCmd, PSTR("PWM_T1A") )  )
    {   
    OCR1A = (uint16_t)gsCmd.ixCmdVal_1;   
    return;
    };
   
if( !strcasecmp_P( gsCmd.ucaCmd, PSTR("PWM_T1B") )  )
    {   
    OCR1B = (uint16_t)gsCmd.ixCmdVal_1;   
    return;
    };

//  ---------------------------------------------------
   


// ------------------------------------

if( !strcasecmp_P( gsCmd.ucaCmd, PSTR("GTCNT0") )  )
    {   
    PrintULongCR(TCNT0);
    return;
    };

if( !strcasecmp_P( gsCmd.ucaCmd, PSTR("GTCCR0") )  )
    {   
    PrintULongCR(TCCR0);
    return;
    };
   
if( !strcasecmp_P( gsCmd.ucaCmd, PSTR("GTCNT1") )  )
    {   
    PrintULongCR(TCNT1);
    return;
    };
if( !strcasecmp_P( gsCmd.ucaCmd, PSTR("GTCCR1A") )  )
    {   
    PrintULongCR(TCCR1A);
    return;
    };
if( !strcasecmp_P( gsCmd.ucaCmd, PSTR("GTCCR1B") )  )
    {   
    PrintULongCR(TCCR1B);
    return;
    };
   
if( !strcasecmp_P( gsCmd.ucaCmd, PSTR("GOCR1A") )  )
    {   
    PrintULongCR(OCR1A);
    return;
    };

if( !strcasecmp_P( gsCmd.ucaCmd, PSTR("GOCR1B") )  )
    {   
    PrintULongCR(OCR1B);
    return;
    };

if( !strcasecmp_P( gsCmd.ucaCmd, PSTR("GTCNT2") )  )
    {   
    PrintULongCR(TCNT2);
    return;
    };

if( !strcasecmp_P( gsCmd.ucaCmd, PSTR("GOC2") )  )
    {   
    PrintULongCR(OCR2);
    return;
    };


// -------------------------------------------------------------------   
//  ---------------------------------------------------


gu8Status = TOGGLE_FLAG; // |STATUS_TRAFFIC_FLAG;
if( !strcasecmp_P( gsCmd.ucaCmd, PSTR("LEDON") )  ) 
    {   
    gu8Status |= TOGGLE_FLAG;
    return;
    };   

if( !strcasecmp_P( gsCmd.ucaCmd, PSTR("LEDOFF") )  ) 
    {   
    gu8Status &= ~TOGGLE_FLAG;
    TOGGLE_LED_OFF();
    return;
    };   

if( !strcasecmp_P( gsCmd.ucaCmd, PSTR("LED") )  ) 
    {   
    if((uint8_t)gsCmd.ixCmdVal_1)
        {
        gu8Status |= TOGGLE_FLAG;
        }
    else
        {
        gu8Status &= ~TOGGLE_FLAG;
        TOGGLE_LED_OFF();
        };
    return;
    };

if( !strcasecmp_P( gsCmd.ucaCmd, PSTR("TALKON") )  ) 
    {   
    gu8Status |= STATUS_TRAFFIC_FLAG;
    return;
    };   

if( !strcasecmp_P( gsCmd.ucaCmd, PSTR("TALKOFF") )  ) 
    {   
    gu8Status &= ~STATUS_TRAFFIC_FLAG;
    return;
    };   

if( !strcasecmp_P( gsCmd.ucaCmd, PSTR("TALK") )  ) 
    {   
    if((uint8_t)gsCmd.ixCmdVal_1)
        {
        gu8Status |= STATUS_TRAFFIC_FLAG;
        }
    else
        {
        gu8Status &= ~STATUS_TRAFFIC_FLAG;
        };
    return;
    };   

if( !strcasecmp_P( gsCmd.ucaCmd, PSTR("PING") )  ) 
    {   
    Print_PStrCR( PSTR("Pong") );   
    return;
    };   

if( !strcasecmp_P( gsCmd.ucaCmd, PSTR("Device") )  ) 
    {   
    Print_PStrCR( PSTR( AUTOR ) );   
    Print_PStrCR( PSTR( DATUM ) );   
    Print_PStrCR( PSTR(HARDWARE ) );   
    Print_PStrCR( PSTR( SHOW_BAUDRATE ) );   
    return;
    };

if( !strcasecmp_P( gsCmd.ucaCmd, PSTR("TT") ) )
    {
    PrintLongCR( gu32_Ticks );
    return;
    };


if( !strcasecmp_P( gsCmd.ucaCmd, PSTR("RR") ) )
    {
    gu32_Ticks = 0; //Reset TickCounter
    return;
    };


if( !strcasecmp_P( gsCmd.ucaCmd, PSTR("BAUD") ) )
    {
    uart_init( UART_BAUD_SELECT((uint16_t)gsCmd.ixCmdVal_1, F_CPU) );
    ResetRxBuff();
    return;
    };   

};
#endif


// **********************************
int main(void)
// **********************************
{
uint32_t u32MCULast= 0;
cli();//The global interrupt flag is maintained in the I bit of the status register (SREG). 
//INIT HARDWARE
//USing of PORTOUTS  1=OUT, 0=IN
DDRB = 0;
DDRC = 0;
DDRD =  UART_RXTX_LEVEL; //TX
PORTD = UART_RXTX_PULL;

//ADCSR |= (1<<ADC); //ADC OFF

//INIT_OC2DIR();  //| (1<<OC1A) | (1<<OC1B)
//INIT_PWM_T1_DIR();

//SFIOR = (1<<PUD); //Pullup Disable

//Pointer and Strings init
wdt_enable(WDTO_1S); //WDTO_500MS
wdt_reset();   //WATCHDOG!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

// Initialize UART library, pass baudrate and avr cpu clock
// with the macro UART_BAUD_SELECT()
//#ifdef UART_IS_USED
uart_init( UART_BAUD_SELECT(UART_BAUD_RATE, F_CPU) );
ResetRxBuff();
sei();

Print_PStrCR( PSTR(HARDWARE) );
Print_PStrCR( PSTR(SOFTWARE) );

Print_PStrCR( PSTR(AUTOR) );
Print_PStrCR( PSTR(DATUM) );
uart_puts_p( PSTR("UART-Baud="));
Print_PStrCR( PSTR(SHOW_BAUDRATE) );
//#endif

OCR1A = PWM_T1_MITTE;
OCR1B = PWM_T1_MITTE;
OCR2 = OCR2_MITTE;

Start_TICK_T0();    //8 Bit Timer 2 = MS Tick Counter
gu32_Ticks = 0;
gu8Status = TOGGLE_FLAG; // |STATUS_TRAFFIC_FLAG;
// ************ MAIN LOOP FOR EVER *********************
  // TOGGLE
for (;;)  /* loop forever */ //Aber schnell > 200.000 mal/Sekunde
    {
    sei();
     wdt_reset(); //WATCHDOG!
    //Hier kann was gemacht werden jede 1 Sekunde   
    u32MCULast++;
   
    if( gu8Status & TICK_EVENT )
        {
        gu8Status &= ~TICK_EVENT;       
       
        if( gu8Status & TOGGLE_FLAG )
            {       
            INIT_TOGGLE();
            TOGGLE_LED();
            };
       
        if(gu8Status & FRQ_MEASURE_READY_FLAG)
            {
            PrintULongCR( (uint32_t)gufT1_MeasureFRQ );
            gu8Status &= ~FRQ_MEASURE_READY_FLAG;
            };
   
        //PrintLongCR( gu32_Ticks );
        if( gu8Status & STATUS_TRAFFIC_FLAG )
            {
            uart_puts_p( PSTR("MCU L/S=") );       
            PrintULongCR( u32MCULast );
            u32MCULast = 0;
            /*
            CRLF();
            ULongToNumStr( TCNT1 );
            CRLF();
            uart_puts_p( PSTR(", ") );       
            ULongToNumStr( gu32_Ticks );
            uart_puts( gcaNumStr );
            uart_puts_p( PSTR(", ") );       
            PrintLongCR( OCR1A );
            */
            //PrintStrCR(  ByteToBin (TIMSK) );
            };
        }; // Tickcounter
               
    if( gu8Status & ORDER_EVENT)
        {
        CheckOrder( gcaRxStr );//gcaRxStr = accumulated str
        ResetRxBuff();
        };

    }; //main loop Ende
};
// ******************* MAIN END ********************************************


main.h
   
#ifndef MAIN_HEADER  //Prevents multiple includes
#define MAIN_HEADER

#define UART_BAUD_RATE 9600
//#define UART_BAUD_RATE 57600U
// #define UART_BAUD_RATE 19200U

#define TIMER_TICK_USED

#define DISABLE_ALL_PULLUP()    (SFIOR |= _BV(PUD));
#define ENABLE_ALLUP_SCL()    (SFIOR &= ~(_BV(PUD)));

#define WDTO_2S   7 //WatchDog

//========================================================================
//TIMERS
//TIMER2  = is 61 miliseconds Timer ~approx.
// 16MhZ / 1024 / 256  = 61,03515625 Hz
// T= 1/f = 0.016384 ms / Interrupt
//Aufzaehlbezeichner
#define RX_BITNR    PD0 //0
#define TX_BITNR    PD1    //1
#define UART_RXTX_PULL    0x03
#define UART_RXTX_LEVEL    0x02

extern volatile  uint32_t gu32_Ticks; //  T2 timeCounter, only NN_Counter for Keypressings
extern void CheckOrder(char *pcStrOrder); //von gcaRxStr
#ifdef TIMER_TICK_USED
void StartTickTimer(void);    //0.1 Seconds  interrupt
#endif
 

#define OC1A_PIN    PB1
#define OC1B_PIN    PB2
#define OC2_PIN        PB3
#define ADC0_PIN    PC0
#define ADC1_PIN    PC1
#define ADC2_PIN    PC2
#define ADC3_PIN    PC3
#define ADC4_PIN    PC4
#define T1_PIN        PD5
#define AIN5_PIN    PD6
#define AIN1_PIN    PD7

#define T1_DDRX                DDRB
#define T1_PORT            PORTB
#define INIT_OC1A_PIN()        (T1_DDRX |= (1<< OC1A_PIN))
#define INIT_OC1B_PIN()        (T1_DDRX |= (1<< OC1B_PIN))
#define SET_T1A_HIGH()        (T1_DDRX |= (1<< OC1A_PIN) )
#define SET_T1A_LOW()        (T1_DDRX &= ~(1<< OC1A_PIN))
#define CLR_T1_OC1A_PIN()    (T1_DDRX &= ~(1<< OC1A_PIN))
#define CLR_T1_OC1B_PIN()    (T1_DDRX &= ~(1<< OC1B_PIN))

#define OC2DDRX    DDRB
#define OC2PORT    PORTB
#define INIT_OC2DIR()    ( OC2DDRX |= (1<<OC2_PIN) )
#define SET_OC2_HIGH()    ( OC2PORT |= (1<<OC2_PIN) )
#define SET_OC2_LOW()    ( OC2PORT &=~(1<<OC2_PIN) )


#define TICK_1000MS    3906 //31250    //122.0703125  8MHz
//#define TICK_1000MS    31250U    //122.0703125  8MHz
//#define TICKTIME_FLOAT    3906.25    //31250
//#define FRQ_FLOAT_FAKTOR    0.256 //( 1000.0 /  31250 );

//#define TICK_50MS        1562 // nur ~ungef   
#define TICK_25MS        98    //781 // nur ~ungef   
//#define TICK_25MS        781U // nur ~ungef   
 
#define PWM_T1_1MS        16000U
#define PWM_T1_MITTE    24000U
#define OCR2_MITTE    127
#define PWM_2MS        32000U

#define INIT_TOGGLE()    (DDRB |= (1<< PB2))  // TOGGLE
#define TOGGLE_LED()    (PORTB ^= (1<< PB2))
#define TOGGLE_LED_OFF()    (PORTB &= ~(1<< PB2))

#define TICK_EVENT                0x01
#define ORDER_EVENT                0x02
#define STATUS_TRAFFIC_FLAG        0x04
#define TOGGLE_FLAG                0x08
#define FRQ_MEASURE_ACTIVE_FLAG    0x20
#define FRQ_MEASURE_READY_FLAG    0x40
//volatile uint8_t gu8Status;
extern volatile uint8_t gu8Status;

#endif  //MAIN_HEADER

TxtFun.c

#include <ctype.h>
#include <inttypes.h>
#include <avr\io.h>
#include <avr\pgmspace.h> // <--#include <progmem.h>
#include <string.h>
//#include <math.h>
#include <stdlib.h>
#include "main.h"
#include "uart328.h"
#include "TxtFunc.h"

#ifdef UART_USE_ENABLED

// GLOBALE VARIABLEN
char* gpcRxPars;
char gcaRxStr[RX_STRMAX + 1]; //+1 for the 0
char gcaNumStr[NUMMAX + 1]; //+1 for the 0
char gcaStr[STRMAX + 1]; //+1 for the 0
COMMAND_TYPE gsCmd;



//Funktionen Definition
// *******************************************************************
void UART_TXRX_Check(void)
/*   
* Get received character from ringbuffer
* uart_getc() returns in the lower byte the received character and
* in the higher byte (bitmask) the last receive error
* UART_NO_DATA is returned when no data is available.
*/
// *******************************************************************
{
uint16_t uiRxUart;

if( gu8Status & ORDER_EVENT )
    {
    return;
    };

uiRxUart = uart_getc();//!FETCH ALLWAYS BYTE FROM RX RINGBUFF INTERRUPT!
if ( !(uiRxUart & UART_NO_DATA) )  //0x0100
    {
//   * new data available from UART
//  * check for Frame or Overrun error
#ifdef USE_ERROR_MSG
    if ( uiRxUart & (UART_FRAME_ERROR | UART_OVERRUN_ERROR | UART_BUFFER_OVERFLOW) )
        {
        ResetRxBuff();
        uart_init( UART_BAUD_SELECT(UART_BAUD_RATE, F_CPU) );// !! Init UART interface
// Framing Error detected, i.e no stop bit detected
        Print_PStrCR(  PSTR("UartErr") );
        };
#endif
//NOW SELCT ACTION FROM ORDER
//Check CR
    uiRxUart &= 0xFF;
    if( (uiRxUart < 13) || (uiRxUart > 122) ){return;};
    if(gpcRxPars < (gcaRxStr + RX_STRMAX))    //ENDANSCHLAG ERREICHT ?
        {
        if(uiRxUart == 13)
            {
            gu8Status |= ORDER_EVENT;
            }
        else
            {
      // Accumulate String only to gcaRxStr with uiAAA Parser
            *gpcRxPars++ = uiRxUart;//Append rxByte
            *gpcRxPars = 0; //ZERO carry
            };//switch
        }// if (pcRxPars < (gcaRxStr + RXSTRMAX))
    else  // To much data Rx, than clear simple all
        {
     //overflow of RX clears all
        ResetRxBuff();    // Clear Rx Parspointer in Buff an terminate RxStr with 0
        };//if(gpcRxPars < (gcaRxStr + RXSTRMAX))
// ENDE DER RX EMPFANGSAUSWERTUNG
    };
};



// *******************************************************************
void ResetRxBuff(void)
// *******************************************************************
{
gpcRxPars = gcaRxStr; // Set parse pointer back;
*gpcRxPars = 0;    //clear Rx
//uart_flush();
gu8Status &= ~ORDER_EVENT;
};



// *******************************************************************
void TokensRXStr(char *pcStrOrder) //von gcaRxStr
// *******************************************************************
{ //INPUT ERWARTET INDER FOR "BEFEHL,WERT" BSP: "SFR,1000"
//uint16_t uiCnt =0;
char caDelimiter[]=",";
char * pStrTok; // für strtok_r
char * pucCh = &pcStrOrder[ strlen(pcStrOrder) ]; // Stelle POINTER auf \0 Ende  // kein unsigned char*

if( (pStrTok = strtok_r( pcStrOrder, caDelimiter , &pucCh)) != NULL) // Trenne 1.Token in Command
    {   
    strcpy(gsCmd.ucaCmd, pStrTok);
    }
else
    {
    *gsCmd.ucaCmd = 0;
    };   
gsCmd.ucaCmd[ COMAMNDSIZEMAX ] = 0; //Sicherheitsterminierung COMAMNDSIZEMAX=10


//für 2 fVal Variablen nach dem Kommando
//gsCmd.ixCmdVal_1 = gsCmd.ixCmdVal_2 = 0;
//gsCmd.CmdVal_1 = gsCmd.ixCmdVal_2 = 0;
if( (pStrTok = strtok_r( NULL,  caDelimiter, &pucCh)) != NULL)
    {
    gsCmd.ixCmdVal_1 = atol(pStrTok);// Und dann TO Float   
    };
   
if( (pStrTok = strtok_r( NULL,  caDelimiter, &pucCh)) != NULL)
    {
//    gsCmd.ixCmdVal_2 = atof(pStrTok);// Und dann TO Float   
    gsCmd.ixCmdVal_2 = atol(pStrTok);// Und dann TO Float   
    };
};


#define FLOAT_PRAEDIGITS_MAX    6 // DIgits nach //dtostrf(fVal,NUMMAX, DIGITS_MAX, gcaNumStr);
#define FLOAT_DIGITS_MAX        3 // DIgits nach //dtostrf(fVal,NUMMAX, DIGITS_MAX, gcaNumStr);
// *******************************************************************
void PrintCR(void)
// *******************************************************************
{
uart_putc( 13 );
};

// ****************
void CRLF(void)
// ****************
{
uart_putc(13);
uart_putc(10);
};


// *******************************************************************
void PrintStrCR(const char* pStr)
// *******************************************************************
{
uart_puts(pStr);
PrintCR();
};


// *******************************************************************
void Print_PStrCR(PGM_P pmStr)
// *******************************************************************
{
uart_puts_p(pmStr);
PrintCR();
};

// **********************************************
void FloatToNumStr(double fVal)
// *************
{
dtostrf(fVal, FLOAT_PRAEDIGITS_MAX, FLOAT_DIGITS_MAX, gcaNumStr ); //[-]d.ddd
};

// **********************************************
void LongToNumStr(int32_t lVal)
// **********************************************
{
ltoa(lVal, gcaNumStr, 10 );
};

// **********************************************
void ULongToNumStr(uint32_t ulVal)
// **********************************************
{
ultoa(ulVal, gcaNumStr, 10 );
};


// *******************************************************************
void PrintLongCR(int32_t lVal)
// *******************************************************************
{
LongToNumStr(lVal); PrintStrCR(gcaNumStr);
};

// *******************************************************************
void PrintULongCR(uint32_t ulVal)
// *******************************************************************
{
ULongToNumStr(ulVal); PrintStrCR(gcaNumStr);
};

// *******************************************************************
void PrintFloatCR(double fVal)
// *******************************************************************
{
FloatToNumStr(fVal); PrintStrCR(gcaNumStr);
};
#endif //UART_USE_ENABLED


txtFunc.h


#ifndef TXTFUNC_HEADER
#define TXTFUNC_HEADER

#define UART_USE_ENABLED

#ifdef UART_USE_ENABLED   
#define STRMAX 64
#define NUMMAX 32
#define RX_STRMAX 32
#define COMAMNDSIZEMAX  32
#define DELIMITER        ','
#define DELIMITERSTR    ","
#define ASC_CR    13
#define ASC_LF    10

// TYPEN DEKLARATION
typedef struct
    {
    char ucaCmd[COMAMNDSIZEMAX +1];
    int32_t ixCmdVal_1;
    int32_t ixCmdVal_2;
//uint8_t ucCmdID;
    }COMMAND_TYPE;

// GLOBALE VARIABLEN
// const char MCA_DELIMITER_MSG[] PROGMEM    = ",";
extern char* gpcRxPars;
extern char gcaRxStr[RX_STRMAX + 1]; //+1 for the 0
extern char gcaNumStr[NUMMAX + 1]; //+1 for the 0
extern char gcaStr[STRMAX + 1]; //+1 for the 0
extern COMMAND_TYPE gsCmd;


// PROTOTYPEN
//Funktions Deklaration
extern void ResetRxBuff(void);
extern void UART_TXRX_Check(void);
extern void TokensRXStr(char *pcStrOrder); //von gcaRxStr


extern void CRLF(void);
extern void PrintCR(void);
extern void PrintStrCR(const char * pStr);
extern void Print_PStrCR(PGM_P pmStr);
extern void CheckOrder(char * pcStr);
extern void LongToNumStr(int32_t lVal);
extern void ULongToNumStr(uint32_t ulVal);
extern void PrintLongCR(int32_t lVal);
extern void PrintULongCR(uint32_t ulVal);
extern void FloatToNumStr(double fVal);
#endif  //UART_USE_ENABLED

#endif // TXTFUNC_HEADER


uart328.c


// Christof Ermer 2.2.2015 MODIFIZIERT PGM_P Pointer bei uart_puts_p
//SREG = u8Sreg;  5.2016

/*************************************************************************
Title:    Interrupt UART library with receive/transmit circular buffers
Author:   Peter Fleury <pfleury@gmx.ch>   http://jump.to/fleury
File:     $Id: uart.c,v 1.6.2.1 2007/07/01 11:14:38 peter Exp $
Software: AVR-GCC 4.1, AVR Libc 1.4.6 or higher
Hardware: any AVR with built-in UART,
License:  GNU General Public License
         
DESCRIPTION:
    An interrupt is generated when the UART has finished transmitting or
    receiving a byte. The interrupt handling routines use circular buffers
    for buffering received and transmitted data.
   
    The UART_RX_BUFFER_SIZE and UART_TX_BUFFER_SIZE variables define
    the buffer size in bytes. Note that these variables must be a
    power of 2.
   
USAGE:
    Refere to the header file uart.h for a description of the routines.
    See also example test_uart.c.

NOTES:
    Based on Atmel Application Note AVR306
                   
LICENSE:
    Copyright (C) 2006 Peter Fleury

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
                       
*************************************************************************/

/************************************************************************
uart_available, uart_flush, uart1_available, and uart1_flush functions
were adapted from the Arduino HardwareSerial.h library by Tim Sharpe on
11 Jan 2009.  The license info for HardwareSerial.h is as follows:

  HardwareSerial.cpp - Hardware serial library for Wiring
  Copyright (c) 2006 Nicholas Zambetti.  All right reserved.

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General Public
  License along with this library; if not, write to the Free Software
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
  Modified 23 November 2006 by David A. Mellis
************************************************************************/

/************************************************************************
Changelog for modifications made by Tim Sharpe, starting with the current
  library version on his Web site as of 05/01/2009.

Date        Description
=========================================================================
05/11/2009  Changed all existing UARTx_RECEIVE_INTERRUPT and UARTx_TRANSMIT_INTERRUPT
              macros to use the "_vect" format introduced in AVR-Libc
              v1.4.0.  Had to split the 3290 and 6490 out of their existing
              macro due to an inconsistency in the UART0_RECEIVE_INTERRUPT
              vector name (seems like a typo: USART_RX_vect for the 3290/6490
              vice USART0_RX_vect for the others in the macro).
            Verified all existing macro register names against the device
              header files in AVR-Libc v1.6.6 to catch any inconsistencies.
05/12/2009  Added support for 48P, 88P, 168P, and 328P by adding them to the
               existing 48/88/168 macro.
            Added Arduino-style available() and flush() functions for both
            supported UARTs.  Really wanted to keep them out of the library, so
            that it would be as close as possible to Peter Fleury's original
            library, but has scoping issues accessing internal variables from
            another program.  Go C!
05/13/2009  Changed Interrupt Service Routine label from the old "SIGNAL" to
               the "ISR" format introduced in AVR-Libc v1.4.0.

************************************************************************/

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include "uart328.h"


/*
 *  constants and macros
 */

/* size of RX/TX buffers */
#define UART_RX_BUFFER_MASK ( UART_RX_BUFFER_SIZE - 1)
#define UART_TX_BUFFER_MASK ( UART_TX_BUFFER_SIZE - 1)

#if ( UART_RX_BUFFER_SIZE & UART_RX_BUFFER_MASK )
#error RX buffer size is not a power of 2
#endif
#if ( UART_TX_BUFFER_SIZE & UART_TX_BUFFER_MASK )
#error TX buffer size is not a power of 2
#endif

#if defined(__AVR_AT90S2313__) \
 || defined(__AVR_AT90S4414__) || defined(__AVR_AT90S4434__) \
 || defined(__AVR_AT90S8515__) || defined(__AVR_AT90S8535__) \
 || defined(__AVR_ATmega103__)
 /* old AVR classic or ATmega103 with one UART */
 #define AT90_UART
 #define UART0_RECEIVE_INTERRUPT   UART_RX_vect
 #define UART0_TRANSMIT_INTERRUPT  UART_UDRE_vect
 #define UART0_STATUS   USR
 #define UART0_CONTROL  UCR
 #define UART0_DATA     UDR 
 #define UART0_UDRIE    UDRIE
#elif defined(__AVR_AT90S2333__) || defined(__AVR_AT90S4433__)
 /* old AVR classic with one UART */
 #define AT90_UART
 #define UART0_RECEIVE_INTERRUPT   UART_RX_vect
 #define UART0_TRANSMIT_INTERRUPT  UART_UDRE_vect
 #define UART0_STATUS   UCSRA
 #define UART0_CONTROL  UCSRB
 #define UART0_DATA     UDR
 #define UART0_UDRIE    UDRIE
#elif  defined(__AVR_ATmega8__)  || defined(__AVR_ATmega16__) || defined(__AVR_ATmega32__) \
  || defined(__AVR_ATmega323__)
  /* ATmega with one USART */
 #define ATMEGA_USART
 #define UART0_RECEIVE_INTERRUPT   USART_RXC_vect
 #define UART0_TRANSMIT_INTERRUPT  USART_UDRE_vect
 #define UART0_STATUS   UCSRA
 #define UART0_CONTROL  UCSRB
 #define UART0_DATA     UDR
 #define UART0_UDRIE    UDRIE
#elif  defined(__AVR_ATmega8515__) || defined(__AVR_ATmega8535__)
  /* ATmega with one USART */
 #define ATMEGA_USART
 #define UART0_RECEIVE_INTERRUPT   USART_RX_vect
 #define UART0_TRANSMIT_INTERRUPT  USART_UDRE_vect
 #define UART0_STATUS   UCSRA
 #define UART0_CONTROL  UCSRB
 #define UART0_DATA     UDR
 #define UART0_UDRIE    UDRIE
#elif defined(__AVR_ATmega163__)
  /* ATmega163 with one UART */
 #define ATMEGA_UART
 #define UART0_RECEIVE_INTERRUPT   UART_RX_vect
 #define UART0_TRANSMIT_INTERRUPT  UART_UDRE_vect
 #define UART0_STATUS   UCSRA
 #define UART0_CONTROL  UCSRB
 #define UART0_DATA     UDR
 #define UART0_UDRIE    UDRIE
#elif defined(__AVR_ATmega162__)
 /* ATmega with two USART */
 #define ATMEGA_USART0
 #define ATMEGA_USART1
 #define UART0_RECEIVE_INTERRUPT   USART0_RXC_vect
 #define UART1_RECEIVE_INTERRUPT   USART1_RXC_vect
 #define UART0_TRANSMIT_INTERRUPT  USART0_UDRE_vect
 #define UART1_TRANSMIT_INTERRUPT  USART1_UDRE_vect
 #define UART0_STATUS   UCSR0A
 #define UART0_CONTROL  UCSR0B
 #define UART0_DATA     UDR0
 #define UART0_UDRIE    UDRIE0
 #define UART1_STATUS   UCSR1A
 #define UART1_CONTROL  UCSR1B
 #define UART1_DATA     UDR1
 #define UART1_UDRIE    UDRIE1
#elif defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__)
 /* ATmega with two USART */
 #define ATMEGA_USART0
 #define ATMEGA_USART1
 #define UART0_RECEIVE_INTERRUPT   USART0_RX_vect
 #define UART1_RECEIVE_INTERRUPT   USART1_RX_vect
 #define UART0_TRANSMIT_INTERRUPT  USART0_UDRE_vect
 #define UART1_TRANSMIT_INTERRUPT  USART1_UDRE_vect
 #define UART0_STATUS   UCSR0A
 #define UART0_CONTROL  UCSR0B
 #define UART0_DATA     UDR0
 #define UART0_UDRIE    UDRIE0
 #define UART1_STATUS   UCSR1A
 #define UART1_CONTROL  UCSR1B
 #define UART1_DATA     UDR1
 #define UART1_UDRIE    UDRIE1
#elif defined(__AVR_ATmega161__)
 /* ATmega with UART */
 #error "AVR ATmega161 currently not supported by this libaray !"
#elif defined(__AVR_ATmega169__)
 /* ATmega with one USART */
 #define ATMEGA_USART
 #define UART0_RECEIVE_INTERRUPT   USART0_RX_vect
 #define UART0_TRANSMIT_INTERRUPT  USART0_UDRE_vect
 #define UART0_STATUS   UCSRA
 #define UART0_CONTROL  UCSRB
 #define UART0_DATA     UDR
 #define UART0_UDRIE    UDRIE
#elif defined(__AVR_ATmega48__) ||defined(__AVR_ATmega88__) || defined(__AVR_ATmega168__) || \
      defined(__AVR_ATmega48P__) ||defined(__AVR_ATmega88P__) || defined(__AVR_ATmega168P__) || \
      defined(__AVR_ATmega328P__)
 /* TLS-Added 48P/88P/168P/328P */
 /* ATmega with one USART */
 #define ATMEGA_USART0
 #define UART0_RECEIVE_INTERRUPT   USART_RX_vect
 #define UART0_TRANSMIT_INTERRUPT  USART_UDRE_vect
 #define UART0_STATUS   UCSR0A
 #define UART0_CONTROL  UCSR0B
 #define UART0_DATA     UDR0
 #define UART0_UDRIE    UDRIE0
#elif defined(__AVR_ATtiny2313__)
 #define ATMEGA_USART
 #define UART0_RECEIVE_INTERRUPT   USART_RX_vect
 #define UART0_TRANSMIT_INTERRUPT  USART_UDRE_vect
 #define UART0_STATUS   UCSRA
 #define UART0_CONTROL  UCSRB
 #define UART0_DATA     UDR
 #define UART0_UDRIE    UDRIE
#elif defined(__AVR_ATmega329__) ||\
      defined(__AVR_ATmega649__) ||\
      defined(__AVR_ATmega325__) ||defined(__AVR_ATmega3250__) ||\
      defined(__AVR_ATmega645__) ||defined(__AVR_ATmega6450__)
  /* ATmega with one USART */
  #define ATMEGA_USART0
  #define UART0_RECEIVE_INTERRUPT   USART0_RX_vect
  #define UART0_TRANSMIT_INTERRUPT  USART0_UDRE_vect
  #define UART0_STATUS   UCSR0A
  #define UART0_CONTROL  UCSR0B
  #define UART0_DATA     UDR0
  #define UART0_UDRIE    UDRIE0
#elif defined(__AVR_ATmega3290__) ||\
      defined(__AVR_ATmega6490__) ||
  /* TLS-Separated these two from the previous group because of inconsistency in the USART_RX */
  /* ATmega with one USART */
  #define ATMEGA_USART0
  #define UART0_RECEIVE_INTERRUPT   USART_RX_vect
  #define UART0_TRANSMIT_INTERRUPT  USART0_UDRE_vect
  #define UART0_STATUS   UCSR0A
  #define UART0_CONTROL  UCSR0B
  #define UART0_DATA     UDR0
  #define UART0_UDRIE    UDRIE0
#elif defined(__AVR_ATmega2560__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega640__)
/* ATmega with two USART */
  #define ATMEGA_USART0
  #define ATMEGA_USART1
  #define UART0_RECEIVE_INTERRUPT   USART0_RX_vect
  #define UART1_RECEIVE_INTERRUPT   USART0_UDRE_vect
  #define UART0_TRANSMIT_INTERRUPT  USART1_RX_vect
  #define UART1_TRANSMIT_INTERRUPT  USART1_UDRE_vect
  #define UART0_STATUS   UCSR0A
  #define UART0_CONTROL  UCSR0B
  #define UART0_DATA     UDR0
  #define UART0_UDRIE    UDRIE0
  #define UART1_STATUS   UCSR1A
  #define UART1_CONTROL  UCSR1B
  #define UART1_DATA     UDR1
  #define UART1_UDRIE    UDRIE1 
#elif defined(__AVR_ATmega644__)
 /* ATmega with one USART */
 #define ATMEGA_USART0
 #define UART0_RECEIVE_INTERRUPT   USART0_RX_vect
 #define UART0_TRANSMIT_INTERRUPT  USART0_UDRE_vect
 #define UART0_STATUS   UCSR0A
 #define UART0_CONTROL  UCSR0B
 #define UART0_DATA     UDR0
 #define UART0_UDRIE    UDRIE0
#elif defined(__AVR_ATmega164P__) || defined(__AVR_ATmega324P__) || defined(__AVR_ATmega644P__)
 /* ATmega with two USART */
 #define ATMEGA_USART0
 #define ATMEGA_USART1
 #define UART0_RECEIVE_INTERRUPT   USART0_RX_vect
 #define UART1_RECEIVE_INTERRUPT   USART0_UDRE_vect
 #define UART0_TRANSMIT_INTERRUPT  USART1_RX_vect
 #define UART1_TRANSMIT_INTERRUPT  USART1_UDRE_vect
 #define UART0_STATUS   UCSR0A
 #define UART0_CONTROL  UCSR0B
 #define UART0_DATA     UDR0
 #define UART0_UDRIE    UDRIE0
 #define UART1_STATUS   UCSR1A
 #define UART1_CONTROL  UCSR1B
 #define UART1_DATA     UDR1
 #define UART1_UDRIE    UDRIE1
#else
 #error "no UART definition for MCU available"
#endif


/*
 *  module global variables
 */
static volatile unsigned char UART_TxBuf[UART_TX_BUFFER_SIZE];
static volatile unsigned char UART_RxBuf[UART_RX_BUFFER_SIZE];
static volatile unsigned char UART_TxHead;
static volatile unsigned char UART_TxTail;
static volatile unsigned char UART_RxHead;
static volatile unsigned char UART_RxTail;
static volatile unsigned char UART_LastRxError;

#if defined( ATMEGA_USART1 )
static volatile unsigned char UART1_TxBuf[UART_TX_BUFFER_SIZE];
static volatile unsigned char UART1_RxBuf[UART_RX_BUFFER_SIZE];
static volatile unsigned char UART1_TxHead;
static volatile unsigned char UART1_TxTail;
static volatile unsigned char UART1_RxHead;
static volatile unsigned char UART1_RxTail;
static volatile unsigned char UART1_LastRxError;
#endif



ISR(UART0_RECEIVE_INTERRUPT)
/*************************************************************************
Function: UART Receive Complete interrupt
Purpose:  called when the UART has received a character
**************************************************************************/
{
    uint8_t u8Sreg = SREG;
   unsigned char tmphead;
    unsigned char data;
    unsigned char usr;
    unsigned char lastRxError;
 
 
    /* read UART status register and UART data register */
    usr  = UART0_STATUS;
    data = UART0_DATA;
   
    /* */
#if defined( AT90_UART )
    lastRxError = (usr & (_BV(FE)|_BV(DOR)) );
#elif defined( ATMEGA_USART )
    lastRxError = (usr & (_BV(FE)|_BV(DOR)) );
#elif defined( ATMEGA_USART0 )
    lastRxError = (usr & (_BV(FE0)|_BV(DOR0)) );
#elif defined ( ATMEGA_UART )
    lastRxError = (usr & (_BV(FE)|_BV(DOR)) );
#endif
       
    /* calculate buffer index */
    tmphead = ( UART_RxHead + 1) & UART_RX_BUFFER_MASK;
   
    if ( tmphead == UART_RxTail ) {
        /* error: receive buffer overflow */
        lastRxError = UART_BUFFER_OVERFLOW >> 8;
    }else{
        /* store new index */
        UART_RxHead = tmphead;
        /* store received data in buffer */
        UART_RxBuf[tmphead] = data;
    }
    UART_LastRxError = lastRxError;  
SREG = u8Sreg;
}


ISR(UART0_TRANSMIT_INTERRUPT)
/*************************************************************************
Function: UART Data Register Empty interrupt
Purpose:  called when the UART is ready to transmit the next byte
**************************************************************************/
{
uint8_t u8Sreg = SREG;
unsigned char tmptail;


if ( UART_TxHead != UART_TxTail) {
    /* calculate and store new buffer index */
    tmptail = (UART_TxTail + 1) & UART_TX_BUFFER_MASK;
    UART_TxTail = tmptail;
    /* get one byte from buffer and write it to UART */
    UART0_DATA = UART_TxBuf[tmptail];  /* start transmission */
}else{
    /* tx buffer empty, disable UDRE interrupt */
    UART0_CONTROL &= ~_BV(UART0_UDRIE);
}
SREG = u8Sreg;
}


/*************************************************************************
Function: uart_init()
Purpose:  initialize UART and set baudrate
Input:    baudrate using macro UART_BAUD_SELECT()
Returns:  none
**************************************************************************/
void uart_init(unsigned int baudrate)
{
    UART_TxHead = 0;
    UART_TxTail = 0;
    UART_RxHead = 0;
    UART_RxTail = 0;
   
#if defined( AT90_UART )
    /* set baud rate */
    UBRR = (unsigned char)baudrate;

    /* enable UART receiver and transmmitter and receive complete interrupt */
    UART0_CONTROL = _BV(RXCIE)|_BV(RXEN)|_BV(TXEN);

#elif defined (ATMEGA_USART)
    /* Set baud rate */
    if ( baudrate & 0x8000 )
    {
         UART0_STATUS = (1<<U2X);  //Enable 2x speed
         baudrate &= ~0x8000;
    }
    UBRRH = (unsigned char)(baudrate>>8);
    UBRRL = (unsigned char) baudrate;
  
    /* Enable USART receiver and transmitter and receive complete interrupt */
    UART0_CONTROL = _BV(RXCIE)|(1<<RXEN)|(1<<TXEN);
   
    /* Set frame format: asynchronous, 8data, no parity, 1stop bit */
    #ifdef URSEL
    UCSRC = (1<<URSEL)|(3<<UCSZ0);
    #else
    UCSRC = (3<<UCSZ0);
    #endif
   
#elif defined (ATMEGA_USART0 )
    /* Set baud rate */
    if ( baudrate & 0x8000 )
    {
           UART0_STATUS = (1<<U2X0);  //Enable 2x speed
           baudrate &= ~0x8000;
       }
    UBRR0H = (unsigned char)(baudrate>>8);
    UBRR0L = (unsigned char) baudrate;

    /* Enable USART receiver and transmitter and receive complete interrupt */
    UART0_CONTROL = _BV(RXCIE0)|(1<<RXEN0)|(1<<TXEN0);
   
    /* Set frame format: asynchronous, 8data, no parity, 1stop bit */
    #ifdef URSEL0
    UCSR0C = (1<<URSEL0)|(3<<UCSZ00);
    #else
    UCSR0C = (3<<UCSZ00);
    #endif

#elif defined ( ATMEGA_UART )
    /* set baud rate */
    if ( baudrate & 0x8000 )
    {
        UART0_STATUS = (1<<U2X);  //Enable 2x speed
        baudrate &= ~0x8000;
    }
    UBRRHI = (unsigned char)(baudrate>>8);
    UBRR   = (unsigned char) baudrate;

    /* Enable UART receiver and transmitter and receive complete interrupt */
    UART0_CONTROL = _BV(RXCIE)|(1<<RXEN)|(1<<TXEN);

#endif

}/* uart_init */


/*************************************************************************
Function: uart_getc()
Purpose:  return byte from ringbuffer 
Returns:  lower byte:  received byte from ringbuffer
          higher byte: last receive error
**************************************************************************/
unsigned int uart_getc(void)
{   
    unsigned char tmptail;
    unsigned char data;


    if ( UART_RxHead == UART_RxTail ) {
        return UART_NO_DATA;   /* no data available */
    }
   
    /* calculate /store buffer index */
    tmptail = (UART_RxTail + 1) & UART_RX_BUFFER_MASK;
    UART_RxTail = tmptail;
   
    /* get data from receive buffer */
    data = UART_RxBuf[tmptail];
   
    return (UART_LastRxError << 8) + data;

}/* uart_getc */


/*************************************************************************
Function: uart_putc()
Purpose:  write byte to ringbuffer for transmitting via UART
Input:    byte to be transmitted
Returns:  none         
**************************************************************************/
void uart_putc(unsigned char data)
{
    unsigned char tmphead;

   
    tmphead  = (UART_TxHead + 1) & UART_TX_BUFFER_MASK;
   
    while ( tmphead == UART_TxTail ){
        ;/* wait for free space in buffer */
    }
   
    UART_TxBuf[tmphead] = data;
    UART_TxHead = tmphead;

    /* enable UDRE interrupt */
    UART0_CONTROL    |= _BV(UART0_UDRIE);

}/* uart_putc */


/*************************************************************************
Function: uart_puts()
Purpose:  transmit string to UART
Input:    string to be transmitted
Returns:  none         
**************************************************************************/
void uart_puts(const char *s )
{
    while (*s)
      uart_putc(*s++);

}/* uart_puts */


/*************************************************************************
Function: uart_puts_p()
Purpose:  transmit string from program memory to UART
Input:    program memory string to be transmitted
Returns:  none
**************************************************************************/
//void uart_puts_p(const char *progmem_s )
void uart_puts_p(PGM_P  progmem_s )
{
    register char c;
   
    while ( (c = pgm_read_byte(progmem_s++)) )
      uart_putc(c);

}/* uart_puts_p */



/*************************************************************************
Function: uart_available()
Purpose:  Determine the number of bytes waiting in the receive buffer
Input:    None
Returns:  Integer number of bytes in the receive buffer
**************************************************************************/
int uart_available(void)
{
        return (UART_RX_BUFFER_MASK + UART_RxHead - UART_RxTail) % UART_RX_BUFFER_MASK;
}/* uart_available */



/*************************************************************************
Function: uart_flush()
Purpose:  Flush bytes waiting the receive buffer.  Acutally ignores them.
Input:    None
Returns:  None
**************************************************************************/
void uart_flush(void)
{
        UART_RxHead = UART_RxTail;
}/* uart_flush */


/*
 * these functions are only for ATmegas with two USART
 */
#if defined( ATMEGA_USART1 )

SIGNAL(UART1_RECEIVE_INTERRUPT)
/*************************************************************************
Function: UART1 Receive Complete interrupt
Purpose:  called when the UART1 has received a character
**************************************************************************/
{
    unsigned char tmphead;
    unsigned char data;
    unsigned char usr;
    unsigned char lastRxError;
 
 
    /* read UART status register and UART data register */
    usr  = UART1_STATUS;
    data = UART1_DATA;
   
    /* */
    lastRxError = (usr & (_BV(FE1)|_BV(DOR1)) );
       
    /* calculate buffer index */
    tmphead = ( UART1_RxHead + 1) & UART_RX_BUFFER_MASK;
   
    if ( tmphead == UART1_RxTail ) {
        /* error: receive buffer overflow */
        lastRxError = UART_BUFFER_OVERFLOW >> 8;
    }else{
        /* store new index */
        UART1_RxHead = tmphead;
        /* store received data in buffer */
        UART1_RxBuf[tmphead] = data;
    }
    UART1_LastRxError = lastRxError;  
}


SIGNAL(UART1_TRANSMIT_INTERRUPT)
/*************************************************************************
Function: UART1 Data Register Empty interrupt
Purpose:  called when the UART1 is ready to transmit the next byte
**************************************************************************/
{
    unsigned char tmptail;

   
    if ( UART1_TxHead != UART1_TxTail) {
        /* calculate and store new buffer index */
        tmptail = (UART1_TxTail + 1) & UART_TX_BUFFER_MASK;
        UART1_TxTail = tmptail;
        /* get one byte from buffer and write it to UART */
        UART1_DATA = UART1_TxBuf[tmptail];  /* start transmission */
    }else{
        /* tx buffer empty, disable UDRE interrupt */
        UART1_CONTROL &= ~_BV(UART1_UDRIE);
    }
}


/*************************************************************************
Function: uart1_init()
Purpose:  initialize UART1 and set baudrate
Input:    baudrate using macro UART_BAUD_SELECT()
Returns:  none
**************************************************************************/
void uart1_init(unsigned int baudrate)
{
    UART1_TxHead = 0;
    UART1_TxTail = 0;
    UART1_RxHead = 0;
    UART1_RxTail = 0;
   

    /* Set baud rate */
    if ( baudrate & 0x8000 )
    {
        UART1_STATUS = (1<<U2X1);  //Enable 2x speed
      baudrate &= ~0x8000;
    }
    UBRR1H = (unsigned char)(baudrate>>8);
    UBRR1L = (unsigned char) baudrate;

    /* Enable USART receiver and transmitter and receive complete interrupt */
    UART1_CONTROL = _BV(RXCIE1)|(1<<RXEN1)|(1<<TXEN1);
   
    /* Set frame format: asynchronous, 8data, no parity, 1stop bit */  
    #ifdef URSEL1
    UCSR1C = (1<<URSEL1)|(3<<UCSZ10);
    #else
    UCSR1C = (3<<UCSZ10);
    #endif
}/* uart_init */


/*************************************************************************
Function: uart1_getc()
Purpose:  return byte from ringbuffer 
Returns:  lower byte:  received byte from ringbuffer
          higher byte: last receive error
**************************************************************************/
unsigned int uart1_getc(void)
{   
    unsigned char tmptail;
    unsigned char data;


    if ( UART1_RxHead == UART1_RxTail ) {
        return UART_NO_DATA;   /* no data available */
    }
   
    /* calculate /store buffer index */
    tmptail = (UART1_RxTail + 1) & UART_RX_BUFFER_MASK;
    UART1_RxTail = tmptail;
   
    /* get data from receive buffer */
    data = UART1_RxBuf[tmptail];
   
    return (UART1_LastRxError << 8) + data;

}/* uart1_getc */


/*************************************************************************
Function: uart1_putc()
Purpose:  write byte to ringbuffer for transmitting via UART
Input:    byte to be transmitted
Returns:  none         
**************************************************************************/
void uart1_putc(unsigned char data)
{
    unsigned char tmphead;

   
    tmphead  = (UART1_TxHead + 1) & UART_TX_BUFFER_MASK;
   
    while ( tmphead == UART1_TxTail ){
        ;/* wait for free space in buffer */
    }
   
    UART1_TxBuf[tmphead] = data;
    UART1_TxHead = tmphead;

    /* enable UDRE interrupt */
    UART1_CONTROL    |= _BV(UART1_UDRIE);

}/* uart1_putc */


/*************************************************************************
Function: uart1_puts()
Purpose:  transmit string to UART1
Input:    string to be transmitted
Returns:  none         
**************************************************************************/
void uart1_puts(const char *s )
{
    while (*s)
      uart1_putc(*s++);

}/* uart1_puts */


/*************************************************************************
Function: uart1_puts_p()
Purpose:  transmit string from program memory to UART1
Input:    program memory string to be transmitted
Returns:  none
**************************************************************************/
void uart1_puts_p(const char *progmem_s )
{
    register char c;
   
    while ( (c = pgm_read_byte(progmem_s++)) )
      uart1_putc(c);

}/* uart1_puts_p */



/*************************************************************************
Function: uart1_available()
Purpose:  Determine the number of bytes waiting in the receive buffer
Input:    None
Returns:  Integer number of bytes in the receive buffer
**************************************************************************/
int uart1_available(void)
{
        return (UART_RX_BUFFER_MASK + UART1_RxHead - UART1_RxTail) % UART_RX_BUFFER_MASK;
}/* uart1_available */



/*************************************************************************
Function: uart1_flush()
Purpose:  Flush bytes waiting the receive buffer.  Acutally ignores them.
Input:    None
Returns:  None
**************************************************************************/
void uart1_flush(void)
{
        UART1_RxHead = UART1_RxTail;
}/* uart1_flush */

#endif

uart328.h

#ifndef UART_H
#define UART_H
/************************************************************************
Title:    Interrupt UART library with receive/transmit circular buffers
Author:   Peter Fleury <pfleury@gmx.ch>   http://jump.to/fleury
File:     $Id: uart.h,v 1.8.2.1 2007/07/01 11:14:38 peter Exp $
Software: AVR-GCC 4.1, AVR Libc 1.4
Hardware: any AVR with built-in UART, tested on AT90S8515 & ATmega8 at 4 Mhz
License:  GNU General Public License
Usage:    see Doxygen manual

LICENSE:
    Copyright (C) 2006 Peter Fleury

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
   
************************************************************************/

/************************************************************************
uart_available, uart_flush, uart1_available, and uart1_flush functions
were adapted from the Arduino HardwareSerial.h library by Tim Sharpe on
11 Jan 2009.  The license info for HardwareSerial.h is as follows:

  HardwareSerial.h - Hardware serial library for Wiring
  Copyright (c) 2006 Nicholas Zambetti.  All right reserved.

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General Public
  License along with this library; if not, write to the Free Software
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
************************************************************************/

/************************************************************************
Changelog for modifications made by Tim Sharpe, starting with the current
  library version on his Web site as of 05/01/2009.

Date        Description
=========================================================================
05/12/2009  Added Arduino-style available() and flush() functions for both
            supported UARTs.  Really wanted to keep them out of the library, so
            that it would be as close as possible to Peter Fleury's original
            library, but has scoping issues accessing internal variables from
            another program.  Go C!

************************************************************************/

/**
 *  @defgroup pfleury_uart UART Library
 *  @code #include <uart.h> @endcode
 *
 *  @brief Interrupt UART library using the built-in UART with transmit and receive circular buffers.
 *
 *  This library can be used to transmit and receive data through the built in UART.
 *
 *  An interrupt is generated when the UART has finished transmitting or
 *  receiving a byte. The interrupt handling routines use circular buffers
 *  for buffering received and transmitted data.
 *
 *  The UART_RX_BUFFER_SIZE and UART_TX_BUFFER_SIZE constants define
 *  the size of the circular buffers in bytes. Note that these constants must be a power of 2.
 *  You may need to adapt this constants to your target and your application by adding
 *  CDEFS += -DUART_RX_BUFFER_SIZE=nn -DUART_RX_BUFFER_SIZE=nn to your Makefile.
 *
 *  @note Based on Atmel Application Note AVR306
 *  @author Peter Fleury pfleury@gmx.ch  http://jump.to/fleury
 */
 
/**@{*/


#if (__GNUC__ * 100 + __GNUC_MINOR__) < 304
#error "This library requires AVR-GCC 3.4 or later, update to newer AVR-GCC compiler !"
#endif


/*
** constants and macros
*/

/** @brief  UART Baudrate Expression
 *  @param  xtalcpu  system clock in Mhz, e.g. 4000000L for 4Mhz         
 *  @param  baudrate baudrate in bps, e.g. 1200, 2400, 9600    
 */
#define UART_BAUD_SELECT(baudRate,xtalCpu) ((xtalCpu)/((baudRate)*16l)-1)

/** @brief  UART Baudrate Expression for ATmega double speed mode
 *  @param  xtalcpu  system clock in Mhz, e.g. 4000000L for 4Mhz          
 *  @param  baudrate baudrate in bps, e.g. 1200, 2400, 9600    
 */
#define UART_BAUD_SELECT_DOUBLE_SPEED(baudRate,xtalCpu) (((xtalCpu)/((baudRate)*8l)-1)|0x8000)


/** Size of the circular receive buffer, must be power of 2 */
#ifndef UART_RX_BUFFER_SIZE
#define UART_RX_BUFFER_SIZE 128
#endif
/** Size of the circular transmit buffer, must be power of 2 */
#ifndef UART_TX_BUFFER_SIZE
#define UART_TX_BUFFER_SIZE 128
#endif

/* test if the size of the circular buffers fits into SRAM */
#if ( (UART_RX_BUFFER_SIZE+UART_TX_BUFFER_SIZE) >= (RAMEND-0x60 ) )
#error "size of UART_RX_BUFFER_SIZE + UART_TX_BUFFER_SIZE larger than size of SRAM"
#endif

/*
** high byte error return code of uart_getc()
*/
#define UART_FRAME_ERROR      0x0800              /* Framing Error by UART       */
#define UART_OVERRUN_ERROR    0x0400              /* Overrun condition by UART   */
#define UART_BUFFER_OVERFLOW  0x0200              /* receive ringbuffer overflow */
#define UART_NO_DATA          0x0100              /* no receive data available   */


/*
** function prototypes
*/

/**
   @brief   Initialize UART and set baudrate
   @param   baudrate Specify baudrate using macro UART_BAUD_SELECT()
   @return  none
*/
extern void uart_init(unsigned int baudrate);


/**
 *  @brief   Get received byte from ringbuffer
 *
 * Returns in the lower byte the received character and in the
 * higher byte the last receive error.
 * UART_NO_DATA is returned when no data is available.
 *
 *  @param   void
 *  @return  lower byte:  received byte from ringbuffer
 *  @return  higher byte: last receive status
 *           - \b 0 successfully received data from UART
 *           - \b UART_NO_DATA          
 *             <br>no receive data available
 *           - \b UART_BUFFER_OVERFLOW  
 *             <br>Receive ringbuffer overflow.
 *             We are not reading the receive buffer fast enough,
 *             one or more received character have been dropped
 *           - \b UART_OVERRUN_ERROR    
 *             <br>Overrun condition by UART.
 *             A character already present in the UART UDR register was
 *             not read by the interrupt handler before the next character arrived,
 *             one or more received characters have been dropped.
 *           - \b UART_FRAME_ERROR      
 *             <br>Framing Error by UART
 */
extern unsigned int uart_getc(void);


/**
 *  @brief   Put byte to ringbuffer for transmitting via UART
 *  @param   data byte to be transmitted
 *  @return  none
 */
extern void uart_putc(unsigned char data);


/**
 *  @brief   Put string to ringbuffer for transmitting via UART
 *
 *  The string is buffered by the uart library in a circular buffer
 *  and one character at a time is transmitted to the UART using interrupts.
 *  Blocks if it can not write the whole string into the circular buffer.
 *
 *  @param   s string to be transmitted
 *  @return  none
 */
extern void uart_puts(const char *s );


/**
 * @brief    Put string from program memory to ringbuffer for transmitting via UART.
 *
 * The string is buffered by the uart library in a circular buffer
 * and one character at a time is transmitted to the UART using interrupts.
 * Blocks if it can not write the whole string into the circular buffer.
 *
 * @param    s program memory string to be transmitted
 * @return   none
 * @see      uart_puts_P
 */
//extern void uart_puts_p(const char *s );
extern void uart_puts_p(PGM_P s );

/**
 * @brief    Macro to automatically put a string constant into program memory
 */
#define uart_puts_P(__s)       uart_puts_p(PSTR(__s))

/**
 *  @brief   Return number of bytes waiting in the receive buffer
 *  @param   none
 *  @return  bytes waiting in the receive buffer
 */
extern int uart_available(void);

/**
 *  @brief   Flush bytes waiting in receive buffer
 *  @param   none
 *  @return  none
 */
extern void uart_flush(void);


/** @brief  Initialize USART1 (only available on selected ATmegas) @see uart_init */
extern void uart1_init(unsigned int baudrate);
/** @brief  Get received byte of USART1 from ringbuffer. (only available on selected ATmega) @see uart_getc */
extern unsigned int uart1_getc(void);
/** @brief  Put byte to ringbuffer for transmitting via USART1 (only available on selected ATmega) @see uart_putc */
extern void uart1_putc(unsigned char data);
/** @brief  Put string to ringbuffer for transmitting via USART1 (only available on selected ATmega) @see uart_puts */
extern void uart1_puts(const char *s );
/** @brief  Put string from program memory to ringbuffer for transmitting via USART1 (only available on selected ATmega) @see uart_puts_p */
extern void uart1_puts_p(const char *s );
/** @brief  Macro to automatically put a string constant into program memory */
#define uart1_puts_P(__s)       uart1_puts_p(PSTR(__s))
/** @brief   Return number of bytes waiting in the receive buffer */
extern int uart1_available(void);
/** @brief   Flush bytes waiting in receive buffer */
extern void uart1_flush(void);

/**@}*/


#endif // UART_H