//-------------------- KNIHOVNA pro obsluhu 2x16 LCD displeje-------------------------

/*
		zapojení pro KME Control Board
		
		(LCD displej je připojen na PORT B)

		pin B0, B1 - nepoužit
		pin B2 ---- RS  (Instrukce =0, Data = 1)
		pin B3 ---- Enable (E)
		piny B4 až B7 ----- DB4 - DB7 (DB0 až DB3 uzemněno => logická 0)

*/

// definice parametrů
#define F_CPU 16000000		// definice frekvence krystalu
#define RS 2				// třetí pin portu B(B2)
#define EN 3				// čtvrtý pin portu B(B3)
#define PORT PORTB
#define DDR DDRB

// práce s bity
#define setb(port,pin)    (port |= 1<<pin)    //nastav bit
#define clrb(port,pin)    port &= ~(1<<pin) //nuluj bit

#include <util/delay.h>		// knihovna pro práci s časem

// definice funkcí ovládajících displej
void init_lcd (void);
void lcd_text(char* text);
void lcd_byt  (unsigned char byt);          //napiš bajt)
void lcd_bytN  (unsigned char byt);          //napiš bajt) / no zero
void zapis (unsigned char c);




#if defined LCD //////////////////////////////////////////////////-------------

// makra pro LCD displej
#define cls()		  	  instrukce(0x01);_delay_ms(3)		 //vymaž displej
#define cursor_off()      instrukce(0x0c)				 //vypni kurzor
#define cursor_on()       instrukce(0x0e)				 //zapni kurzor
#define cursor_blink()    instrukce(0x0f)				 //kurzor bliká
#define line_1()	      instrukce(0x80)				 //jdi na řádek 1
#define line_2() 	      instrukce(0xc0)				 //jdi na řádek 2
#define shift_lcd_left()  instrukce(0x18)				 //posuň text doleva
#define shift_lcd_right() instrukce(0x1c)				 //posuň text doprava
//jdi na řádek (lin), sloupec (col):
#define gotoxy(lin,col)   instrukce(64*(lin+1)+(col-1))


void povol (void)
{
		setb(PORT,EN);		// povolovací bit
		_delay_us(1);
		clrb(PORT,EN);		// zakáže bit
		_delay_us(50);
}


// zápis
void zapis (unsigned char c)
{
char temp;
	temp  = c & 0xf0;
	PORT &= 0x0f;
	PORT += temp;
	povol();
	temp  = c & 0x0f;
	temp  = temp << 4;
	PORT &= 0x0f;
	PORT += temp;
	povol();
}

// zapíše instrukci
void instrukce (unsigned char ins)
{
clrb(PORT,RS);
zapis(ins);
}

// Napiš znak na LCD:
void lcd_c(unsigned char dat)
{
setb(PORT,RS);
zapis(dat);
}

//napiš bajt (tři místa bez úvodních nul)
void lcd_byt(unsigned char byt)
{
unsigned char b1,b2=1;

	b1=byt/100;                    //b1=stovky
    if(b1==0) {b2=0; lcd_c(32);}   //byt<100 zobraz mezeru
	else lcd_c(b1+0x30);           //zobraz stovky

    b1=byt%100;                    //zbytek po dělení stem
	byt=b1;
	b1=b1/10;                      //b1=desítky
    if((b1==0) & (b2==0))          //byt<10 zobraz mezeru
	lcd_c(32);
	else lcd_c(b1+0x30);           //zobraz desítky

	b1=byt%10;                     //zbytek po dělení deseti
    lcd_c(b1+0x30);                //zobraz jednotky
 }

void lcd_bytN(unsigned char byt)
{
unsigned char b1,b2=1;

	b1=byt/100;                    //b1=stovky
    if(b1==0) {b2=0; lcd_c(32);}   //byt<100 zobraz mezeru
	else lcd_c(b1+0x30);           //zobraz stovky

    b1=byt%100;                    //zbytek po dělení stem
	byt=b1;
	b1=b1/10;                      //b1=desítky
    if((b1==0) & (b2==0))          //byt<10 zobraz nulu
	lcd_c(48);
	else lcd_c(b1+0x30);           //zobraz desítky

	b1=byt%10;                     //zbytek po dělení deseti
    lcd_c(b1+0x30);                //zobraz jednotky
}

// inicializace LCD displeje
void init_lcd (void)
{
	DDRB |= 0xfc;		// nastaví vše ve směrovém reg. kromě pinů B0 a B1
	clrb(PORT,RS);		
	clrb(PORT,EN);		
	_delay_ms(16);
	PORT |=0x30;
	povol();
	_delay_ms(5);
	povol();
	_delay_ms(6);
	povol();
	clrb(PORT,4);
	povol();
	instrukce(0x28);
	instrukce(0x06);
	instrukce(0x0c);
	instrukce(0x01);
	_delay_ms(3);
}


//napiš string, umístěný v RAM
void lcd_text(char* text)
{
unsigned char i=0,temp;

	do
	{
	temp = text[i];
	if(temp==0) break;             //každý string je ukončený nulou
	lcd_c(temp);
	i++;
	}
	while(temp>0);
}



#endif

