
// mojelib1.h

/*
Zapojení LCD displeje 16*1:     deska ZD1 - attiny2313
RS    = PORTB.2	(lcdpin4)
EN    = PORTB.3	(lcdpin6)
DATA4 = PORTB.4	(lcdpin11)
DATA5 = PORTB.5	(lcdpin12)
DATA6 = PORTB.6	(lcdpin13)
DATA7 = PORTB.7	(lcdpin14)
---------------------------------------------------------------------------*/

//přepsat při jiném zapojení displeje: (DATA4-7 vždy na PORT4-7)
#define PORT PORTB
#define DDR  DDRB
#define EN   3
#define RS   2

#define F_CPU 16000000


// 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


// Časové smyčky:
void waitms  (unsigned int c);              // čekej milisekund(max65553):
void waitus  (unsigned int c);              // čekej mikrosekund(max65553):


// Funkce pro UART:
void init_uart (unsigned int baud);         //inicializace UART
unsigned char u_getc( void );               //přijmi znak z UART
void u_putc( char data );                   //napiš znak do UART
void u_puts( char *text );                  //napiš string do UART

// Funkce pro displej:
void init_lcd (void);                       //inicializace
void lcd_instr(unsigned char ins);          //napiš instrukci
void lcd_c    (unsigned char dat);          //napiš znak;
void lcd_byt  (unsigned char byt);          //napiš bajt)
void lcd_text (char* text); 		        //napiš string, umístěný v RAM
void lcd_ftext(const char* text); 			//napiš string, umístěný ve FLASH

#if defined LCD ////////////////////////////////////////////////////////////
#include <avr/pgmspace.h>  // pgm_read_byte()

// Makra pro displej:
#define cls()		  	  lcd_instr(0x01);waitms(3)		 //vymaž displej
#define cursor_off()      lcd_instr(0x0c)				 //vypni kurzor
#define cursor_on()       lcd_instr(0x0e)				 //zapni kurzor
#define cursor_blink()    lcd_instr(0x0f)				 //kurzor bliká
#define line_1()	      lcd_instr(0x80)				 //jdi na řádek 1
#define line_2() 	      lcd_instr(0xc0)				 //jdi na řádek 2
#define shift_lcd_left()  lcd_instr(0x18)				 //posuň text doleva
#define shift_lcd_right() lcd_instr(0x1c)				 //posuň text doprava
//jdi na řádek (lin), sloupec (col):
#define gotoxy(lin,col)   lcd_instr(64*(lin+1)+(col-1))
#define set_CGRAM(adresa)  clrb(PORT,RS); setb(PORT,EN); lcd_instr(64+adresa) 
					// nastaví se na pozici v CG RAM - pro uložení znaku


//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
 }


//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);
}


//napiš string, umístěný ve FLASH
void lcd_ftext(const char* text)
{
unsigned char i=0,temp;

	do
	{
	temp =pgm_read_byte(text+i);   //čti bajt z paměti FLASH
	if(temp==0) break;
	lcd_c(temp);
	i++;
	}
	while(temp>0);
}


void len(void)                     //impuls Enable do LCD
{
	setb(PORT,EN);
	waitus(1);
	clrb(PORT,EN);
	waitus(50);
}


void write(char c)
{
char temp;
	temp  = c & 0xf0;
	PORT &= 0x0f;
	PORT += temp;
	len();
	temp  = c & 0x0f;
	temp  = temp << 4;
	PORT &= 0x0f;
	PORT += temp;
	len();
}


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

// Pošli instrukci do LCD:
void lcd_instr(unsigned char ins)
{
clrb(PORT,RS);
write(ins);
}

// Inicializace LCD ve 4-bitovém módu
void init_lcd(void)
{
	DDR |= 0xf0;
	setb(DDR,RS);
	setb(DDR,EN);
	clrb(PORT,RS);
	clrb(PORT,EN);
	waitms(16);
	PORT |= 0x30;  //0000 0011
	len();
	waitms(5);
	len();
	waitus(6);
	len();
	clrb(PORT,4);
	len();
	lcd_instr(0x28);
	lcd_instr(0x06);
	lcd_instr(0x0c);
	lcd_instr(0x01);
	waitms(3);
}
#endif //////////////////////////////////////////////////////////////////////
//defined LCD

#if defined UART ////////////////////////////////////////////////////////////

// UART inicializace
void init_uart (unsigned int baud)
{
if(baud==1200) {UBRRH=2;UBRRL=  8;}
if(baud==2400) {UBRRH=1;UBRRL=  3;}
if(baud==4800) {UBRRH=0;UBRRL=129;}
if(baud==9600) {UBRRH=0;UBRRL= 64;}
UCSRB=0x18;    // příjem zapnut, vysílání zapnuto
UCSRC=0x06;    // 8-bit, 1 stopbit, bez parity
}


// UART pošli znak:
void u_putc( char data )
{

while ( !( UCSRA & (1<<UDRE)) )     // Wait for empty transmit buffer
;
UDR = data;                         // Put data into buffer, sends the data
}


// UART pošli string:
void u_puts( char *text )
{
unsigned char i=0,temp;

	do
	{
	temp = text[i];
	if(temp==0) break;
	u_putc(temp);
	i++;
	}
	while(temp>0);
}

// UART přijmi znak:
unsigned char u_getc( void )
{

while ( !(UCSRA & (1<<RXC)) )       // Wait for data to be received
;
return UDR;                         // Get and return received data from buffer
}

#endif //////////////////////////////////////////////////////////////////////
//defined UART


//čekej milisekund:
unsigned char reg21 = F_CPU / 60000;    // F_CPU = frekv. oscilátoru [Hz],
                                        // (vnitřní konstanta překladače)
void waitms  (unsigned int c)
{
	asm("push	r20");
	asm("push	r21");
asm("_Wms0:");
	asm("ldi	r20,0x14");
asm("_Wms1:");
	asm("lds	r21,reg21");
asm("_Wms2:");
	asm("dec	r21");
	asm("brne	_Wms2");
	asm("dec		r20");
	asm("brne	_Wms1");
	asm("dec	r24");
	asm("brne	_Wms0");
	asm("dec	r25");
	asm("brpl	_Wms0");
	asm("pop   	r21");
	asm("pop   	r20");
}


//čekej mikrosekund:
unsigned char reg20 = F_CPU / 6000000 + 1;
void waitus(unsigned int c)
{
	asm("push	r20");
asm("_wus0:");
	asm("lds	r20,reg20");  // 1-6MHz: r20=1  6-12MHz: r20=2
asm("_wus1:");
	asm("dec	r20");
	asm("brne	_wus1");
	asm("dec	r24");
	asm("brne	_wus0");
	asm("dec	r25");
	asm("brpl	_wus0");
	asm("pop	r20");
}

//endfile

