//---------------------------řízení SS motorku pomocí PWM signálu ----------------
#define F_CPU 16000000					// nastavení frekvence krystalu
#include <avr/io.h>						
#include <util/delay.h>
#define LCD                          	// deklarace a vložení knihovny LCD
#include "mojelib1.h"        		 

//hlavičky funkcí-----------------------------------------------------------------
void tlacitka(void);
void zobraz_LCD(void);
void zmena_PWM(void);

//globální proměné----------------------------------------------------------------
int smer = 1;														// smer otáčení 1-vpravo, 0 vlevo
unsigned char PWM [10] = {255,200,195,170,150,140,135,128,115,105};	// hodnoty porovnávací hladiny u PWM
unsigned char DCL [10] = {0,22,24,34,42,46,49,51,56,59};			// naměřené hodnoty z průběhu PWM
int ukazatel = 0;													// určuje prvek v poli PWM

int main (void)
{
	DDRC = 0xff;				// deklarace výstupních a vstupních PORTů
	DDRB = 0xff;
	DDRD= 0b11110000;			// nastavení 4 pinů jako vstupních pro tlačítka
	PORTC = 0b11000010;			// zapnutí LCD displeje	
	PORTB = 0b00000001;			// povolení PWM - na modulku povolí EN bit u IO LM317

	init_lcd();					// inicializace LCD
	cls();
	_delay_ms(10);

	// nastavení časovače ---------------------------------------------------------------
	TCCR1A=0b11000001;			// nastav při komparaci s OCR1A (OCR1A využijeme 
								// pouze 8 bytového průběhu PWM
	TCCR1B=0b00001101;			// nastavena dělička 1024 
	TIMSK=0b00010000;			// nastavení přerušení na porovnání OCR1A s TCNT1
	OCR1AH=0;					// horní polovina porovn. registru 16-bit časovače je prázdná
	OCR1AL=255;					// naplnění porov. registru spodní části 16bit čítače
	

	while(1)					//nekonečná smyčka
	{
		tlacitka();				//vykonání funkce tlačítek
		zobraz_LCD();			//zobrazení rychlosti PWM 

	}

}

void tlacitka (void)
{
	_delay_ms(150);					// pojistka proti rychlému překliknutí
	if ((PIND&0b00000100)==0)		// test stisku 3.tlacitka (žluté)
		{
		if (smer==0)				// nastavení směru otáčení, tedy PWM
		  smer=1;					// smer = 1 na jednu stranu a smer =0 na druhou
		 else smer =0;	

		zmena_PWM();				// pokud změním směr, změňím i rychlost
		}

	if (!smer)						// identifikace směru pomocí LED diody
		PORTD=(PIND|0b00010000);	// nastav LED
	  else
		PORTD=(PIND&0b11101111);	// zhasni LED

    if ((PIND&0b00000001)==0)		// test stisku 1.tlacitka
	  {								// změna PWM modulace k vyššímu
	   if(ukazatel==9)				// pokud dojde na konec nastav opět začátek
	      ukazatel=0;				
	     else ukazatel++;			// inkrementace ukazatele hodnot

		zmena_PWM();				// provede změnu PWM
   		}

	if ((PIND&0b00000010)==0)		// test stisku 2.tlacitka
	    {
	   if(ukazatel==0)				// testuje jestli je na začátku
	      ukazatel=9;				// pokud ano nastaví na konec
	     else ukazatel--;			// odečte ukazatele na pole hodnot
       
	   zmena_PWM();
   		}

}

void zobraz_LCD(void)
{
	gotoxy(1,1);					// výpis na LCD
	lcd_text("Stupen:");
	gotoxy(1,8);
	lcd_c(ukazatel+48);				// výpis ukazatele +48 => odpovídá hodnotě v ASCII tabulce
	gotoxy(1,10);
	lcd_text("f=61Hz");				// frekvence PWM neměná a nastavena na 60,8Hz
	gotoxy(2,1);
	lcd_text("DCL:");				
	gotoxy(2,5);

	if(ukazatel==0) lcd_text("0");				// pokud motor stojí
		else lcd_byt(DCL[ukazatel]);			// zobraz DCL
		// pro oba směry je dáno stejné DCL, i když v jednom směru se hodnoty nepatrně liší

	gotoxy(2,8);
	lcd_text("%");
	gotoxy(2,11);					// vypíše směr otáčení
	if (smer ==1) lcd_text("vlevo");
		else lcd_text("vpravo");
}

void zmena_PWM (void)
{

	if (smer==1)
  		OCR1AL=PWM[ukazatel] ;		//načtení do porovnávací hladiny
	else 
  		{
		if (ukazatel!=0)			// ošetření prudkého roztočení při situaci 255-255=0
  		OCR1AL=255-PWM[ukazatel];		
		else OCR1AL=0;			// hodnota 255 pro obě strany stejná
 		}

		cls();						// při změně hodnoty vymaže displej
		_delay_ms(10);
}
