Вот сам код:
#include ‹avr/io.h›
#include ‹util/delay.h›
#include ‹avr/interrupt.h›
#define F_CPU 8000000UL // устанавливаем рабочую частоту контроллера
//------------------0-----1-----2-----3-----4-----5-----6-----7-----8------9----dp---minus-blank---E---r
char SEGMENTE[] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F, 0x80, 0x40, 0x00, 0x79, 0x50};
volatile unsigned char segcounter = 0;
volatile int display1 = 0, display2 = 0, display3 = 0, display4 = 0, display5 = 0, display6 = 0, display7 = 0, display8 = 0, display9 = 0;
/*** Прерывание по переполнению T2, динамическая индикация ***/
ISR (TIMER2_OVF_vect)
{
PORTD = 0xFF;
PORTB = (1 ‹‹ segcounter);
switch (segcounter)
{
case 0:
PORTD = ~(SEGMENTE[display1]);
break;
case 1:
PORTD = ~((SEGMENTE[display2])|0x80);
break;
case 2:
PORTD = ~(SEGMENTE[display3]); // добавляем точку |0x80)
break;
///////////////////////////////////////
case 3:
PORTD = ~(SEGMENTE[display4]);
break;
case 4:
PORTD = ~((SEGMENTE[display5])|0x80);
break;
case 5:
PORTD = ~(SEGMENTE[display6]); // добавляем точку |0x80)
break;
}
if ((segcounter++) ›
segcounter = 0;
}
volatile unsigned long value;
volatile unsigned int adc_counter;
/***Прерывание по окончанию преобразования АЦП***/
ISR (ADC_vect)
{
value = value + (ADC*11/4);
adc_counter++;
}
unsigned char Temp_H = 0,Temp_L = 0,OK_Flag = 0,temp_flag;
/*** Инициализация DS18B20 ***/
unsigned char DS18B20_init(void)
{
PORTC &= ~(1 ‹‹ PC0); // устанавливаем низкий уровень
DDRC |= (1 ‹‹ PC0);
_delay_us(490);
DDRC &= ~(1 ‹‹ PC0);
_delay_us(6
;
OK_Flag = (PINC & (1 ‹‹ PC0)); // ловим импульс присутствия датчика
// если OK_Flag = 0 датчик подключен, OK_Flag = 1 датчик не подключен
_delay_us(500);
return OK_Flag;
}
/*** Функция чтения байта из DS18B20 ***/
unsigned char read_18b20(void)
{
unsigned char i;
unsigned char dat = 0;
for(i = 0;i ‹ 8;i++)
{
DDRC |= (1 ‹‹ PC0);
_delay_us(2);
DDRC &= ~(1 ‹‹ PC0);
_delay_us(4);
dat = dat ›› 1;
if(PINC & (1 ‹‹ PC0))
{
dat |= 0x80;
}
_delay_us(62);
}
return dat;
}
/*** функция записи байта в DS18B20 ***/
void write_18b20(unsigned char dat)
{
unsigned char i;
for(i = 0;i ‹ 8;i++)
{
DDRC |= (1 ‹‹ PC0);
_delay_us(2);
if(dat & 0x01)
{
DDRC &= ~(1 ‹‹ PC0);
}
else
{
DDRC |= (1 ‹‹ PC0);
}
dat = dat ›› 1;
_delay_us(62);
DDRC &= ~(1 ‹‹ PC0);
_delay_us(2);
}
}
/*** Главная функция ***/
int main(void)
{
DDRD = 0xFF;
DDRB |= (1 ‹‹ PB0)|(1 ‹‹ PB1)|(1 ‹‹ PB2)|(1 ‹‹ PB3);
PORTD = 0x00;
PORTB = 0x00;
DDRC = (0 ‹‹ PC1);
TIMSK |= (1 ‹‹ TOIE2); // разрешение прерывания по таймеру2
TCCR2 |= (1 ‹‹ CS21); //предделитель на 8
_delay_ms(50);
// переменные для целого значения температуры и давления
unsigned int tempint = 0,tempint1,tempint2,tempint3,tempint4,tempint5,tem pint6;
unsigned int temppoint = 0,temppoint1; // переменные для дробного значения температуры
ADCSRA = (1 ‹‹ ADEN) // разрешение АЦП
|(1 ‹‹ ADSC) // запуск преобразования
|(1 ‹‹ ADFR) // непрерывный режим работы АЦП
|(1 ‹‹ ADPS2)|(1 ‹‹ ADPS1)|(0 ‹‹ ADPS0) // предделитель на 64 (частота АЦП 125kHz)
|(1 ‹‹ ADIE); // разрешение прерывания
ADMUX = (1 ‹‹ REFS1)|(1 ‹‹ REFS0) // внутренний ИОН 2,56V
|(0 ‹‹ MUX3)|(0 ‹‹ MUX2)|(0 ‹‹ MUX1)|(1 ‹‹ MUX0); // вход PC1
_delay_ms(50);
sei(); //глобально разрешаем прерывания
while(1)
{
if (adc_counter › 1000) // вычисляем среднее значение АЦП
{
tempint4 = value/adc_counter % 1000 / 100;
tempint5 = value/adc_counter % 100 / 10;
tempint6 = value/adc_counter % 10;
display4 = 12;// выводим значения на дисплей
display5 = tempint5; display6 = tempint6;
adc_counter = 0;
value = 0;
}
_delay_ms(50);
if(OK_Flag == 1) // если датчик не ответил
{
// ставим прочерки во всех разрядах
display1 = 13; display2 = 14;
display3 = 14;
}
DS18B20_init(); // инициализация DS18B20
write_18b20(0xCC); // проверка кода датчика
write_18b20(0x44); // запуск температурного преобразования
_delay_ms(1000);
DS18B20_init(); // инициализация DS18B20
write_18b20(0xCC); // проверка кода датчика
write_18b20(0xBE); // считываем содержимое ОЗУ
Temp_L = read_18b20(); // читаем первые 2 байта блокнота
Temp_H = read_18b20();
temp_flag = 1; // флаг знака температуры равен 1(плюс)
if(Temp_H &(1 ‹‹ 3)) // проверяем бит знака температуры на равенство единице
{
signed int tmp;
temp_flag = 0; // флаг знака равен 0(минус)
tmp = (Temp_H ‹‹
| Temp_L;
tmp = -tmp;
Temp_L = tmp;
Temp_H = tmp ›› 8;
}
tempint = ((Temp_H ‹‹ 4) & 0x70)|(Temp_L ›› 4); // вычисляем целое значение температуры
tempint1 = tempint % 1000 / 100;
tempint2 = tempint % 100 / 10;
tempint3 = tempint % 10;
temppoint = Temp_L & 0x0F; // вычисляем дробное значение температуры
temppoint = temppoint * 625; // точность температуры
temppoint1 = temppoint / 1000;
if(tempint1 == 1)
{
tempint2 = 13;
tempint3 = 14;
temppoint1 = 14;
}
if(tempint2 ‹ 1)// если 1 цифра значения температуры меньше 1, то гасим 1 разряд индикатора
tempint2 = 12;
if((temp_flag == 0 && OK_Flag != 1)) // если флаг знака температуры равен 0, в последнем разряде ставим минус
{
temppoint1 = 11;
display1 = tempint2; display2 = tempint3;
display3 = temppoint1;
}
if(OK_Flag != 1)
{
display1 = tempint2;// выводим значения Температуры на дисплей
display2 = tempint3; display3 = temppoint1;
}
}
}