Опубликовано 2010-09-20 15:21:28 автором Ruslan

Опис роботи з датчиком температури DS18B20


У пристроях автоматики дуже часто потрібно контролювати якийсь параметр навколишнього середовища: температуру , вологість , освітленість , тиск і т.д. Для цього існують датчики - пристрої , які перетворять одну фізичну величину в іншу. Для вимірювання температури існує дуже багато різноманітних датчиків , від найпростіших контактних (біметалеві , ртутні ) до складних перетворювачів температури в напругу , частоту , струм і т.д.
Сьогодні я покажу, як цифровий датчик температури DS18B20 подружиться з мікроконтролером avr atmega8 .

Датчік температури DS18B20 до avr

  1. GND - мінус живлення.
  2. DQ - лінія введення \ виводу даних.
  3. Vdd - плюс живлення.  Датчик температури DS18B20 - мікросхема з трьома виводами , DS18B20 обмінюється даними по шині 1 -Wire . На одній шині може бути дуууже багато датчиків , це досягається за рахунок того, що кожен DS18B20 має свій унікальний код , і мікроконтролер таким чином ініциалізує передачу даних з певним датчиком на шині.
    Діапазон вимірюваних температур від -55 ° C до +125 ° C і точністю 0.5 ° C. Роздільна здатність за замовчуванням встановлена ​​12 - біт, але може бути змінена користувачем на 9 , 10 , або 11 біт. Ще однією особливістю DS18B20 є можливість працювати без зовнішнього живлення , він може живитись від лінії даних ( " parasite power " ), за відсутності зовнішнього джерела. Ця здатність реалізується за рахунок того, що всередині датчика є конденсатор, який заряджається через підтягуючий резистор від високого рівня на лінії даних. Цей метод часто називають методом « паразитного живлення» .
    Давайте зберемо простий термометр на DS18B20 і мікроконтролері atmega8 .
    Задача:
    Цифровий термометр повинен вимірювати температуру і виводити її на lcd дисплей.
    Схема термометра виглядає наступним чином
    Схема термометра на DS18B20

     У CodeVision є спеціальна бібліотека для роботи з DS18B20 . У ній знаходяться всі необхідні функції для роботи з ним. Для того , щоб використовувати даний датчик у своїх конструкціях , необхідно виконати ряд нескладних процедур по підключенню датчика. На фізичному рівні датчик підключається до одного з виводів будь-якого порту. Вивід GND з'єднується із загальним проводом , вивід Vdd підключається до +5 В, а вивід DQ - до лінії обраного порту. При цьому на вивід DQ відноситься підтягуючий резистор (зазвичай 4,7 к) , другий вивід якого підключається до +5 В.
    Програма виглядає так

    # include
    # include
    / / 1 Wire Bus functions
    / / вказуємо, куди підключений датчик
    # asm
       . equ __ w1_port = 0x18 ; PORTB
       . equ __ w1_bit = 0
    # endasm

    # include / / бібліотека для роботи з датчиком ds18b20
     
    / / Alphanumeric LCD Module functions
    / / вказуємо, куди підключений екран
    # asm
       . equ __ lcd_port = 0x12 ; PORTD
    # endasm

    # include / / бібліотека для LCD
    # include / / бібліотека, в якій живе функція sprintf
     
    char lcd_buf [ 16 ] ; / / Масив, в якому формуються дані для виведення на lcd
    float temperature ; / / Змінна, в якій буде зберігається значення температури

    void main ( void )
    {
    lcd_init ( 16 ) ; / / Ініціалізація LCD на 16 символів
    w1_init (); / / / / Ініціалізація шини 1 wire
     
    while ( 1 )
          {
              temperature = ds18b20_temperature (0); / / отримуємо температуру від датчика 0
              sprintf ( lcd_buf , " t = % .1 f \ xdfC " , temperature ) ; / / Формуємо рядок для виведення
              lcd_clear (); / / Чистимо дисплей
              lcd_puts ( lcd_buf ) ; / / Виводимо вміст масиву lcd_buf на дисплей
              delay_ms ( 1000 ) ; / / Робимо затримку в 1 секунду
          } ;
    }


    За програмою ніби все зрозуміло , єдине тільки треба у властивостях проекту вказати ( s ) printf features float і частоту мк виставити на 1 mhz , для цього переходимо Project - > Configure - > C Compiler і виставляємо все як на скріншотінастройка DS18B20Компілюємо і отримуємо термометрТермометр на DS18B20Як бачите, підключити датчик температури до мк не складає ніяких труднощів , 20 хвилин і термометр на lcd готовий.
    Зараз ми зробимо ще один термометр, але з виведенням температури на Led ( семисегментний індикатор) . C термометром на семісегментнику не все так просто, як здається на перший погляд. Справа в тому, що функція ds18b20_temperature блокує виконання основного потоку, поки датчик не пришле значення температури, а це близько однієї секунди. Ось вихідний код функції
    < br >
    float ds18b20_temperature ( unsigned char * addr )
    {
    unsigned char resolution ;
    if ( ds18b20_read_spd ( addr ) == 0 ) return -9999 ;
    resolution = ( __ds18b20_scratch_pad.conf_register >> 5 ) & 3 ;
    if ( ds18b20_select ( addr ) == 0 ) return -9999 ;
    w1_write ( 0x44 ) ;
    delay_ms ( conv_delay [ resolution ] ) ; ось на цьому delay_ms головний потік і зупиняється
    if ( ds18b20_read_spd ( addr ) == 0 ) return -9999 ;
    w1_init ();
    return (* ( ( int * ) & __ds18b20_scratch_pad.temp_lsb ) & ( ( int ) bit_mask [ resolution ])) * 0.0625 ;
    }


    а в нас-то індикація на семісегментнику динамічна , це значить, що семісегментнік буде зависати на період вимірювання температури. Щоб вирішити цю проблему, нам прийдеться вручну посилати команди DS18B20 .
    Алгоритм такий :
    послали команду на вимірювання температури, і далі займаємося своїми справами
    через півтори секунди запитали в датчика, чи виміряв він температуру , якщо так, то отримуємо дані і виводимо їх на семісегментник . Посилати команди датчику ми будемо за допомогою функції w1_write . Давайте приступимо до написання коду
     

    Виведення значення температури на дисплей складається з наступних кроків:

    1. Визначаємо знак температури і відображаємо його на дисплеї
    2. Якщо температура відємна , перетворимо її на додатну.
    3. Віделяемо за допомогою бітових масок цілу частину температури , переводимо в символи і відображаємо на дисплеї.    Щоб перевести оцифроване значення температури в градуси , потрібно це значення помножити на вагу молодшого розряду. Для цілої частини температури вага молодшого розряду ( BIT4 ) дорівнює 1 градусу Цілься , а значить множити нічого не потрібно.
    4. Виділяємо дробову частину , перетворимо дробову частину в цілу , переводимо в символи і відображаємо на дисплеї.

    Комментарии - (4)

    • Sanyo.95 говорит:
      Большое спасибо автору за урок, все отлично, но кода для вывода на семисегментник нет, очень хотелось бы взглянуть.
    • Артём говорит:
      День добрый! Можете вот это: "послали команду на измерение температуры, и дальше занимаемся своими делами через полторы секунды спросили у датчика, измерил ли он температуру, если да, то получаем данные и выводим их на семисегментник. Посылать команды датчику мы будем с помощью функции w1_write. Давайте приступим к написанию кода" написать кодом, сам не допираю как всё это будет выглядеть, заранее спасибо!
    • Артём говорит:
      на странице кода не видно/нет...

    Добавить комментарий

    Для отправки комментария вы должны авторизоваться.