Примеры CodeVisionAVR - Термометр & ЖКИ

Автор: Internet. Опубліковано в Початківцям з CV AVR

Зміст статті

  Подключение одного датчика .

Программная часть. 

Подключим один датчик к микроконтроллеру ATmega8. Программная часть.

Подключаем к основному коду программы заголовочный файл.h


#include <ds18b20.h>

Чтобы начать работать с одним датчиком, достаточно воспользоваться двумя функциями:

Функция инициализации

ds18b20_init( адрес датчика, нижний порог Т, верхний порог Т, разрешающая способность );

функция чтения температуры

ds18b20_temperature( адрес датчика );

Код программы.

Code
#include                                                      // библиотека ввода вывода микроконтроллера
#asm
  .equ __w1_port=0x18 ;PORTB                                       // сообщаем куда подключен датчик
.equ __w1_bit=0
#endasm
#include <1wire.h>                                                        // библиотека работы с 1Wire
#include                                                    // библиотека для работы с датчиком ds18b20
#asm
  .equ __lcd_port=0x12 ;PORTD                                       // сообщаем куда подключён экран
#endasm
#include                                                            // библиотека для LCD
#include                                                        // библиотека задержки
#include                                                         // стандартная библиотека вывода символов на экран 
unsigned char devices;                                                    // переменная в которой количество присоеденённых датчиков
int temp;                                                                        // переменная для хранения температуры  
unsigned char lcd_buffer[16]; 
void main(void)                                                              // Declare your global variables here

PORTB=0b00000000;                                                      // Port B initialization
 DDRB=0b00000000;                                                      // 0b в таком виде легче представить состояние портов
PORTC=0b10000000;                                                      // Port C initialization
DDRC=0b00000000;
PORTD=0b00000000;                                                      // Port D initialization
DDRD=0b00000000;
ACSR=0x80;                                                                  // Analog Comparator: Off
lcd_init(16);                                                                   // инициилизация LCD, и говорим что он на 16 символов
devices=w1_init();                                                          // ищим датчики
while(devices>0)                                                            // бесконечный цикл, если датчик подключон
{
  temp=ds18b20_temperature(0);                                    // читаем температуру  
  if (temp>1000){                                                           // если датчик выдаёт больше 1000
  temp=4096-temp;                                                        // отнимаем от данных 4096
  temp=-temp;                                                               // и ставим знак "минус"
}
  sprintf(lcd_buffer,"t=%i.%u xdfC",temp,temp%1);          // записуем в масив показания на экран 
  lcd_clear();                                                                  // чистим дисплей перед выводом
  lcd_puts(lcd_buffer);                                                     // выводим масив на LCD
  delay_ms(500);                                                            // ждём 500мс
};

Проект использования одного датчика ds18b20

Еще один пример если необходимо выводить значение температуры с точностью до одной сотой,

Код программы.

Code
#include                                              // библиотека ввода вывода микроконтроллера
#asm
  .equ __w1_port=0x18 ;PORTB                               // сообщаем куда подключен датчик
  .equ __w1_bit=0                                                   // 1 Wire Bus functions
#endasm
#include                                            // библиотека для работы с датчиком ds18b20
#include                                                // библиотека задержки
#define MAX_DS18B20 8
unsigned char ds18b20_devices;
unsigned char ds18b20_rom_codes[MAX_DS18B20][9];
#asm 
  .equ __lcd_port=0x12 ;PORTD                               // сообщаем куда подключён экран
#endasm 
#include                                                    // библиотека для LCD
#include                                                 // библиотека для LCD
float temper;                                                          // переменная в которой количество 
int temp_0,temper_fl,min=0;                                   // обьявляем перменные
char lcd_buffer[16];                                                // масив с данными для экрана
void temperature(void)                                           // функция по работе с термо-датчиком
{
temper=ds18b20_temperature(&ds18b20_rom_codes[0][0]);
  temp_0=temper;                                                  // отбор целой части от температуры 
  if(temper<0)                                                        // при отрицательной температуре  
{
  temper_fl=(temper-temp_0-0.0625)*10;                // дробная часть 
  temp_0=-((temp_0*10)+temper_fl);                      // температура*10 
  min=1;                                                                // минус
  }else                                                                   // при положительной 
{
  min=0;                                                                // плюс 
  temper_fl=(temper-temp_0)*10;                           // дробная часть 
  temp_0=(temp_0*10)+temper_fl;                          // температура*10 

  if ((temp_0 < 1300) & (temp_0 > 0))                      // установим порог 
temp_0= temp_0;
else
{
temp_0 =0; 

}
void main(void)                                                      //основная функция
{
 char *_str=" c2.at.ua";                                  //Создаем информ. строку 
char *_str1="Tepјoјeїp 0.1 x60C"; 

PORTB=0b00000000;                                              // «WzAVR «Port B initialization
 DDRB=0b00000000;                                              // 0b в таком виде легче представить состояние портов

PORTC=0b10000000;                                              // «WzAVR «Port C initialization
DDRC=0b00000000;

PORTD=0b00000000;                                              // «WzAVR «Port D initialization
DDRD=0b00000000;

ACSR=0x80;                                                          // «Analog Comparator: Off
ds18b20_devices=w1_search(0xf0,ds18b20_rom_codes); 
 ds18b20_init(0,-35,35,DS18B20_12BIT_RES);          // переключения термометра в 12 битный режим 
  w1_init();                                                             // 1 Wire Bus initialization
  lcd_init(16);                                                          // Инициализация ЖКИ на 16 символов 
  lcd_gotoxy(0, 0);                                                  // Переводим курсор на первый символ первой строки 
  lcd_puts(_str);                                                      // Выводим строку _str на дисплей ЖКИ  
  lcd_gotoxy(0, 1);                                                  // Переводим курсор на первый символ первой строки 
  lcd_puts(_str1);                                                    // Выводим строку _str на дисплей ЖКИ 
  delay_ms(900);                                                    // ждём 900мс  
  lcd_clear();                                                          // чистим дисплей перед выводом  
lcd_init(16);                                                           // «WzAVR « Инициализация ЖКИ на 16 символов
while (1)                                                                // бесконечный цикл, если датчик подключон  
{
delay_ms(50);
  temperature();                                                     // вызываем функцию температуры
  lcd_clear();                                                          // очищаем LCD
if(min==1)
{
  sprintf(lcd_buffer,"t=-%u.%u x60C ",temp_0/10,temp_0%10); //вывод отрицательной температуры 
}else
{
  sprintf(lcd_buffer,"t=+%i.%d x60C ",temp_0/10,temp_0%10); // вывод положительной
}
  lcd_puts(lcd_buffer);                                             // вывод на дисплей
};
}


Проект использования одного датчика ds18b20    с точностью до  0.1°C

Подключение двух датчиков.


При подключении более одного датчика ds18b20 на линию 1-wire, необходимо выполнять чтение ROM каждого датчика, чтоб обращаться к каждому индивидуально. Используя функцию w1_search, производим поиск устройств 1-wire, тем самым выясняем их количество на линии и производим чтение ROM данных каждого датчика:

unsigned char devices;

unsigned char rom_code[2][9];

Код программы.

Code
#include                                              // библиотека ввода вывода микроконтроллера
#asm
  .equ __w1_port=0x18 ;PORTB                               //сообщаем куда подключен датчик
.equ __w1_bit=0
#endasm
#include                                             //библиотека для работы с датчиком ds18b20
unsigned char rom_code[4][9];                                //масив с адресами найденых датчиков
#define MAX_DS18B20 8
#asm 
  .equ __lcd_port=0x12 ;PORTD                               //сообщаем куда подключён экран
#endasm 
#include                                                    //библиотека для LCD
#include                                                 //библиотека для LCD
#include                                                //библиотека задержки
unsigned char i,devices;                                          //переменная в которой количество 
int temp1,temp2;                                                    //обьявляем перменные
unsigned char lcd_buffer_1[16];                               //масив с данными для экрана
unsigned char lcd_buffer_2[16];                               //масив с данными для экрана 
void main(void)                                                      // Declare your global variables here
{
 char *_str=" c2.at.ua";                                  //Создаем информ. строку 
char *_str1="2 Tepјoјeїpa 1 x60C"; 

PORTB=0b00000000;                                              // «WzAVR «Port B initialization
 DDRB=0b00000000;                                              // 0b в таком виде легче представить состояние портов

PORTC=0b10000000;                                              // «WzAVR «Port C initialization
DDRC=0b00000000;

PORTD=0b00000000;                                              // «WzAVR «Port D initialization
DDRD=0b00000000;
devices=w1_search(DS18B20_SEARCH_ROM_CMD,rom_code); //определим сколько устройств подключено к шине 1-Wire 

ACSR=0x80;                                                          // «Analog Comparator: Off
 ds18b20_init(0,-35,35,DS18B20_12BIT_RES);          // переключения термометра в 12 битный режим 
  w1_init();                                                             // Wire Bus initialization
  lcd_init(16);                                                         // Инициализация ЖКИ на 16 символов 
  lcd_gotoxy(0, 0);                                                  // Переводим курсор на первый символ первой строки 
  lcd_puts(_str);                                                      // Выводим строку _str на дисплей ЖКИ  
  lcd_gotoxy(0, 1);                                                  // Переводим курсор на первый символ первой строки 
  lcd_puts(_str1);                                                    // Выводим строку _str на дисплей ЖКИ 
  delay_ms(900);                                                    // ждём 900мс  
  lcd_clear();                                                          // чистим дисплей перед выводом  
lcd_init(16);                                                            // Инициализация ЖКИ на 16 символов
while(devices>0)                                                     // бесконечный цикл, если датчик подключон  
{                                                                           // Place your code here
  temp1 = ds18b20_temperature(&rom_code[0][0]);  // читаем температуру с выбранного датчика
//if( temp1 > 1000 ) { temp1 = 4096 - temp1; temp1 = -temp1; }
  if ((temp1 < 130) & (temp1 > -60))                        // установим границу диапазон 
temp1= temp1;
else
{
  temp1 =0;                                                            // если выходит за границу тогда 0
}
sprintf(lcd_buffer_1," t%u=%i.%u xdfC ",i+1,temp1,temp1%1);
  lcd_gotoxy(0,0);                                                   // указали место на дисплее
lcd_puts(lcd_buffer_1); // выводим масив на LCD
  temp2 = ds18b20_temperature( &rom_code[1][0] ); //читаем температуру с выбранного датчика  
//if( temp2 > 1000 ) { temp2 = 4096-temp2; temp2 = -temp2; }
  if ((temp2 < 130) & (temp2 > -60))                        // установим границу диапазон 
temp2= temp2;
else
{
  temp2 =0;                                                           // если выходит за границу тогда 0
}
sprintf(lcd_buffer_2," t%u=%i.%u xdfC ",i+2,temp2,temp2%1); 
lcd_gotoxy(0,1);
  lcd_puts(lcd_buffer_2);                                          // выводим масив на LCD
  delay_ms(30);                                                      // ждём 
};

}

Проект использования двух датчиков ds18b20

Пример проекта где можно подключать датчики "десятками". :)

Код программы.

Code
/*****************************************************
CodeWizardAVR 
Project : Ver. 1.6.0
Version : Термометр 1°С
Date : 04.02.2012 
Company : c2.at.ua 
Chip type : ATmega8
Program type : Application
Clock frequency : 4,000000 MHz
*****************************************************/ 
#include <mega8.h> // библиотека ввода вывода микроконтроллера
#asm
.equ __w1_port=0x18 ;PORTB //сообщаем куда подключен датчик
.equ __w1_bit=0
#endasm
#include <ds18b20.h> //библиотека для работы с датчиком ds18b20
#define MAX_DS18B20 8
#asm 
.equ __lcd_port=0x12 ;PORTD //сообщаем куда подключён экран
#endasm 
#include <lcd.h> //библиотека для LCD
#include <stdio.h> //библиотека для LCD
#include <delay.h> //библиотека задержки
unsigned char rom_code[16][9]; //масив с адресами найденых датчиков
char lcd_buffer[16]; //масив с данными для экрана
unsigned char devices=9, iw=0; //переменная в которой количество присоеденённых датчиков, и номер выбранного датчика
int temp; //переменная для хранения температуры
void main(void) 

PORTB=0b00000010; // Port B initialization
DDRB=0b00000000; // 
PORTC=0b11000000; // Port C initialization
DDRC=0b00000000;
PORTD=0b00000000; // Port D initialization
DDRD=0b00000000;
ACSR=0x80; // Analog Comparator: Off
lcd_init(16); //инициилизация LCD, и говорим что он на 16 символов
devices=w1_search(0xf0,rom_code); //ищим датчики, и записуем их адреса в масив
while(devices>0) //бесконечный цикл, если датчик подключон

if (PINB.1==1 ) { //Если нажата кнопка
iw++; //Увиличиваем переменную "i" на 1
delay_ms(300); //Ждём 300мс для "анти-дребезга"
}
if(iw>=devices){ 
delay_ms(5); //Если "iw" больше или равно найденым датчикам
iw=0; //тогда "i" равно нулю
}
temp=ds18b20_temperature(&rom_code[iw][0]); //читаем температуру с выбранного датчика
if (temp>1000){ //если датчик выдаёт больше 1000
temp=4096-temp; //отнимаем от данных 4096
temp=-temp; //и ставим знак "минус"
};
if (temp > -1000) // установим порог если обрыв датчика 
temp= temp;
else
{
temp =0; // выводим ноль

sprintf(lcd_buffer,"t%i=%i.%u xdfC", iw,temp,temp%1); //записуемв масив для экрана температуру и всё такое
lcd_clear(); //чистим дисплей перед выводом
lcd_puts(lcd_buffer); //выводим масив на LCD
delay_ms(50); //ждём 500мс
};
}


Проект такого подключения датчиков ds18b20  

Fuse бит , при прошивке МК выставить так