#include <inttypes.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include "def.h"
static unsigned char lcd_init_8[1]=
{
 0x30,
};
static unsigned char lcd_init_4[3]=
{
0x28,
0x0d,
0x06,
};
static unsigned char lcd_clean[2]=
{
 0x01,
 0x02,
};
void LCD_write (unsigned char *p, int len, char command, char flag)
    {
      while (len--)
            {
          if (flag==0){LCD_read();}
           switch (command)
                  {
                case 0:
                     CLEARBIT(LCD_PORT_D, A);                      // адрес регистра комманд
                    break;
                case 1:
                     SETBIT(LCD_PORT_D, A);                     // адрес регистра данных
                    break;
                }
                CLEARBIT(LCD_PORT_D, WR);                           // операция записи
                SETBIT(LCD_PORT_D, E);                           // строб
                if ((*p & 0x80) == 0x80) SETBIT(LCD_PORT_B, BIT3);
                else CLEARBIT(LCD_PORT_B,BIT3);
                if ((*p & 0x40) == 0x40) SETBIT(LCD_PORT_B, BIT2);
                else CLEARBIT(LCD_PORT_B,BIT2);
                if ((*p & 0x20) == 0x20) SETBIT(LCD_PORT_B, BIT1);
                else CLEARBIT(LCD_PORT_B,BIT1);
                if ((*p & 0x10) == 0x10) SETBIT(LCD_PORT_B, BIT0);
                else CLEARBIT(LCD_PORT_B,BIT0);
                CLEARBIT(LCD_PORT_D, E);                     // сбрасывам строб
                SETBIT(LCD_PORT_D, E);                        // строб
                if ((*p & 0x08) == 0x08) SETBIT(LCD_PORT_B, BIT3);
                else CLEARBIT(LCD_PORT_B,BIT3);
                if ((*p & 0x04) == 0x04) SETBIT(LCD_PORT_B, BIT2);
                else CLEARBIT(LCD_PORT_B,BIT2);
                if ((*p & 0x02) == 0x02) SETBIT(LCD_PORT_B, BIT1);
                else CLEARBIT(LCD_PORT_B,BIT1);
                if ((*p & 0x01) == 0x01) SETBIT(LCD_PORT_B, BIT0);
                else CLEARBIT(LCD_PORT_B,BIT0);
                CLEARBIT(LCD_PORT_D,E);                     // сбрасываем строб
                  p++;                                    // увеличиваем счётчик передаваемых байт
         }
      }
int LCD_read (void)
       {
       unsigned char dataRead=0;
       LCD_DIR  = 0x00;                                    // порт индикатора на вход
        CLEARBIT(LCD_PORT_D, A);                                  // адрес регистра комманд
        SETBIT(LCD_PORT_D, WR);                                    // операция чтения
        SETBIT(LCD_PORT_D, E);                                    // строб
      while(CHECKBIT (LCD_IN, BIT3)) {};                        // ждём флага (0)
        dataRead = (LCD_IN &((BIT3)|(BIT2)|(BIT1)|(BIT0)))<<4;         // читаем верхнюю тетраду
        CLEARBIT(LCD_PORT_D,E);                                 // сбрасываем строб
      SETBIT(LCD_PORT_D, E);                                    // строб
        dataRead |=(int) (LCD_IN &((BIT3)|(BIT2)|(BIT1)|(BIT0)));      // читаем нижнюю тетраду
        CLEARBIT(LCD_PORT_D,E);                                 // сбрасываем строб
      CLEARBIT(LCD_PORT_D,WR);                              // отменяем операцию чтения
      LCD_DIR  = 0xFF;                                    // порт индикатора на выход
      return dataRead;                                    // возвращаем прочтённые данные (если нужны)
      }
void init_LCD (void)
{
 _delay_ms (20);
 LCD_write (lcd_init_8, sizeof(lcd_init_8), comm, no_check_flag);      // 8-ми проводный интерфейс
 _delay_us (40);
 LCD_write (lcd_init_8, sizeof(lcd_init_8), comm, no_check_flag);      // 8-ми проводный интерфейс
 _delay_us (40);
 LCD_write (lcd_init_8, sizeof(lcd_init_8), comm, no_check_flag);      // 8-ми проводный интерфейс
 _delay_us (40);
 LCD_write (lcd_init_4, sizeof(lcd_init_4), comm, check_flag);         // 4-х проводный интерфейс
}
void LCD_clean (void)
{
 LCD_write (lcd_clean, sizeof(lcd_clean), comm, check_flag);         // очистка дисплея и установка курсора в позицию 0
}