/*****************************************************
This program was produced by the
CodeWizardAVR V2.03.8a Evaluation
Automatic Program Generator
© Copyright 1998-2008 Pavel Haiduc, HP InfoTech s.r.l.
http://www.hpinfotech.com

Project : 
Version : 
Date    : 05.11.2008
Author  : Freeware, for evaluation and non-commercial use only
Company : 
Comments: 


Chip type           : ATmega16
Program type        : Application
Clock frequency     : 16,000000 MHz
Memory model        : Small
External RAM size   : 0
Data Stack size     : 256
*****************************************************/

#include <mega16.h>
#include <spi.h>
#include <delay.h>
#include <stdio.h>
#include <mem.h>

#define RES PORTB.1 // вывод нокиевского экрана - ресет - очень нужный
#define DC  PORTB.0  // вывод "Команда-Данные" инверсный - тож очень нужный

// com портный ввод по прерыванию
#define RXB8 1
#define TXB8 0
#define UPE 2
#define OVR 3
#define FE 4
#define UDRE 5
#define RXC 7

#define FRAMING_ERROR (1<<FE)
#define PARITY_ERROR (1<<UPE)
#define DATA_OVERRUN (1<<OVR)
#define DATA_REGISTER_EMPTY (1<<UDRE)
#define RX_COMPLETE (1<<RXC)

// USART Receiver buffer
#define RX_BUFFER_SIZE 8
char rx_buffer[RX_BUFFER_SIZE];

#if RX_BUFFER_SIZE<256
unsigned char rx_wr_index,rx_rd_index,rx_counter;
#else
unsigned int rx_wr_index,rx_rd_index,rx_counter;
#endif

// This flag is set on USART Receiver buffer overflow
bit rx_buffer_overflow;
bit below;  // идентификатор отрицательности
bit ExtRep; // идентификатор необходимости скидывать скретчпады в ком порт

// 1 Wire Bus functions
#asm
.equ __w1_port=0x18 ;PORTB
   .equ __w1_bit=3
#endasm

// DS1820 Temperature Sensor functions
//#include <ds18b20.h> // это включать вместо следущей если хочется супер точность(пробывал - в эмуле не работает)
#include <1wire.h>
#include <ds18b20.h>

// maximum number of DS1820 devices
// connected to the 1 Wire bus
#define MAX_DS1820 5
// number of DS1820 devices
// connected to the 1 Wire bus
unsigned char devices; //Это кол-во даччиков температуры 

// DS1820 devices ROM code storage area,
// 9 bytes are used for each device
// (see the w1_search function description in the help)
unsigned char rom_codes[MAX_DS1820][9];
int motor_step = 0;      // состояние шагового мотора

eeprom char mem_contr=56; // контрастность экранчика
eeprom unsigned int WaitDS = 60; // сколько десятков миллисекунд ждать окончания преобразования ДСками(чем больше тем дольше :)

void lcd_clear(void);


/*
//табличка расчета CRC
flash unsigned char CRCTable[256] = {
        0, 94, 188, 226, 97, 63, 221, 131, 194, 156, 126, 32, 163, 253, 31, 65,
        157, 195, 33, 127, 252, 162, 64, 30, 95, 1, 227, 189, 62, 96, 130, 220,
        35, 125, 159, 193, 66, 28, 254, 160, 225, 191, 93, 3, 128, 222, 60, 98,
        190, 224, 2, 92, 223, 129, 99, 61, 124, 34, 192, 158, 29, 67, 161, 255,
        70, 24, 250, 164, 39, 121, 155, 197, 132, 218, 56, 102, 229, 187, 89, 7,
        219, 133, 103, 57, 186, 228, 6, 88, 25, 71, 165, 251, 120, 38, 196, 154,
        101, 59, 217, 135, 4, 90, 184, 230, 167, 249, 27, 69, 198, 152, 122, 36,
        248, 166, 68, 26, 153, 199, 37, 123, 58, 100, 134, 216, 91, 5, 231, 185,
        140, 210, 48, 110, 237, 179, 81, 15, 78, 16, 242, 172, 47, 113, 147,205,
        17, 79, 173, 243, 112, 46, 204, 146, 211, 141, 111, 49, 178, 236, 14, 80,
        175, 241, 19, 77, 206, 144, 114, 44, 109, 51, 209, 143, 12, 82, 176, 238,
        50, 108, 142, 208, 83, 13, 239, 177, 240, 174, 76, 18, 145, 207, 45, 115,
        202, 148, 118, 40, 171, 245, 23, 73, 8, 86, 180, 234, 105, 55, 213, 139,
        87, 9, 235, 181, 54, 104, 138, 212, 149, 203, 41, 119, 244, 170, 72, 22,
        233, 183, 85, 11, 136, 214, 52, 106, 43, 117, 151, 201, 74, 20, 246, 168,
        116, 42, 200, 150, 21, 75, 169, 247, 182, 232, 10, 84, 215, 137, 107, 53};
*/

// табличка шрифта
flash char table[546] = {                                                      
     0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000 ,   // sp
     0b00000000, 0b00000000, 0b01011111, 0b00000000, 0b00000000, 0b00000000 ,   // !
     0x00, 0x07, 0x00, 0x07, 0x00 ,0x00 ,   // "
     0x14, 0x7f, 0x14, 0x7f, 0x14 ,0x00 ,   // #
     0x24, 0x2a, 0x7f, 0x2a, 0x12 ,0x00 ,   // $
     0xc4, 0xc8, 0x10, 0x26, 0x46 ,0x00 ,   // %
     0x36, 0x49, 0x55, 0x22, 0x50 ,0x00 ,   // &
     0x00, 0x05, 0x03, 0x00, 0x00 ,0x00 ,   // '
     0x00, 0x1c, 0x22, 0x41, 0x00 ,0x00 ,   // (
     0x00, 0x41, 0x22, 0x1c, 0x00 ,0x00 ,   // )
     0x14, 0x08, 0x3E, 0x08, 0x14 ,0x00 ,   // *
     0x08, 0x08, 0x3E, 0x08, 0x08 ,0x00 ,   // +
     0x00, 0x00, 0x50, 0x30, 0x00 ,0x00 ,   // ,
     0x10, 0x10, 0x10, 0x10, 0x10 ,0x00 ,   // -
     0x00, 0x60, 0x60, 0x00, 0x00 ,0x00 ,   // .
     0x20, 0x10, 0x08, 0x04, 0x02 ,0x00 ,   // /
     0b00110110, 0b01000001, 0b01000001, 0b01000001, 0b00110110, 0b00000000 ,   // 0
     0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00110110, 0b00000000 ,   // 1
     0b00110000, 0b01001001, 0b01001001, 0b01001001, 0b00000110, 0b00000000 ,   // 2
     0b00000000, 0b01001001, 0b01001001, 0b01001001, 0b00110110, 0b00000000 ,   // 3
     0b00000110, 0b00001000, 0b00001000, 0b00001000, 0b00110110, 0b00000000 ,   // 4
     0b00000110, 0b01001001, 0b01001001, 0b01001001, 0b00110000, 0b00000000 ,   // 5
     0b00110110, 0b01001001, 0b01001001, 0b01001001, 0b00110000, 0b00000000 ,   // 6
     0b00000000, 0b00000001, 0b00000001, 0b00000001, 0b00110110, 0b00000000 ,   // 7
     0b00110110, 0b01001001, 0b01001001, 0b01001001, 0b00110110, 0b00000000 ,   // 8
     0b00000110, 0b01001001, 0b01001001, 0b01001001, 0b00110110, 0b00000000 ,   // 9
     0x00, 0x36, 0x36, 0x00, 0x00 ,0x00 ,   // :
     0x00, 0x56, 0x36, 0x00, 0x00 ,0x00 ,   // ;
     0x08, 0x14, 0x22, 0x41, 0x00 ,0x00 ,   // <
     0x14, 0x14, 0x14, 0x14, 0x14 ,0x00 ,   // =
     0x00, 0x41, 0x22, 0x14, 0x08 ,0x00 ,   // >
     0x02, 0x01, 0x51, 0x09, 0x06 ,0x00 ,   // ?
     0x32, 0x49, 0x59, 0x51, 0x3E ,0x00 ,   // @
     0x7E, 0x11, 0x11, 0x11, 0x7E ,0x00 ,   // A
     0x7F, 0x49, 0x49, 0x49, 0x36 ,0x00 ,   // B
     0x3E, 0x41, 0x41, 0x41, 0x22 ,0x00 ,   // C
     0x7F, 0x41, 0x41, 0x22, 0x1C ,0x00 ,   // D
     0x7F, 0x49, 0x49, 0x49, 0x41 ,0x00 ,   // E
     0x7F, 0x09, 0x09, 0x09, 0x01 ,0x00 ,   // F
     0x3E, 0x41, 0x49, 0x49, 0x7A ,0x00 ,   // G
     0x7F, 0x08, 0x08, 0x08, 0x7F ,0x00 ,   // H
     0x00, 0x41, 0x7F, 0x41, 0x00 ,0x00 ,   // I
     0x20, 0x40, 0x41, 0x3F, 0x01 ,0x00 ,   // J
     0x7F, 0x08, 0x14, 0x22, 0x41 ,0x00 ,   // K
     0x7F, 0x40, 0x40, 0x40, 0x40 ,0x00 ,   // L
     0x7F, 0x02, 0x0C, 0x02, 0x7F ,0x00 ,   // M
     0x7F, 0x04, 0x08, 0x10, 0x7F ,0x00 ,   // N
     0x3E, 0x41, 0x41, 0x41, 0x3E ,0x00 ,   // O
     0x7F, 0x09, 0x09, 0x09, 0x06 ,0x00 ,   // P
     0x3E, 0x41, 0x51, 0x21, 0x5E ,0x00 ,   // Q
     0x7F, 0x09, 0x19, 0x29, 0x46 ,0x00 ,   // R
     0x46, 0x49, 0x49, 0x49, 0x31 ,0x00 ,   // S
     0x01, 0x01, 0x7F, 0x01, 0x01 ,0x00 ,   // T
     0x3F, 0x40, 0x40, 0x40, 0x3F ,0x00 ,   // U
     0x1F, 0x20, 0x40, 0x20, 0x1F ,0x00 ,   // V
     0x3F, 0x40, 0x38, 0x40, 0x3F ,0x00 ,   // W
     0x63, 0x14, 0x08, 0x14, 0x63 ,0x00 ,   // X
     0x07, 0x08, 0x70, 0x08, 0x07 ,0x00 ,   // Y
     0x61, 0x51, 0x49, 0x45, 0x43 ,0x00 ,   // Z
     0x00, 0x7F, 0x41, 0x41, 0x00 ,0x00 ,   // [
     0x55, 0x2A, 0x55, 0x2A, 0x55 ,0x00 ,   // 55
     0x00, 0x41, 0x41, 0x7F, 0x00 ,0x00 ,   // ]
     0x04, 0x02, 0x01, 0x02, 0x04 ,0x00 ,   // ^
     0x40, 0x40, 0x40, 0x40, 0x40 ,0x00 ,   // _
     0x00, 0x01, 0x02, 0x04, 0x00 ,0x00 ,   // '
     0x20, 0x54, 0x54, 0x54, 0x78 ,0x00 ,   // a
     0x7F, 0x48, 0x44, 0x44, 0x38 ,0x00 ,   // b
     0x38, 0x44, 0x44, 0x44, 0x20 ,0x00 ,   // c
     0x38, 0x44, 0x44, 0x48, 0x7F ,0x00 ,   // d
     0x38, 0x54, 0x54, 0x54, 0x18 ,0x00 ,   // e
     0x08, 0x7E, 0x09, 0x01, 0x02 ,0x00 ,   // f
     0x0C, 0x52, 0x52, 0x52, 0x3E ,0x00 ,   // g
     0x7F, 0x08, 0x04, 0x04, 0x78 ,0x00 ,   // h
     0x00, 0x44, 0x7D, 0x40, 0x00 ,0x00 ,   // i
     0x20, 0x40, 0x44, 0x3D, 0x00 ,0x00 ,   // j
     0x7F, 0x10, 0x28, 0x44, 0x00 ,0x00 ,   // k
     0x00, 0x41, 0x7F, 0x40, 0x00 ,0x00 ,   // l
     0x7C, 0x04, 0x18, 0x04, 0x78 ,0x00 ,   // m
     0x7C, 0x08, 0x04, 0x04, 0x78 ,0x00 ,   // n
     0x38, 0x44, 0x44, 0x44, 0x38 ,0x00 ,   // o
     0x7C, 0x14, 0x14, 0x14, 0x08 ,0x00 ,   // p
     0x08, 0x14, 0x14, 0x18, 0x7C ,0x00 ,   // q
     0x7C, 0x08, 0x04, 0x04, 0x08 ,0x00 ,   // r
     0x48, 0x54, 0x54, 0x54, 0x20 ,0x00 ,   // s
     0x04, 0x3F, 0x44, 0x40, 0x20 ,0x00 ,   // t
     0x3C, 0x40, 0x40, 0x20, 0x7C ,0x00 ,   // u
     0x1C, 0x20, 0x40, 0x20, 0x1C ,0x00 ,   // v
     0x3C, 0x40, 0x30, 0x40, 0x3C ,0x00 ,   // w
     0x44, 0x28, 0x10, 0x28, 0x44 ,0x00 ,   // x
     0x0C, 0x50, 0x50, 0x50, 0x3C ,0x00 ,   // y
     0x44, 0x64, 0x54, 0x4C, 0x44 ,0x00 ,   // z      
     };

unsigned char a2[30]; //Временная строка для вывода на экран
unsigned char temp=0; // просто временная переменная для всех случаев
int i=1;              // переменная для циклов

//переменные для RC5

// подключение тсопа
#define tsop PINB.2
 
//Счетчик битов RC5
unsigned char sct_bit = 0;

unsigned char cnt_bit = 0;              //счетчик принятых бит
unsigned char code [14];                //принятый код

unsigned char counter = 0;              //"тики" таймера

eeprom unsigned char l_min = 80;                     //диапазон для "длинного" (long) интервала в посылке, в "тиках" таймера, 1,28..2,176мс 
eeprom unsigned char l_max = 136;
eeprom unsigned char s_min = 44;                     //диапазон для "короткого" (short) интервала в посылке, в "тиках" таймера, 0,704..1,088мс
eeprom unsigned char s_max = 68;

bit state =  0;                                 //флаг состояния линии приема
bit error = 0;                                  //флаг ошибки

//переменные структуры посылки, всего 14 бит
unsigned char startbit1 = 0;                    //первый стартовый бит, д.б. = 1
unsigned char startbit2 = 0;                    //второй стартовый бит, д.б. = 1                    
unsigned char toggle = 0;                       //триггерный бит, инвертируется в посылке при нажатии кнопки, при удержании - не инв.!
unsigned char address = 0;                      //адрес устройства, 5 бит
unsigned char command = 0;                      //команда (данные), 6 бит

// конец переменных пультика 

     
// Declare your global variables here

// USART Receiver interrupt service routine
interrupt [USART_RXC] void usart_rx_isr(void)
{
char status,data;
status=UCSRA;
data=UDR;
if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0)
   {
   rx_buffer[rx_wr_index]=data;
   if (++rx_wr_index == RX_BUFFER_SIZE) rx_wr_index=0;
   if (++rx_counter == RX_BUFFER_SIZE)
      {
      rx_counter=0;
      rx_buffer_overflow=1;
      };
   };
}

#ifndef _DEBUG_TERMINAL_IO_
// Get a character from the USART Receiver buffer
#define _ALTERNATE_GETCHAR_
#pragma used+
char getchar(void)
{
char data;
while (rx_counter==0);
data=rx_buffer[rx_rd_index];
if (++rx_rd_index == RX_BUFFER_SIZE) rx_rd_index=0;
#asm("cli")
--rx_counter;
#asm("sei")
return data;
}
#pragma used-
#endif

struct ds_scratch_pad_struct
       {
       unsigned char temp_lsb,temp_msb,
                temp_high,temp_low,
                conf_register,
                res1,
                res2,
                res3,
                crc;
       } ds_scratch_pad;
 
char x = 1;

char y = 1;
                                               
void port(void)
{        
#asm("cli");
// Declare your local variables here
// Input/Output Ports initialization
// Port A initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T 
PORTA=0x00;
DDRA=0x00;

// Port B initialization
// Func7=Out Func6=Out Func5=Out Func4=Out Func3=Out Func2=In Func1=Out Func0=Out 
// State7=0 State6=0 State5=0 State4=0 State3=0 State2=P State1=0 State0=0 
PORTB=0x04;
DDRB=0xFB;

// Port C initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T 
PORTC=0x00;
DDRC=0xFF;

// Port D initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T 
PORTD=0x00;
DDRD=0x00;


// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 62,500 kHz
// Mode: Normal top=FFh
// OC0 output: Disconnected
TCCR0=0x04;
TCNT0=0x00;
OCR0=0x00;


// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer 1 Stopped
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer 1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer 2 Stopped
// Mode: Normal top=FFh
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;

// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
// INT2: On
// INT2 Mode: Falling Edge
GICR|=0x20;
MCUCR=0x00;
MCUCSR=0x00;
GIFR=0x20;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x01;

// USART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART Receiver: On
// USART Transmitter: On
// USART Mode: Asynchronous
// USART Baud Rate: 9600
UCSRA=0x00;
UCSRB=0x98;
UCSRC=0x86;
UBRRH=0x00;
UBRRL=0x67;


// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;

#asm("sei");

}

void writedata(char data)
{
DC = 1;
spi(data);
}
void writecomm(char comm)
{
DC = 0;
spi(comm);
}
void lcd_init(void)
{
RES=0;       
delay_ms(100);       
RES=1;       
delay_ms(100); 
SPCR=0x50;       
SPSR=0x00;           
writecomm(0x21); // LCD Extended Commands.
//writecomm(0xC8); // Set LCD Vop (Contrast).
writecomm(0b10000000|mem_contr);
writecomm(0x06); // Set Temp coefficent. 
writecomm(0x13); // LCD bias mode 1:48.
writecomm(0b01000101); //Переводим СКРОЛЛИНГ вверх на пол строки - вторая строка = первая на экране
writecomm(0x20); // LCD Standard Commands, Horizontal addressing mode.
writecomm(0x0C); // LCD in normal mode.

} 
void lcd_gotoxy(char x, char y)
{
writecomm((0x40|(y+1)));   // Y axis 
writecomm((0x80|x));   // X axis
}
void lcd_clear_row(char y)
{
unsigned int i;
lcd_gotoxy(0,y);
for(i = 84; i > 0; i--){writedata(0x00);};
}
void lcd_clear(void)
{
unsigned int i;
lcd_gotoxy(0,0);
for(i = 700; i > 0; i--){writedata(0x00);};
}
void lcd_putchar(char character)
{
    int tablept, count, char_column;
    if ((character<0x20)||(character>0x7f)) {return;}              
    tablept = ((6*character) - 192);                    

    for (count=5;count>0;count--)                            
    {
        char_column = table[tablept];
        writedata(char_column);
        tablept++;
    }
    writedata(0x00);                                        
}
void lcd_putstr(const char *s)
{
    while(*s) {lcd_putchar(*s++);}                                
}

void ComInterface(void)
{
  // COM портовая менюшка
      
  while(rx_counter){
    temp = getchar();
    putchar(temp);
    putsf("\n\r");
    if((temp=='c')||(temp=='C'))
    {
        // ввели С - типа идентификатор конфигурирования
        putsf("Configure mode\n\r");
        putsf("1----Setting contrast\n\r");
        putsf("2----Setting bias\n\r");
        putsf("3----ReSetting LCD\n\r");
        putsf("4----ReScan 1Wire\n\r");
        if(ExtRep)
            putsf("5----Turn off ExtRep\n\r");
        else
            putsf("5----Turn on ExtRep\n\r");
        putsf("6----Setting WaitDS\n\r");
        
        putsf("7----Setting l_min\n\r");
        putsf("8----Setting l_max\n\r");
        putsf("9----Setting s_min\n\r");
        putsf("0----Setting s_max\n\r");                                           
        putsf("*----Clear LCD\n\r"); 
            
        switch(getchar()){
           case '*':
                lcd_clear();
                x=1;
                y=1;
                getchar();
                break;
                
           case '1':
                putsf("\n\r -- Setting the contrast \n\r");
               //1 - Настройка кинтраста
               // будем получать 0 или 1 побитово 
               i = mem_contr;
               temp = getchar();
               while((temp=='+')||(temp=='-')){
                    if(temp=='+')
                    {
                        i=i+1;
                    }
                    if(temp=='-')
                    {
                        i=i-1;
                    }
                    if(i<=0) i=1;
                    if(i>0b01111111) i=0b01001000;
                    writecomm(0x21); // LCD Extended Commands.
                    writecomm(0b10000000|i); // Вставляем нашу контрастность
                    writecomm(0x20);
                    sprintf(a2, "contrast = %i \n\r",i); 
                    puts(a2);
                    temp = getchar();                        
               }  
               // сохраняем контраст в еепром
               mem_contr = i;                         
               break;
           case '2':
               PORTC = 0b10010000;
               break;
           case '3':
               lcd_init();
               break;
           case '4':
               devices=w1_search(0xf0,rom_codes);                 
               break;
           case '5':
                if(ExtRep)
                    ExtRep = 0;
                else
                    ExtRep = 1;
                break;
           case '6':
                putsf("\n\r -- Setting the timeout for Temperature conversion of the DS18B20 -- \n\r");
               //1 - Настройка задержки
               // будем получать 0 или 1 побитово 
               i = WaitDS;
               temp = getchar();
               while((temp=='+')||(temp=='-')){
                    if(temp=='+')
                    {
                        i=i+1;
                    }
                    if(temp=='-')
                    {
                        i=i-1;
                    }
                    if(i<=0) i=1;
                    if(i>0b01111111) i=0b01001000;
                    sprintf(a2, "Wait in millisec = %i x 10ms \n\r",i); 
                    puts(a2);
                    temp = getchar();                        
               }  
               // сохраняем WaitDS в еепром
               WaitDS = i;                         
               break;
               
               // настройки ир
           case '7':
                putsf("\n\r -- Setting the l_min -- \n\r");
               //1 - Настройка задержки
               // будем получать 0 или 1 побитово 
               i = l_min;
               temp = getchar();
               while((temp=='+')||(temp=='-')){
                    if(temp=='+')
                    {
                        i=i+1;
                    }
                    if(temp=='-')
                    {
                        i=i-1;
                    }
                    if(i<=0) i=1;
                    if(i>0b01111111) i=0b01001000;
                    sprintf(a2, "Wait in timer ticks = %i \n\r",i); 
                    puts(a2);
                    temp = getchar();                        
               }  
               // сохраняем WaitDS в еепром
               l_min = i;                         
               break;
           case '8':
                putsf("\n\r -- Setting the timeout l_max -- \n\r");
               //1 - Настройка задержки
               // будем получать 0 или 1 побитово 
               i = l_max;
               temp = getchar();
               while((temp=='+')||(temp=='-')){
                    if(temp=='+')
                    {
                        i=i+1;
                    }
                    if(temp=='-')
                    {
                        i=i-1;
                    }
                    if(i<=0) i=1;
                    if(i>0b01111111) i=0b01001000;
                    sprintf(a2, "Wait in timer ticks = %i \n\r",i); 
                    puts(a2);
                    temp = getchar();                        
               }  
               // сохраняем WaitDS в еепром
               l_max = i;                         
               break;
           case '9':
                putsf("\n\r -- Setting the timeout s_min -- \n\r");
               //1 - Настройка задержки
               // будем получать 0 или 1 побитово 
               i = s_min;
               temp = getchar();
               while((temp=='+')||(temp=='-')){
                    if(temp=='+')
                    {
                        i=i+1;
                    }
                    if(temp=='-')
                    {
                        i=i-1;
                    }
                    if(i<=0) i=1;
                    if(i>0b01111111) i=0b01001000;
                    sprintf(a2, "Wait in timer ticks = %i \n\r",i); 
                    puts(a2);
                    temp = getchar();                        
               }  
               // сохраняем WaitDS в еепром
               s_min = i;                         
               break;
           case '0':
                putsf("\n\r -- Setting the timeout s_max -- \n\r");
               //1 - Настройка задержки
               // будем получать 0 или 1 побитово 
               i = s_max;
               temp = getchar();
               while((temp=='+')||(temp=='-')){
                    if(temp=='+')
                    {
                        i=i+1;
                    }
                    if(temp=='-')
                    {
                        i=i-1;
                    }
                    if(i<=0) i=1;
                    if(i>0b01111111) i=0b01001000;
                    sprintf(a2, "Wait in timer ticks = %i \n\r",i); 
                    puts(a2);
                    temp = getchar();                        
               }  
               // сохраняем WaitDS в еепром
               s_max = i;                         
               break;
           }
        putsf("\n\r Continuing normal cycle\n\r");
    }         
  }
}

// External Interrupt 2 service routine - отработка тсопа
interrupt [EXT_INT2] void ext_int2_isr(void)
    {
    PORTC.0=1;
    counter = TCNT0;                        //сохраяем значение таймера-счетчика
    
    /*
    // типа вывод таймингов
    
    lcd_gotoxy(x, y-1);
    sprintf(a2, "%i",counter);
    lcd_putstr(a2);
    
    x+=14;
    if(x>=84)
    {
        y+=1;
        x=1;
    }
    if(y>=7)
    {
        y=1;
        x=1;
    }
    
    */
    TCNT0 = 0x00;                           //обнуляем таймер
    error = 1;                              //поставили ошибку - потом сбросим в теле, если все ок
               
    if (cnt_bit == 0)                       //старт посылки   
            {
            TCCR0 = 0x04;                           //запускаем таймер, частота 31250кГц (или надо править диапазоны тиков для интервалов)
            code [cnt_bit] = !tsop;                 //записываем бит кода, PIND.2 - входная нога, прерывание 0
            cnt_bit++;                              //увеличиваем счетчик принятых бит
            state = 1;                              //ставим флаг, т.к. была 1
            }
                  
            else                                        //в других случаях (не первое срабатывание прерывания)
                    {
                    if ((counter>s_min) && (counter<s_max)) //проверка короткого промежутка
                            {
                            if (state)                      //если была 1
                                    {
                                    state = 0;              //обнуляем состояние
                                    error = 0;              //и ошибку, т.к. все корректно
                                    }
                                    else                    //если был 0
                                            {
                                            state = 1;                      //ставим флаг, т.к. теперь - 1
                                            code[cnt_bit] = !tsop;          //записываем данные - состояние линии
                                            cnt_bit++;                      //увеличиваем счетчик приема
                                            error=0;                        //обнуляем ошибку, т.к. все корректно
                                            };
                            };     
                   
                    if ((counter>l_min) && (counter<l_max)) //проверка длинного промежутка
                            {
                            code[cnt_bit] = !tsop;        //записываем данные - состояние линии
                            cnt_bit++;                      //увеличиваем счетчик приема
                            error = 0;                      //обнуляем ошибку, т.к. все корректно
                            };
                                                  
                    if (error == 1)                         //если не попали ни в один из промежутков, то 
                            {
                            char i = 0;                     //внутренняя переменная
                                
                            TCCR0 = 0x00;                   //останавливаем таймер
                            TCNT0 = 0x00;                   //обнуляем таймер
                            counter = 0;                    //обнуляем счетчик
                            cnt_bit = 0;                    //обнуляем счетчик принятых бит
                            for (i=0; i<14; i++) code[i]=0; //обнуляем массив принятого кода
                            };
                   
                    if (cnt_bit == 14)                      //если приняли все 14 бит
                            {
                            char i = 0;                     //внутренняя переменная
                            TCCR0 = 0x00;                   //останавливаем таймер
                            TCNT0 = 0x00;;                  //обнуляем таймер
                            cnt_bit = 0;                    //обнуляем счетчик принятых бит
                                
                            startbit1 = code[0];            //первый стартовый бит
                            startbit2 = code[1];            //второй стартовый бит
                            toggle = code[2];               //триггер-бит
                                                            //формируем переменные адреса и команды
                            address = (code[3] << 4)|(code[4] << 3)|(code[5] << 2)|(code[6] << 1)|code[7];                    
                            command = (code[8] << 5)|(code[9] << 4)|(code[10] << 3 )|(code[11] << 2)|(code[12] << 1)|code[13];
                            
                            lcd_clear_row(0);
                            lcd_gotoxy(1, 0);
                            sprintf(a2, "%i",address);
                            lcd_putstr(a2);
                            
                            lcd_clear_row(0);
                            lcd_gotoxy(1, 1);
                            sprintf(a2, "%i",command);
                            lcd_putstr(a2);
                                     
                            for (i=0; i<14; i++) code[i]=0; //обнуляем массив принятого кода
                            };
                    }; 
    PORTC.0=0;                                                                               
    }

// Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
        char i = 0;                     //внутренняя переменная
        
        TCCR0 = 0x00;                   //останавливаем таймер
        TCNT0 = 0x00;                   //обнуляем таймер
        counter = 0;                    //обнуляем счетчик
        cnt_bit = 0;                    //обнуляем счетчик принятых бит
        for (i=0; i<14; i++) code[i]=0; //обнуляем массив принятого кода
}

void main(void)
{
// Declare your local variables here
int CurrDev = 1;
float ds_temp; // если даччик тупенький и float если высокоточный

port();       // настраиваем порты

// ds1820_init();// инициализируем термометры
//devices=w1_search(DS18B20_SEARCH_ROM_CMD,rom_codes); // это включать при необх повышенной точности
lcd_init();   // инициируем нокиевый экран
lcd_clear();  // чистим его
lcd_gotoxy(1,3);
sprintf(a2, "Initialising..");
lcd_putstr(a2);
puts(a2);
putsf("\n\r");
    
do{
    devices=w1_search(0xf0,rom_codes);
    lcd_gotoxy(1,5);
    sprintf(a2, "%i DEV(S)DET.",devices);
    lcd_putstr(a2);
    lcd_gotoxy(1,6);
    sprintf(a2, "Still search..",devices);
    lcd_putstr(a2);
}while(devices==0);
lcd_clear_row(6); 

for(i=0;i<devices;i++)
{     
    if(!ds18b20_init(&rom_codes[i][0],25,35,DS18B20_12BIT_RES))
    {
        lcd_clear();
        lcd_gotoxy(5,0);
        sprintf(a2, "Er.init DS %i", &rom_codes[i][0]);
        lcd_putstr(a2);
        //delay_ms(1000);        
    }          
}
lcd_clear();
sprintf(a2, "N3310 MonitoR");
lcd_gotoxy(0,0);  
lcd_putstr(a2);
puts(a2);
putsf("\n\r");
lcd_gotoxy(0,1); 
sprintf(a2, "LeXX LTD & Co.");
lcd_putstr(a2);
puts(a2);
putsf("\n\r");
printf("DS`s devices find = %i\n\r", devices);

while (1)
      {
      
      // проверяем стек COM порта
      ComInterface();
      
      w1_init();
      w1_write(0b11001100); // SkipRom
      w1_write(0b01000100); // Convert T
      
      // теперь сильная подтяжка
      PORTB|=0b00100000;
      DDRB|=0b00100000;
      
      temp=WaitDS;
      for(i=0;i<=temp;i++)
      {
        delay_ms(10); // ждем завершения конверсии
      }
      
      // теперь отпускаем
             
          for (i=0;i<devices;i++)
          {
              lcd_gotoxy(75,2+i);
              sprintf(a2, "<");
              lcd_putstr(a2);
              
              // читаем скретчпад в структуру __ds18b20_scratch_pad  (адрес 0108h//0176h длина 9 байт)
              ds18b20_read_spd(&rom_codes[i][0]); 
              
              // копируем полученные результаты в нашу струткуру ds_scratch_pad (адрес 015Ch//01DFh)
              for(CurrDev = 0;CurrDev<=9;CurrDev++)
              {
                    pokeb(CurrDev+0x01DF, peekb(CurrDev+0x0176));
              }
              
              if(ExtRep)
              {
                  // кидаем строчки в com порт 
                  puts(&rom_codes[i][0]);
                  puts(&rom_codes[i][1]);
                  puts(&rom_codes[i][2]);
                  puts(&rom_codes[i][3]);
                  puts(&rom_codes[i][4]);
                  puts(&rom_codes[i][5]);
                  puts(&rom_codes[i][6]);
                  puts(&rom_codes[i][7]);
                  puts(&rom_codes[i][8]);
                  putsf("\n\r");
                                    
                  printf("temp_lsb = %i \n\r" ,ds_scratch_pad.temp_lsb); 
                  //puts(a2);
                  printf("temp_msb = %i \n\r" ,ds_scratch_pad.temp_msb); 
                  //puts(a2);
                  printf("temp_high = %i \n\r" ,ds_scratch_pad.temp_high); 
                  //puts(a2);
                  printf("temp_low = %i \n\r" ,ds_scratch_pad.temp_low); 
                  //puts(a2);
                  printf("conf_register = %i \n\r" ,ds_scratch_pad.conf_register); 
                  //puts(a2);
                  printf("res1 = %i \n\r" ,ds_scratch_pad.res1); 
                  //puts(a2);
                  printf("res2 = %i \n\r" ,ds_scratch_pad.res2); 
                  //puts(a2);
                  printf("res3 = %i \n\r" ,ds_scratch_pad.res3); 
                  //puts(a2);
                  printf("crc = %i \n\r" ,ds_scratch_pad.crc); 
                  //puts(a2);
              }
              
              /*
              // проверяем CRC и если не сходится - пишем ошибку
              temp = 0;
              temp = CRCTable[temp^ds_scratch_pad.temp_lsb];
              temp = CRCTable[temp^ds_scratch_pad.temp_msb];
              temp = CRCTable[temp^ds_scratch_pad.temp_high];
              temp = CRCTable[temp^ds_scratch_pad.temp_low];
              temp = CRCTable[temp^ds_scratch_pad.conf_register];
              temp = CRCTable[temp^ds_scratch_pad.res1];
              temp = CRCTable[temp^ds_scratch_pad.res2];
              temp = CRCTable[temp^ds_scratch_pad.res3];
              */
              
              /*
              // в темп находится наша WHW - выводим и сравниваем :)
              sprintf(a2, "crc DS = %i , CRC mc = %i\n\r" ,ds_scratch_pad.crc, temp); 
              puts(a2);                            
              */
              
              // сравниваем CRC и если не совпадает - результат - лажа
              if(w1_dow_crc8(&ds_scratch_pad, 8)==ds_scratch_pad.crc)
              {
              
                  // обработаем старший байт - если он отрицателен то все биты надо инвертировать
                  temp = ds_scratch_pad.temp_msb;
                  if((temp>>6)&1)
                    {
                        below=1;
                        temp = temp^0b11111111;
                    }
                  else
                    below=0;
                  
                  ds_temp = (float)((temp&1)*16+((temp>>1)&1)*32+((temp>>2)&1)*64);             
                  
                  // теперь младший
                  temp = ds_scratch_pad.temp_lsb;
                  // если число отрицательно - инвертируем
                  if(below)
                    temp=temp^0b11111111;
                              
                  ds_temp = ds_temp + (float)((temp&1)*0.0625+((temp>>1)&1)*0.125+((temp>>2)&1)*0.25+((temp>>3)&1)*0.5+((temp>>4)&1)+((temp>>5)&1)*2+((temp>>6)&1)*4+((temp>>7)&1)*8);
                                    
                  if(below)
                    ds_temp = (float)(0-ds_temp);             
                  
                  /*
                  sprintf(a2, "bits %i = %i %i %i %i %i %i %i %i \n\r", temp ,temp&1,(temp>>1)&1,(temp>>2)&1,(temp>>3)&1,(temp>>4)&1,(temp>>5)&1,(temp>>6)&1,(temp>>7)&1);
                  puts(a2);
                  */
                  
                  // выводим на экранчик
                  sprintf(a2, "t%u=%+.4f\xf8C\n\r",i+1, ds_temp);                                                               
                  lcd_clear_row(2+i);
                  lcd_gotoxy(1,2+i);
                  lcd_putstr(a2); // выводим на экранчик
                  
                  // строчка для com порта
                  printf("t%u(%i)= %f \n\r",i+1, rom_codes[i], ds_temp); 
                  //puts(a2);
                  
              }
              else
              {
                  sprintf(a2, "t%u= ERROR !\n\r",i+1, ds_temp);                                                               
                  lcd_clear_row(2+i);
                  lcd_gotoxy(1,2+i);
                  lcd_putstr(a2); // выводим на экранчик
                  
                  // строчка для com порта
                  printf("t%u(%i)= ERROR \n\r",i+1, rom_codes[i], ds_temp); 
                  //puts(a2);
              }
                
              
              lcd_gotoxy(75,2+i);
              sprintf(a2, "-");
              lcd_putstr(a2);
          }
      
      };

}
