| 
              #include <iom8v.h>#include <macros.h>
 
 //DS18B20
 #define DQ (PIND&BIT(3))
 #define DQ_0 PORTD&=~BIT(3)
 #define DQ_1 PORTD|=BIT(3)
 #define DQ_IN DDRD&=~BIT(3)
 #define DQ_OUT DDRD|=BIT(3)
 
 //keys
 #define K1 (PINC&BIT(0))
 #define K2 (PINC&BIT(1))
 #define K3 (PINC&BIT(2))
 #define K4 (PINC&BIT(3))
 
 flash char const SEG8[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
 #define NEG 4
 #define CNT 5
 #define CE 6
 #define LTEN 7 //less than -10
 unsigned char SA=0x00;
 unsigned char SB=0x00;
 
 unsigned int number=989;
 
 void delay_250us(void)
 {
 unsigned int i;
 for (i=0;i<285;i++);
 }
 
 void delay_us(unsigned int n)
 {
 if (n==0)
 return;
 while (--n);
 }
 
 void delay(unsigned int n)
 {
 unsigned int i;
 while (n--)
 for (i=0;i<1140;i++);
 }
 
 void DS18B20_Error(void)
 {
 PORTB=0x86;
 PORTD&=~BIT(4);
 while (1);
 }
 
 void DS18B20_Init(void)
 {
 DQ_OUT;
 DQ_1;
 delay_us(6);
 DQ_0;
 delay_us(600);
 DQ_1;
 delay_us(120);
 if (DQ)
 DS18B20_Error();
 delay_us(620);
 }
 
 unsigned char DS18B20_Read(void)
 {
 unsigned char i,dat;
 for (i=0;i<8;i++)
 {
 DQ_OUT;
 DQ_1;
 delay_us(2);
 DQ_0;
 delay_us(4);
 DQ_1;
 delay_us(6);
 dat>>=1;
 
 if (DQ)
 dat|=0x80;
 else
 dat|=0x00;
 delay_us(60);
 }
 return dat;
 }
 
 void DS18B20_Write(unsigned char dat)
 {
 unsigned char i;
 for (i=0;i<8;i++)
 {
 DQ_OUT;
 DQ_1;
 delay_us(2);
 DQ_0;
 if (dat&0x01)
 DQ_IN;
 else
 DQ_OUT;
 
 delay_us(30);
 DQ_1;
 delay_us(3);
 dat>>=1;
 }
 delay_us(10);
 }
 
 void DS18B20_ReadyReadTemp(void)
 {
 DS18B20_Init();
 DS18B20_Write(0xcc);
 DS18B20_Write(0x44);
 delay_us(20);
 
 DS18B20_Init();
 DS18B20_Write(0xcc);
 DS18B20_Write(0xbe);
 }
 
 void seg8_scan(unsigned char n)
 {
 unsigned char d[3];
 unsigned char p;
 while (n--)
 {
 if (SB<35)
 {
 PORTB=0xbf;
 PORTD&=0x0f; //clear the high 4 bits
 PORTD|=0x90; //1001xxxx
 delay(1);
 continue;
 }
 
 d[0]=number/1000;
 d[1]=number%1000/100;
 d[2]=number%100/10;
 d[3]=number%10;
 SA&=~BIT(LTEN); //clear LTEN
 p=1;
 PORTD|=0xf0; //set the high 4 bits to switch off all the LEDs
 
 if (SA&BIT(CE))
 {
 PORTB=SEG8[d[0]];
 if (d[0]>0)
 {
 PORTD&=~BIT(4);
 SA|=BIT(LTEN);
 }
 delay_250us();
 
 PORTD|=0xf0;
 PORTB=SEG8[d[1]];
 if (d[1]>0 || (SA&BIT(LTEN)))
 {
 PORTD&=~BIT(5);
 SA|=BIT(LTEN);
 }
 delay_250us();
 
 PORTD|=0xf0;
 PORTB=SEG8[d[2]];
 if (d[2]>0 || (SA&BIT(LTEN)))
 PORTD&=~BIT(6);
 delay_250us();
 
 PORTD|=0xf0;
 PORTB=SEG8[d[3]];
 PORTD&=~BIT(7);
 delay_250us();
 }
 else
 {
 if (SA&BIT(NEG))
 {
 PORTB=0xbf;
 if (d[0]>0)
 {
 SA|=BIT(LTEN); //set LTEN
 p=0;
 }
 }
 else if (d[0]>0)
 PORTB=SEG8[d[0]];
 else
 PORTB=0xff;
 PORTD&=~BIT(4);
 delay_250us();
 
 PORTD|=0xf0;
 PORTB=SEG8[d[p]]+((SA&BIT(LTEN))?0x00:0x80);
 PORTD&=~BIT(5);
 delay_250us();
 
 PORTD|=0xf0;
 PORTB=SEG8[d[p+1]]+((SA&BIT(LTEN))?0x80:0x00);
 PORTD&=~BIT(6);
 delay_250us();
 
 PORTD|=0xf0;
 PORTB=SEG8[d[p+2]];
 PORTD&=~BIT(7);
 delay_250us();
 }
 }
 PORTD|=0xf0;
 }
 
 void DS18B20_Measure(void)
 {
 unsigned char tl,th,tltemp;
 unsigned char tn,td;
 DS18B20_ReadyReadTemp();
 tl=DS18B20_Read();
 th=DS18B20_Read();
 
 if ((th&0xf8)!=0x00)
 {
 SA|=BIT(NEG);
 tl=~tl;
 th=~th;
 tltemp=tl+1;
 tl=tltemp;
 if (tltemp>=255)
 th++;
 
 //tn=th*16+tl/16;
 //td=(tl%16)*10/16;
 }
 else
 SA&=~BIT(NEG);
 
 tn=th*16+tl/16;
 td=(tl&0x0f)*625/100; //*6.25
 
 number=tn*100+td%100;
 
 if (SB!=255)
 SB++;
 
 seg8_scan(10);
 }
 
 void key_scan(void)
 {
 if (SB<40)
 return;
 
 if (!K1)
 {
 seg8_scan(3);
 if (!K1)
 {
 if (SA&BIT(CE))
 {
 if (TCCR1B==0x00)
 {
 //Start Timer 1
 TCNT1H=0x85;
 TCNT1L=0xee; //1s
 TCCR1B=0x04;
 }
 else
 TCCR1B=0x00; //Stop Timer 1
 }
 else
 {
 SA|=BIT(CE);
 number=0;
 }
 while (!K1)
 seg8_scan(3);
 seg8_scan(20);
 }
 }
 
 if (SA&BIT(CE))
 {
 if (!K2)
 {
 seg8_scan(3);
 if (!K2)
 {
 number++;
 if (number>9999)
 number=0;
 while (!K2)
 seg8_scan(1);
 seg8_scan(2);
 }
 }
 if (!K3)
 {
 seg8_scan(3);
 if (!K3)
 {
 if (number==0)
 number=9999;
 else
 number--;
 while (!K3)
 seg8_scan(1);
 seg8_scan(2);
 }
 }
 
 if (!K4)
 {
 seg8_scan(3);
 if (!K4)
 {
 TCCR1B=0x00; //stop timer and exit
 SA&=~BIT(CE);
 while (!K4)
 seg8_scan(1);
 seg8_scan(2);
 }
 }
 }
 }
 
 void main(void)
 {
 PORTB=DDRB=0xff;
 DDRC=0x00;
 PORTC=0xff;
 PORTD=DDRD=0xff;
 
 SEI();
 TIMSK|=BIT(TOIE1); //allow Timer 1 overflow interrupt
 DS18B20_Init();
 
 while (1)
 {
 seg8_scan(1);
 DS18B20_Measure();
 key_scan();
 
 while (SA&BIT(CE))
 {
 key_scan();
 seg8_scan(1);
 }
 }
 }
 
 #pragma interrupt_handler timer1_ovf_isr:iv_TIM1_OVF
 void timer1_ovf_isr(void)
 {
 TCNT1H=0x85;
 TCNT1L=0xee; //1s
 
 if (number>=9999)
 number=0;
 else
 number++;
 
 //Note: If you use a crystal of 7.3728MHz, the timer will not be as accurate as 8MHz (internal RC oscillator).
 }
 
              
                |