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

- GND - мінус живлення.
- DQ - лінія введення \ виводу даних.
- Vdd - плюс живлення. ol > Датчик температури DS18B20 - мікросхема з трьома виводами , DS18B20 обмінюється даними по шині 1 -Wire . На одній шині може бути дуууже багато датчиків , це досягається за рахунок того, що кожен DS18B20 має свій унікальний код , і мікроконтролер таким чином ініциалізує передачу даних з певним датчиком на шині.
Діапазон вимірюваних температур від -55 ° C до +125 ° C і точністю 0.5 ° C. Роздільна здатність за замовчуванням встановлена 12 - біт, але може бути змінена користувачем на 9 , 10 , або 11 біт. Ще однією особливістю DS18B20 є можливість працювати без зовнішнього живлення , він може живитись від лінії даних ( " parasite power " ), за відсутності зовнішнього джерела. Ця здатність реалізується за рахунок того, що всередині датчика є конденсатор, який заряджається через підтягуючий резистор від високого рівня на лінії даних. Цей метод часто називають методом « паразитного живлення» . Давайте зберемо простий термометр на DS18B20 і мікроконтролері atmega8 . Задача: Цифровий термометр повинен вимірювати температуру і виводити її на lcd дисплей. Схема термометра виглядає наступним чином
У 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 і виставляємо все як на скріншоті Компілюємо і отримуємо термометр Як бачите, підключити датчик температури до мк не складає ніяких труднощів , 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 . Давайте приступимо до написання коду Виведення значення температури на дисплей складається з наступних кроків: - Визначаємо знак температури і відображаємо його на дисплеї
- Якщо температура відємна , перетворимо її на додатну.
- Віделяемо за допомогою бітових масок цілу частину температури , переводимо в символи і відображаємо на дисплеї. Щоб перевести оцифроване значення температури в градуси , потрібно це значення помножити на вагу молодшого розряду. Для цілої частини температури вага молодшого розряду ( BIT4 ) дорівнює 1 градусу Цілься , а значить множити нічого не потрібно.
- Виділяємо дробову частину , перетворимо дробову частину в цілу , переводимо в символи і відображаємо на дисплеї.
Комментарии - (4) Sanyo.95 говорит: Большое спасибо автору за урок, все отлично, но кода для вывода на семисегментник нет, очень хотелось бы взглянуть. Admin говорит: Здравствуйте, Вы чтото путаете здесь используется LCD
Артём говорит: День добрый! Можете вот это:
"послали команду на измерение температуры, и дальше занимаемся своими делами
через полторы секунды спросили у датчика, измерил ли он температуру, если да, то получаем данные и выводим их на семисегментник. Посылать команды датчику мы будем с помощью функции w1_write. Давайте приступим к написанию кода"
написать кодом, сам не допираю как всё это будет выглядеть, заранее спасибо! Артём говорит: на странице кода не видно/нет...
Добавить комментарийДля отправки комментария вы должны авторизоваться.
|