//----------------------- ADC převodník + PIEZZO -------------------------------------
#define F_CPU  16000000				// frekvence krystalu
#include <avr/io.h>					// definicevstupy výstupy
#include <util/delay.h>				// časové rodlevy
#include <avr/interrupt.h>			// vektory přerušení
#define LCD
#include "LCD_knihovna.h"				// LCD displej
// ------------------------------------------------------------
// hlavičky použitých funkcí ----------------------------------
void ADC_prevodnik (void);			// A/D převod
void zobraz_LCD (void);				// výpis hodnoty na LCD
void zvuk (void);					// generování zvuku
void frekvence (void);				// výpis frekvence na LCD displej

int hodnota;						// změřená hodnota
float mezivysl;						// pomocná hodnota při výpočtu


int main (void)
{
	DDRC =  0xff;					// port C jako výstupní
	PORTC = 0b11000010;				// zapnutí LCD displeje
	init_lcd();						// inicializace LCD
	_delay_ms(20);

	sei();							// povolení přerušení
	ADMUX = 0b00000000;  			// napěťová reference Aref, kanál ADC0
	ADCSRA = 0b11001110;			// enable,přerušení,dělička 64,start převodu

	while (1)
	{
	ADC_prevodnik();				// zahájí nový převod
	}

	return (1);
}

void ADC_prevodnik (void)
{
	
	ADCSRA|=0x40;					// zahájení převodu
}

ISR( ADC_vect)						// přerušení v důsledku dokončení převodu
{
	hodnota = ADCW;					// uložení převedené hodnoty z registru ADCW do hodnota

	mezivysl = (float) 5/1023;		// aplikace vzorce pro získání hodnoty napětí (desetiný tvar)

	mezivysl = (float) mezivysl * hodnota;
	hodnota = (float) mezivysl *100;	// uložení převedené hodnoty 100x větší do proměnné hodnota


	zobraz_LCD();					// vypsání převedené hodnoty
	zvuk();							// generace zvuku dle hodnoty AD převodu
}

void zobraz_LCD (void)				// výpis převodu na LCD
{


	line_1();  
    lcd_text("Napeti:");

	gotoxy(1,11);
	int pomocna = hodnota %100;		// zbytek po celočíselném dělení uložen v proměnná (desetinná část)
	lcd_byt(pomocna/10);			// výpis na jedno desetinné místo

	gotoxy(1,9); 
	lcd_byt(hodnota/100);			// celočíselný výsledek po dělení (celé číslo)

	gotoxy(1,12);
	lcd_text(".");

	gotoxy(1,14);
	lcd_text("V");

	//line_2();						// výpis maximální a minimální hodnoty napětí
	//if (ADCW >0b1111110000 ) lcd_text("Max U (Ucc)");
	//	else if (ADCW == 0x00) lcd_text("Min U");
	//		else lcd_text("             ");
	_delay_ms(10);
}

void zvuk (void)					// generování zvuku
{
	DDRD = 0xff;
	for (int a = 0; a<10; a++)		// zvuk se opakuje 10x (10 period)
	{
		PORTD = 0b10000000;			// nastaví log 1 po danou dobu (20*hodnota/10)us
		_delay_us(20*(hodnota/10));
		PORTD = 0x00;				// nuluje na danou dobu (20*hodnota/10)us
		_delay_us(20*(hodnota/10));
	}
	frekvence();					// z nastavené frekvence urči a vypiš hodnotu
}


void frekvence (void)
{
	float frek;
	int pomocna;

	frek = 1/(0.04*(hodnota/10));	// 1/T - frekvence
	pomocna = (float)frek*1000;		// převod na kHz

	line_2();						// nezobrazuj hodnotu pokud je menší jak 0.2
	if (pomocna < 0.2) lcd_text("Freq:     ????  ");
	else {							// pokud je větší jak 0.2 potom provede

	lcd_text("Freq:");

	gotoxy(2,10);
	int pomocna2 = pomocna %1000;	// desetinná část (zbytek po dělení 1000)
	lcd_byt(pomocna2/10);

	gotoxy(2,7); 
	lcd_byt(pomocna/1000);			// celočíselná hodnota v kHz

	gotoxy(2,10);
	lcd_text(".");

	gotoxy(2,13);
	lcd_text("kHz");

	gotoxy(2,11);
	if ((pomocna2/10)<10) lcd_text("0");
	}

	

}
