Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
TsUiM_jumahon.docx
Скачиваний:
39
Добавлен:
03.05.2015
Размер:
602.36 Кб
Скачать

Алгоритм программы

начало

Инициализация

OK_ввод==1

да

нет

Ставим прочерки

Во всех ридах

Инициализация

И считыван

(Temp –H8(1и3)

да

нет

да

Вычислить отрецательний

Вычис целая значен темпер

конец

Краткое описание программы

Скомпилированная программа представляет собой файл типа сof, который прошиваем на микроконтроллер Аtmegа 8 семейства АVR.

Соединяем компоненты рабочей модели прибора, получаем сигнал с температурного датчика, считываем температуру окружающей среды .

Для общения микроконтроллера с датчиком понадобятся три функции:

функция инициализации или сброса датчика(DS18B20_init();), функция чтения одного байта из датчика(read_18b20();) и функция записи одного байта в датчик(write_18b20();). Для отсчета временных задержек используем стандартную функцию WINAVR util/delay.h, также для корректной работы датчика необходимо прописать в компиляторе реальную тактовую частоту микроконтроллера:

Программный код

// Практическое применение термодатчиков DS18B20. Простой термометр

#include <avr/io.h>

#include <util/delay.h>

#include <avr/interrupt.h>

#define F_CPU 8000000UL // устанавливаем рабочую частоту контроллера //------------------0-----1-----2-----3-----4-----5-----6

char SEGMENTE[] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D,

//------------------7-----8-----9-----dp---minus-blank

0x07, 0x7F, 0x6F, 0x80, 0x40, 0x00}; 

volatile unsigned char segcounter = 0;

volatile int display1 = 0, display2 = 0, display3 = 0, display4 = 0; 

// Прерывание по переполнению T2, динамическая индикация

ISR (TIMER2_OVF_vect)

{  

PORTD = 0xFF;

PORTB = (1 << segcounter);

switch (segcounter)

{  

case 0:

PORTD = ~(SEGMENTE[display1]);

break;

case 1:

PORTD = ~(SEGMENTE[display2]);

break; 

case 2:

PORTD = ~((SEGMENTE[display3])|0x80); // добавляем точку

break;     

case 3:

PORTD = ~(SEGMENTE[display4]);

break;     

}

if ((segcounter++) > 2) segcounter = 0; 

}

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(68);

// ловим импульс присутствия датчика

OK_Flag = (PINC & (1 << PC0));// если OK_Flag = 0 датчик подключен, OK_Flag = 1 датчик не подключен

_delay_us(422);

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;

TIMSK |= (1 << TOIE2); // разрешение прерывания по таймеру2

TCCR2 |= (1 << CS21);  //перед делитель на 8

_delay_ms(50);

// переменные для целого значения температуры

unsigned int tempint = 0,tempint1,tempint2,tempint3;

// переменные для дробного значения температуры

unsigned int temppoint = 0,temppoint1;

 

sei(); //глобально разрешаем прерывания

 

while(1)

{                      

if(OK_Flag == 1) // если датчик не ответил

{

// ставим прочерки во всех разрядах

display1 = 11; display2 = 11;

display3 = 11; display4 = 11;

}

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 << 8) | 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(temp_flag == 0) // если флаг знака температуры равен 0,

tempint1 = 11;     // в первом разряде ставим минус

if(tempint1 < 1) // если первая цифра значения температуры меньше 1,

tempint1 = 12;     // то гасим 1 разряд индикатора

if(tempint2 < 1) // если вторая цифра значения температуры меньше 1,tempint2 = 12;      // то гасим 2 разряд индикатора

// выводим значения на дисплей

display1 = tempint1; display2 = tempint2;

display3 = tempint3; display4

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]