#include <avr/io.h>             	// definice IO registru atd.
#include <avr/interrupt.h>  
#include <avr/sleep.h> 


#define F_CPU 8000000UL //8MHz   
#include <util/delay.h>        


// Změna bitu portu, IO registru nebo proměnné:
#define setb(port,pin)    port |= 1<<pin    //nastav bit
#define clrb(port,pin)    port &= ~(1<<pin) //nuluj bit
#define negb(port,pin)    port ^= 1<<pin    //neguj bit

#define AINpin PB3
#define INT0pin PD2
#define CidloOUTpin PD3
#define SMT160 PC3

// bitova maska snímače teploty
#define TH0 0x80


void INIT();
void ACINIT();
void Timer1INIT();
void SleepINIT();
void Int0INIT();
void Init_USART0();
void Odesilani_USART0(unsigned char);
void u_putc(char);


/////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////



char i=0;	//ukazatel na pole namereych hodnot
unsigned int teplota=0;
long int b;
unsigned int vzdalenost=5,cas;
unsigned char poc=1;
unsigned char test=0x01;
unsigned char vzdalenostchar;
char *pchPtr=(char*)&cas;	//ukazatel na promennou cas, do ktere se budou ukladat dva byty casovace

unsigned char cidlo1=0x20, maska=0xF0, maska2=0x0F, LowData=5, HighData=6;	//binarne 00100000 toto bude pricteno k hodnote hladiny
unsigned char hamm[]={0,105,42,67,76,37,102,15,112,25,90,51,60,85,22,127};


///////////////////////////////////////////NASTAVENI PERIFERII///////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////
//nastaveni portů a komparatoru

void INIT()
{
	DDRB&=~(1<<AINpin);//as input
	PORTB&=~(1<<AINpin);//no Pull-up

	DDRD&=~(1<<INT0pin);//as input
	PORTD&=~(1<<INT0pin);//no Pull-up	

	DDRD|=(1<<CidloOUTpin);//as output;
	PORTD&=~(1<<CidloOUTpin);//no Pull-up

	DDRC=0xFF;			//cely C vystupni
	PORTC=0xFF;

	DDRA&=~(1<<SMT160);//as input
	PORTA&=~(1<<SMT160);//no Pull-up

	sei();	//povoleni preruseni
}	
//nastaveni analogoveho komparatoru
void ACINIT()
{
	ACSR|=
	(0<<ACD)|	//zapnuti komparatoru
	(0<<ACBG)|	//kladny vstup je AIN0
	(0<<ACIE)|	//zakaazani preruseni komparatoru, aby nedoslo k jeho vyvolani pri nastavovani ACIS
	(0<<ACIC)|	//zakazani spusteni casovace
	(1<<ACIS1)|	//preruseni vyvolano prekrocenim hodnoty na ref vstupu
	(1<<ACIS0);
	
}


//nastaveni RTC



void Init_DS1302()
{
   setb(DDRA,2);         // SCLK_M = 1 //nastavit jako vystup
   setb(DDRA,1);		//SDI_M = 1
   setb(DDRA,0);		//RESET_M = 1
   clrb(PORTA,2);       //SCLK = 0 klidovy stav log 0
   clrb(PORTA,0);		//RESET = 0
   clrb(PORTA,1);		//SDI = 0

}

//nastaveni casovace 0

void Timer1INIT()
{
	TCCR1A&=~
	(1<<WGM10)|		//mod 0
	(1<<WGM11)|

	(1<<COM1A1)|	//zadna reakce vystupu na preruseni
	(1<<COM1A0);


	TCCR1B&=~
	(1<<WGM12)|		//mod 0
	(1<<WGM13)|
	
	(1<<CS10)|		//casovac vypnut
	(1<<CS11)|
	(1<<CS12);
		
}

//nastaveni usporneho rezimu

void SleepINIT()
{

sleep_enable();	//povoleni uspani

set_sleep_mode(SLEEP_MODE_PWR_DOWN);	//rezim uspani Power-Down

}

//nastaveni preruseni 0

void Int0INIT()
{
	GICR|=
	(1<<INT0);	//povoleni preruseni INT0
	
	MCUCR&=~		//preruseni se vyvola log0 na vstupu
	(1<<ISC00)|
	(1<<ISC01);

}

//nastaveni USART0
void Init_USART0()
{
	UCSR0A&=~
	(1<<U2X0)|
	(1<<MPCM0);

	UCSR0B|=
	(1<<TXCIE0)|
	(1<<RXEN0)|
	(1<<TXEN0);
	
	
	UCSR0C|=
	(1<<URSEL0)|
	(1<<UCSZ00)|
	(1<<UCSZ01);
	

	UBRR0H=0x00;
	UBRR0L=0x33;	//rychlosst 9600 Bd
}
////////////////////////////////////////MERENI TEPLOTY SMT160////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////

unsigned int Merto() {
 unsigned int sh, sl, opakovani, vystup;
 unsigned char i=5, th=0x08;

 float teplota=0;
 cli();
 while(i--) {
  sh=0;
  opakovani=0x0FFFF;
  while(opakovani--) if(PINC&th) sh++;
  sl=0;
  opakovani=0x0FFFF;
  while(opakovani--) if(!(PINC&th)) sl++;
  teplota+=(int)((((float)sh/(float)(sh+sl))-0.32)/0.00047);
   }
  sei();
 vystup=(int)(teplota/5)+1000;
 if((vystup<700)||(vystup>2200)) vystup=0;
 return vystup;
}


/////////////////////////////////////////Odesilani dat USART////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////

void Odesilani_USART0(unsigned char Data)
{


Data|=cidlo1;
HighData=Data & maska;	//maskovani
LowData=Data & maska2;
HighData=HighData>>4;		//posunuti bitu doprava
LowData=hamm[LowData];
HighData=hamm[HighData];
u_putc(LowData);
u_putc(HighData);

	
}


void u_putc( char data )
{
while ( !( UCSR0A & (1<<UDRE0)) );     // cekej do vyprázdnení bufferu

UDR0 = data;                         
}


////////////////////////////////////////VYPOCET VZDALENOSTI////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////

unsigned char Vzdalenost(unsigned int a){
unsigned int SprRychl, PresTeplota;
float rychl=331.8, rychlK=0.61;

	teplota=Merto();
	PresTeplota=(teplota-1000)/10;
	SprRychl=(unsigned int)(rychl+((float)((rychlK)*(PresTeplota))));
	vzdalenost=(unsigned int)((SprRychl*a)/160000);
	return vzdalenost;
}


////////////////////////////////////////OBSLUHA PRERUSENI////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////
//obsluha preruseni komparatoru

ISR(ANA_COMP_vect)
{
	
	

	TCCR1B&=~(1<<CS10);	//vypnuti casovace

	ACSR&=~(1<<ACIE);	//vypnuti komparatoru

PORTC=TCNT1L;

	ACSR&=~
	(1<<ACI);	//vynulovani priznaku

	test=0x02;	
	sleep_enable();		


}

//obsluha preruseni INT0
ISR(INT0_vect)
{
	sleep_disable();	//vypnuti uspavani

	ACSR|=
	(1<<ACIE);	//povoleni preruseni komparatoru
	
	test=0x01;		//testovani v hlavnim programu

	TCCR1B|=
	(1<<CS10)|	//zapnuti casovace bez deleni
	(0<<CS11)|
	(0<<CS12);

}




/////////////////////////////////////////MAIN////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////

					
int main(void)					//změření vstupního napětí 
{

	INIT();						//potr B vystupni 
	ACINIT();					//nastaveni komaparatoru
	Timer1INIT();				//nastaveni casovace 0	
	SleepINIT();				//nastaveni usporneho rezimu
	Int0INIT();					//nastaveni preruseni


	for(;;)
	{
	if (test==0x01){
	setb(PORTD,3);//PORTD|=(1<<CidloOUTpin);	//odeslani impuslu
	_delay_us(12.125);
	clrb(PORTD,3);//PORTD&=~(0<<CidloOUTpin);
	_delay_us(12.125);
	setb(PORTD,3);//PORTD|=(1<<CidloOUTpin);
	_delay_us(12.125);
	clrb(PORTD,3);//PORTD&=~(0<<CidloOUTpin);
	_delay_us(12.125);
	}

	if (test==0x02){ 
		pchPtr[0]=TCNT1L;	//dolni byte casu
		pchPtr[1]=TCNT1H;	//horni byte casu
		TCNT1L=0x00;	//vynulovani casovace
		TCNT1H=0x00;
		vzdalenost=Vzdalenost(cas);   //vypocet vzdalensoti
	
		vzdalenostchar=vzdalenost;		
		Odesilani_USART0(vzdalenostchar);
	
		ACSR&=~(1<<ACI);	//vynulovani priznaku komparatoru	
		
		sleep_cpu();
		}
	
	
	else {asm ("NOP");}


	}


}









