/*****************************************************
Chip type               : ATtiny2313
AVR Core Clock frequency: 4,000000 MHz
Memory model            : Tiny
External RAM size       : 0
Data Stack size         : 32
*****************************************************/
      
#asm
   .equ __w1_port = 0x12 ;PORTD
   .equ __w1_bit = 0
#endasm

#include <tiny2313.h>
#include <delay.h>
#include <ds1820.h>

int count=0, t=0;
signed char t0 = 12, t1 = 0, t2 = 0;
unsigned char rc[1][9], dv, cd = 0, tc = 15, md = 0, i = 0, lTm = 0, lTc = 0, cSt = 0, lSt = 0, waitMd = 0;

//общий катод
flash char buf[13] = {     
0b01011111, //0
0b00010010, //1 
0b00101111, //2
0b00111011, //3
0b01110010, //4
0b01111001, //5
0b01111101, //6
0b00010011, //7
0b01111111, //8
0b01111011, //9
0b00100000, //-
0b01101100, //t
0b01001101  //C
};  

//общий анод
/*flash char buf[13] = {     
0b10100000, //0
0b11101101, //1 
0b11010000, //2
0b11000100, //3
0b10001101, //4
0b10000110, //5
0b10000010, //6
0b11101100, //7
0b10000000, //8
0b10000100, //9
0b11011111, //-
0b10010011, //t
0b10110010  //C
};  */

void EEPROM_write(unsigned int uiAddress, unsigned char ucData)
{
while(EECR & (1<<EERIE));
EEAR = uiAddress;
EEDR = ucData;
EECR |= (1<<EEMWE);
EECR |= (1<<EERIE);
}

unsigned char EEPROM_read(unsigned int uiAddress)
{
while(EECR & (1<<EEWE));
EEAR = uiAddress;
EECR |= (1<<EERE);
return EEDR;
} 

// External Interrupt 0 service routine
interrupt [EXT_INT0] void ext_int0_isr(void)
{
// Place your code here
    if (md) {
        if (tc < 99) tc++;
        waitMd = 0;
    } 
    else
        md = 1;   
}

// External Interrupt 1 service routine
interrupt [EXT_INT1] void ext_int1_isr(void)
{
// Place your code here
    if (md) {
        if (tc > 0) tc--;
        waitMd = 0;
    } 
    else
        md = 1;
}

// Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
//выход из режима установки контрольной T через 5 сек.
    count++;
    if (count >= 4000) {     
        if (md) { 
            waitMd++;
            if (waitMd >= 5) {
                md = 0;  
                //#asm("cli")
                //EEPROM_write(0, tc);
                //#asm("sei")
            }            
        } 
        else 
            waitMd = 0;
        count = 0;
    }
}

// Timer1 overflow interrupt service routine
interrupt [TIM1_OVF] void timer1_ovf_isr(void)
{
// индикация
    switch (cd){ 
              case 0:{PORTD.4 = 1; PORTD.5 = 1; PORTD.6 = 1; PORTB = buf[t0]; PORTD.6 = 0; break;};  //первая цифра 
              case 1:{PORTD.4 = 1; PORTD.5 = 1; PORTD.6 = 1; PORTB = buf[t1]; PORTD.5 = 0; break;};  //первая цифра
              case 2:{PORTD.4 = 1; PORTD.5 = 1; PORTD.6 = 1; PORTB = buf[t2]; PORTD.4 = 0; break;};  //вторая цифра
          }        
    cd++;                        
    if (cd == 3) cd = 0;         
}

void main(void)
{

// Crystal Oscillator division factor: 1
#pragma optsize-
CLKPR=0x80;
CLKPR=0x00;
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif

// Input/Output Ports initialization
// Port A initialization
// Func2=In Func1=In Func0=In 
// State2=T State1=T State0=T 
PORTA=0x00;
DDRA=0xff;

// Port B 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 
PORTB=0x00;
DDRB=0xff;

// Port D initialization
// Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
// State6=T State5=T State4=T State3=T State2=T State1=T State0=T 
PORTD=0b00001101;
DDRD =0b11110010;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 1,000 kHz
// Mode: Normal top=FFh
// OC0A output: Disconnected
// OC0B output: Disconnected
TCCR0A=0x00;
TCCR0B=0x02;
TCNT0=0x00;
OCR0A=0x00;
OCR0B=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 8000,000 kHz
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer1 Overflow Interrupt: On
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x01;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

// External Interrupt(s) initialization
// INT0: On
// INT0 Mode: Faling Edge
// INT1: On
// INT1 Mode: Faling Edge
// Interrupt on any change on pins PCINT0-7: Off
GIMSK=0xC0;
MCUCR=0x0A;
EIFR=0xC0;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x82;

// Universal Serial Interface initialization
// Mode: Disabled
// Clock source: Register & Counter=no clk.
// USI Counter Overflow Interrupt: Off
USICR=0x00;

// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
#asm("cli");
dv = w1_search(0xf0, rc);
//tc = EEPROM_read(0);
#asm("sei")

while (1)
      {    
        // if (i == 255){ 
              lSt = cSt; 

              t = ds1820_temperature_10(&rc[0][0]) / 10;
//              if (t > 1000)
//                  t = 4096 - t;
                
//обработка ситуации, когда на измерение выпадает прерывание, для непрерывной индикации  
/*              if (t == 25 && lTm != t && lTc != 3) {
                  t = lTm;
                  lTc++;       
              }  
              else {
                  lTm = t;
                  lTc = 0;
              }  
              */

//вкл/выкл нагревателя
              if (t < tc)
                  cSt = 1;
              else
                  cSt = 0;  
                  
              if (cSt != lSt) {
                  if (cSt == 1) 
                      PORTA.1 = 1;
                  else
                      PORTA.1 = 0;    
              }    
//символ для индикации режима              
              switch (md){
                  case 0: {
                           if (t < 0) 
                               t0 = 10;
                           else
                               t0 = 11;   
                           t1 = t / 10; 
                           t2 = t % 10; 
                           break;
                          };           
                  case 1: {t0 = 12; t1 = tc / 10; t2 = tc % 10; break;};      
              }       
         //     i=0;
        //  } 
        //  i++;   
      };    
}
