Práca s digitálnym teplotným snímačom DS18B20 po jednovodičovej zbernici One-Wire.
Dostali sa mi do rúk ešte dve digitálne teplotné čidla od firmy Dallas a to DS18b20. Digitálne preto, že na meranie teploty pomocou nich nie je potrebný žiadný AD prevodník. Informáciu o teplote vyčítame priamo z čidla po jednovodičovej zbernici One-Wire. Rozhodol som sa teda popísať toto čidlo a dať sem príklad ako zmerať pomocou tohto čidla teplotu s mikropočítačom s jadrom AVR.
Zapojenie DS18B20 a MCU
Čidlo je vyrábané v troch púzdrach: TO-92, SO-8 a uSOP-8.
Obr. 1 Púzdra DS18B20
Existuju dva spôsoby ako toto čidlo zapojiť:
a) s externým napájaním – čidlo napajame klasicky z externého zdroja
Obr. 2 Externé napajanie
b) s parazitným napájaním – čidlo napájame cez dátový vodič
Obr. 3 Parazitné napájanie
Ja sa ďalej budem venovať iba verzii s externým napájaním.
Na jednu zbernicu je možné zapojiť viacero čidiel, ktoré sa dajú „adresovať“. Každé čidlo obsahuje unikátny 64 bitový ROM CODE.
Posledných 8 bitov ROM kódu je 28h. Ďalších 48 bitov obsahujú unikátne sériové číslo. A most significant bajt je CRC bajt, ktorý je vypočítaný z prvých 56 bitov ROM kódu. Pre detailný popis výpočtu CRC pozri datasheet.
Obr. 4 Formát ROM kódu
Pamať čidla – nazvaná SCRATCHPAD obsahuje 8 bajtov.
Obr. 5 Scratchpad
Bajt 0 a 1 obsahujú 16 bitové číslo s údajom o teplote a jeho formát je zobrazený na obrázkoch nižšie. Rozlíšeni meranej teploty môžeme nastaviť na 9 až 12 bitov, kde defaultne je nastavené na 12 bitov.
Na nastavenie sa vyžíva konfiguračný Bajt 4:
Obr. 6 Formát konfiguračného bajtu 4
Obr. 7 Nastavenie konfig. bajtu 4
Obr. 8 Bajt 0 a 1 – nameraná teplota
Obr. 9 Popis bitov bajtu 0 a 1
TH a TL bajty sa vyžívajú na signalizáciu alarmu. Nastavujú sa užívateľom a ich hodnota je porovnávaná s nameranou hodnotou a podľa toho sa nastavuje S bit. Viac v datasheete.
Komunikácia čidla s MCU
Komunikácia má tri stupne:
a) inicializácia
b) ROM príkaz
c) DS18B20 funkčný príkaz
Inicializácia sa vykonáva PRESENCE PULSE-om a ďalej bude popísaná v realizácii One-Wire.
ROM príkazy – nasledujú po inicializačnej sekvencii. V prípade, že je na jednej zbernici viac čidiel tak teraz sa vybera to z ktorým chceme pracovať.
Existuje 5 ROM príkazov:
a) search ROM [F0h]
b) read ROM [33h] – tento príkaz môže byť použitý iba pri jednom čidle na zbernici – umožňuje prečítať 64 bitový ROM kód
c) match ROM [55h] – tento príkaz spolu so 64 bit ROM kódom umožňuje vybrať to čidlo s ktorým chceme pracovať – odpovedá iba SLAVE, ktorého ROM kód sa zhoduje s odoslaným ROM kódom
d) skip ROM [CCh] – bez adresácie – komunikuje sa so senzorom bez adresácie – potrebné mať iba jedno čidlo na zbernici
e) alarm search [ECh] – podobný príkazu search ROM s tým že odpovedá iba SLAVE s nastaveným alarm bitom
Funkčné príkazy – tieto príkazy umožňujú čítať, zapisovať do pamäte, merať teplotu a zisťovať (stav) napájanie.
Pre meranie teploty sa zapíše príkaz COVERT T [44h] – zmeria sa teplota a zapíše do pamäte, a pre čítanie pamäte (data o teplote) sa vyšle príkaz READ SCRATCHPAD [BEh]. Čítajú sa postupne bajty od 0. Viac v tabuľke.
Obr. 10 Funkčné príkazy pre čidlo DS18b20
Komunikácia cez One-Wire Bus
Komunikácia s MCU sa deje po jednovodičovej zbernici One-Wire a je potrebne čo najpresnejšie časovanie. Ja si vystačím so štand. funkciami delay a pri použití interného oscilátora v MCU je dobré ho aj kalibrovať (u MCU AVR – OSCCAL).
Pred každým prenosom z čidla je potrebné najprv urobiť inicializačnú sekvenciu. Tá pozostáva z reset impulzu (stiahnutím zbernice na nulu a uvoľnením) o dlžke aspoň 480 us generovaného MASTER-om po ktorej nasleduje tzv. PRESENCE PULSE generovaný SLAVE-om – teda senzorom a trvá 60 až 240 us. Nasledujúci obrázok ukazuje časový diagram:
Obr. 11 Reset impulz a presence pulz
V jazyku C takto:
ds18b20_bus_high(); // pustime spat na log 1
_delay_us(60);
presence_status = DS18B20_PIN & (1<<DS18B20_DQ); // a citame status na zbernici
_delay_us(420);
// podla hodnoty presence_status vyhodnocujeme ci dosiel PRESENCE-PULSE
Čítanie/zápis
Obr. 12 Čitanie/zapis na one-wire bus
Zápis bajtu v jazyku C:
Čítanie bajtu v jazyku C:
if (i==8) data = 0;
ds18b20_bus_low();
_delay_us(5);
ds18b20_bus_high();
_delay_us(10);
if (!(DS18B20_PIN & (1<<DS18B20_DQ))) data |= 0x00;
else if (DS18B20_PIN & (1<<DS18B20_DQ)) data |= 0x80;
_delay_us(45);
}
Bajt sa nachádza v premennej „data“.
Príklad na meranie teploty
Vytvoril som príklad, kde je ukázané zmeranie teploty a vypísanie na displej. Meranie teploty som si spravil do jednej funkcie. Používam zapojenie s externým napájaním.
Pre správny chod je dobré nakalibrovať interný oscilátor (no nie je to nutnosť). V subore ds18b20.h je potrebné nastaviť port a pin kde je pripojené čidlo. Nastavuje sa direktívami:
#define DS18B20_PORT PORTA
#define DS18B20_PIN PINA
#define DS18B20_DDR DDRA
#define DS18B20_DQ PA0
Takže ja mám čidlo pripojené na pine PA0.
Na zmeranie teploty z jedného čidla na zbernici s 12bit rozlíšení slúži funkcia:
unsigned char sign;
unsigned int decimal;
unsigned int integer;
ds18b20_reset_pulse();
ds18b20_write(DS18B20_SKIPROM);
ds18b20_write(DS18B20_CONVERTTEMP);
ds18b20_wait_to_convert();
ds18b20_reset_pulse();
ds18b20_write(DS18B20_SKIPROM);
ds18b20_write(DS18B20_RSCRATCHPAD);
low_byte = ds18b20_read();
_delay_us(5);
high_byte = ds18b20_read();
ds18b20_reset_pulse();
if (high_byte & (0xF0)) sign = 1;
else sign = 0;
decimal = (low_byte & 0x0F)*625;
high_byte &= 0x07;
high_byte <<= 4;
low_byte >>= 4;
low_byte &= 0x0F;
integer = low_byte | high_byte;
if(sign == 0) sprintf(buff,"%u.%04u",integer,decimal);
else if(sign == 1) sprintf(buff,"-%u.%04u",integer,decimal);
}
Výsledok je zapísaný ako string v char* buff. Dobre si všimnite postup práce so senzorom.
Hlavný program vyzerá takto:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
char text[17];
lcd_init();
while(1)
{
ds18b20_get_temp(text);
lcd_position(1,1);
lcd_puts(text);
_delay_ms(200);
}
}
Takže každých 200 ms sa zmeria teplota a vypíše sa na displej.
Downloads
Záver
V tomto článku som sa snažil popísať prácu so senzorom DS18B20. Dúfam, že článok bude nápomocný hlavne začínajúcim. V budúcnosti chcem doplniť meranie teploty s viacerými čidlami na jednej zbernici.
Na budúce: Viac čidiel na jednej zbernici a CRC
Ďakujem, dobrý článok hodne mi pomohol :).
použil jsem vaš binární soubor a nahrál do CPU snímač mám zapojen na stejný pin a s odporem na datovém vodiči 4k7 proti +5V
a na displeji mám hodnotu -127 a nemění se?kde mám hledat problém
nejaka komplexna schema by nebola? snimac, displej, DPS? Dakujem