Projekt: Snímač teploty DS18B20: Rozdiel medzi revíziami
Zo stránky SensorWiki
Bez shrnutí editace |
|||
(41 medziľahlých úprav od jedného ďalšieho používateľa nie je zobrazených) | |||
Riadok 3: | Riadok 3: | ||
# Zobrazte teplotu z dvoch snímačov teploty pripojených na zbernicu 1-Wire. | # Zobrazte teplotu z dvoch snímačov teploty pripojených na zbernicu 1-Wire. | ||
'''Literatúra:''' | |||
* | |||
Riadok 23: | Riadok 26: | ||
---- | ---- | ||
Ako už z názvu vyplýva ide o jednovodičové sériove rozhranie s možnosťou polo | Ako už z názvu vyplýva ide o jednovodičové sériove rozhranie s možnosťou polo duplexnej obojsmernej komunikácie. Zbernica sa skladá v podstate z dvoch vodičov a to dátového a zemiaceho. Dátový vodič slúži zároveň na napájanie zariadeni pripojených na tuto zbernicu. | ||
duplexnej obojsmernej komunikácie. Zbernica sa skladá v podstate z dvoch | |||
vodičov a to dátového a zemiaceho. Dátový vodič slúži zároveň na napájanie | |||
zariadeni pripojených na tuto zbernicu. | |||
'''Oblasti použitia napr:''' | '''Oblasti použitia napr:''' | ||
*identifikačné systémy | |||
*senzory (teploty, vlhkosti a podobne ) | |||
*digitálne potenciometre a iné | |||
[[Súbor:1Wire.gif]] | [[Súbor:1Wire.gif]] | ||
Riadok 45: | Riadok 42: | ||
'''Vlastnosti:''' | '''Vlastnosti:''' | ||
*dĺžka vodiča až 100m | |||
*na jednu linku je možné pripojiť do 150 zariadení s unikátnym sériovým číslom zabezpečenie pomocou 8-bitového CRC kódu | |||
*obojsmerná poloduplexná prevádzka | |||
*identifikácia zariadenia na základe 8-bajtového sériového čísla a 1- bajtovej informácie o type zariadenia | |||
*realizácia prepojenia je pomocou krútenej dvoj linky – twisted pair | |||
Riadok 70: | Riadok 61: | ||
==='''Komunikacia'''=== | ==='''Komunikacia'''=== | ||
Komunikácia je inicializovaná mikropočítačom zmenou úrovne napätia na zbernici | Komunikácia je inicializovaná mikropočítačom zmenou úrovne napätia na zbernici na 0 V. Komunikácia je založená na takzvaných „časových slotoch“, čiže od závislosti doby trvania poklesu úrovne napätia je slave zariadením identifikovaný typ operácie (zápis log.1 alebo log.0, čítanie log.1 alebo log.0, reset a identifikácia zariadenia). | ||
na 0 V. Komunikácia je založená na takzvaných „časových slotoch“, čiže od | |||
závislosti doby trvania poklesu úrovne napätia je slave zariadením | |||
identifikovaný typ operácie (zápis log.1 alebo log.0, čítanie log.1 alebo | |||
log.0, reset a identifikácia zariadenia). | |||
: | : | ||
===='''Inicializácia''' ==== | ===='''Inicializácia''' ==== | ||
:- Na začiatku uPC (master) ztiahne zbernicu k zemi (cez pull up rezistor) na | :- Na začiatku uPC (master) ztiahne zbernicu k zemi (cez pull up rezistor) na minimálne 480us, potom ju uvoľní. | ||
:- Na uvoľnenie zbernice a vrátenie do kľudového stavu je potrebných 60us. Po tejto dobe je možné prečítať stav zbernice. | |||
minimálne 480us, potom ju uvoľní. | :- Ak je na zbernici pripojené nejaké zariadenie, odpovedá ztiahnutím zbernice na dobu 60 až 240 us. Ak sa na zbernici nenacháda žiadne zariadenie, zbernica ostáva po celú dobu v kľudovom stave. | ||
:- Na uvoľnenie zbernice a vrátenie do kľudového stavu je potrebných 60us. Po | :- Celková dĺžka trvania inicializačného procesu je minimálne 2x480us, teda až po dobe 960us môže prísť ďalší signál od mástra. | ||
tejto dobe je možné prečítať stav zbernice. | |||
:- Ak je na zbernici pripojené nejaké zariadenie, odpovedá ztiahnutím zbernice | |||
na dobu 60 až 240 us. Ak sa na zbernici nenacháda žiadne zariadenie, zbernica | |||
ostáva po celú dobu v kľudovom stave. | |||
:- Celková dĺžka trvania inicializačného procesu je minimálne 2x480us, teda až | |||
po dobe 960us môže prísť ďalší signál od mástra. | |||
[[Súbor:Reset_Pulse.png]] | [[Súbor:Reset_Pulse.png]] | ||
: | : | ||
===='''Vysielanie'''==== | ===='''Vysielanie'''==== | ||
:'''Log 1''' | :'''Log 1''' | ||
Riadok 110: | Riadok 84: | ||
===='''Čítanie'''==== | ===='''Čítanie'''==== | ||
: - čítanie je inicializované mástrom. Ten najprv stiahne zbernicu po dobu | : - čítanie je inicializované mástrom. Ten najprv stiahne zbernicu po dobu minimálne 1us, následne ju uvoľní. | ||
: - následuje čítanie zbernice mástrom. To je inicializované po minimálne 15us od začiatku slotu (ten je určený počiatkom stiahnutia zbernice mastrom). | |||
minimálne 1us, následne ju uvoľní. | : - ak slave chce vyslať log 1, ponechá zbernicu uvoľnenú až do konca slotu (master prečíta log 1 - uvoľnená zbernica). | ||
: - následuje čítanie zbernice mástrom. To je inicializované po minimálne 15us | : - ak slave chce vyslať log 0, ztiahne zbernicu (master prečíta log 0 - ztiahnutá zbernica). | ||
od začiatku slotu (ten je určený počiatkom stiahnutia zbernice mastrom). | |||
: - ak slave chce vyslať log 1, ponechá zbernicu uvoľnenú až do konca slotu | |||
(master prečíta log 1 - uvoľnená zbernica). | |||
: - ak slave chce vyslať log 0, ztiahne zbernicu (master prečíta log 0 - | |||
ztiahnutá zbernica). | |||
: - celková dĺžka slotu čítania je 60 až 120us. | : - celková dĺžka slotu čítania je 60 až 120us. | ||
[[Súbor:Zapis_Citanie_1wire.png]] | [[Súbor:Zapis_Citanie_1wire.png]] | ||
V našom prípade sme pracovali so snímačmi teploty s označením DS18B20. | V našom prípade sme pracovali so snímačmi teploty s označením DS18B20. | ||
Preto sú na obrázkoch vyššie použité pre lepšie pochopenie komunikácie na | Preto sú na obrázkoch vyššie použité pre lepšie pochopenie komunikácie na zbernici informácie z datasheetu snímača DS18B20 | ||
zbernici informácie z datasheetu snímača DS18B20 | |||
==='''Priebeh komunikacie na zbernici 1Wire'''=== | ==='''Priebeh komunikacie na zbernici 1Wire'''=== | ||
Riadok 212: | Riadok 176: | ||
[[Súbor:PríkladTeploty.png]] | [[Súbor:PríkladTeploty.png]] | ||
== '''Zapojenie a Program''' == | == '''Zapojenie a Program''' == | ||
Riadok 233: | Riadok 182: | ||
=== '''Funkcia zariadenia''' === | === '''Funkcia zariadenia''' === | ||
''' | ''' | ||
Zariadenie ma za úlohu odmerať teplotu na viacerých snímačoch (v tomto prípade | Zariadenie ma za úlohu odmerať teplotu na viacerých snímačoch (v tomto prípade dvoch). Následne tieto hodnoty zobraziť na displeji. <br /> | ||
Snímače sú pripojené k zberici 1-wire. Identifikácia jednotlivých snímačov je základe ich jedinečného sériového čísla. <br /> | |||
dvoch). Následne tieto hodnoty zobraziť na displeji. <br /> | |||
Snímače sú pripojené k zberici 1-wire. Identifikácia jednotlivých snímačov je | |||
základe ich jedinečného sériového čísla. <br /> | |||
Snímače využívajú v zapojení tri vodiče. Dátový vodič, vodič pre napájanie | Snímače využívajú v zapojení tri vodiče. Dátový vodič, vodič pre napájanie | ||
Riadok 249: | Riadok 194: | ||
<br /> | <br /> | ||
''' | '''Schéma celého zapojenia v simulaćnom programe ISIS Proteus''' <br /> | ||
[[Súbor:ZapojenieProteus.png]] | |||
=== '''Program''' === | === '''Program''' === | ||
Program je písaný v jazyku C, v AVR Studio 4, určenom pre prácu so zariadeniami | Program je písaný v jazyku C, v AVR Studio 4, určenom pre prácu so zariadeniami firmy Atmel. <br /> | ||
Použitý je 8-bitový mikrokontrolér s označením ATmega16. <br /> | |||
firmy Atmel. <br /> | |||
Použitý je 8-bitový | |||
Pre komunikáciu so snímačmi teploty je použitý pin 0 portu A. <br /> | Pre komunikáciu so snímačmi teploty je použitý pin 0 portu A. <br /> | ||
Pre komunikáciu s LCD displejom sú využívané piny 0 až 5 portu C. <br /> | Pre komunikáciu s LCD displejom sú využívané piny 0 až 5 portu C. <br /> | ||
Riadok 278: | Riadok 219: | ||
pin 4: enable pin <br /> | pin 4: enable pin <br /> | ||
pin 5: RS pin <br /> | pin 5: RS pin <br /> | ||
<br /> | |||
(poznámka: čísla pinov nekorešpondujú s číslami vývodov mikrokontroléra, tie sú uvedené v datasheete) | |||
<br /> | <br /> | ||
Riadok 288: | Riadok 232: | ||
(z pohľadu mástra) <br /> | (z pohľadu mástra) <br /> | ||
- hlavičkové subory k 1wire zbernici a LCD displeju (1wire.h a lcd.h)<br /> | - hlavičkové subory k 1wire zbernici a LCD displeju [[Médiá:1wire.h|'''(1wire.h''']] [[Médiá:Lcd2.h | '''a lcd.h)''' ]]<br /> | ||
V následujúcej časti nižšie sú popísané vybrané (najdôležitejšie) časti programu. <br /> | |||
===='''1wire.c'''==== | |||
<br /> | |||
'''Inicializácia na zbernici''' | |||
Principiálne znázornenie možného riešenia na vývojovom diagrame <br /> | |||
[[Súbor:reset_1_wire.png]] | [[Súbor:reset_1_wire.png]] | ||
<br /> | |||
(pzn. nekorešponduje úplne s kódom nižšie) <br /> | |||
Funkcia pre 1-wire reset:<br /> | |||
<source lang="c"> | |||
/*----------------------------------------------------------------------------- | |||
* Generovanie 1-wire reseru. Vráti 0 ak bol zaznamenaý presence impulz, ináč vráti 1 | |||
*/ | |||
uint8_t | |||
OWTouchReset(void) { | |||
_delay_us(1); | |||
THERM_LOW(); // ztiahnutie zbernice | |||
THERM_OUTPUT_MODE(); // nastavenie 1wire pinu ako výstup | |||
_delay_us(480); // oneskorenie pre resetovaci impulz | |||
THERM_INPUT_MODE(); // nastavenie 1wire pinu ako vstup - uvoľnenie zbernice | |||
_delay_us(70); | |||
return(THERM_PIN & _BV(THERM_DQ) ? 1 : 0); //podmienene vyhodnotenie | |||
} | |||
</source> | |||
'''Čítanie bajtu a bitu''' | |||
Principiálne znázornenie možného riešenia na vývojovom diagrame <br /> | |||
[[Súbor:Citaniebajtu_z_1_wire.png]] | |||
<br /> | |||
(pzn. nekorešponduje úplne s kódom nižšie) <br /> | |||
Funkcia pre čítanie bajtu:<br /> | |||
<source lang="c"> | |||
/*----------------------------------------------------------------------------- | |||
* Čítanie bajtu z 1-wire zbernice | |||
*/ | |||
uint8_t | |||
OWReadByte(void) { | |||
int i, result = 0; // result - prijatý bajt | |||
for (i = 0; i < 8; i++) { //cyklus pre načítavanie po bitoch | |||
result >>= 1; // rotácia doprava lebo načítava sa od LSB (poslený bit sa zapise na HSB) | |||
/*testovanie vráteného bitu z funkcie pre čítanie bitu na zbernici*/ | |||
if (OWReadBit()) // volanie funkcie na čítanie bitu zo zbernice (či vráti log 1) | |||
result |= 0x80; // použitie masky (1000 0000) - zapis log 1 | |||
} | |||
return(result); // vráti prečítaný bajt | |||
} | |||
</source> | |||
Funkcia pre čítanie bitu:<br /> | |||
<source lang="c"> | |||
/*----------------------------------------------------------------------------- | |||
* Čítanie jedného bitu na 1-wire zbernici a jeho vrátenie | |||
*/ | |||
uint8_t | |||
OWReadBit(void) { | |||
OWdelay(); | |||
// začiatok slotu čítania bitu | |||
THERM_LOW(); // ztiahnutie zbernice | |||
THERM_OUTPUT_MODE(); // nastavenie 1wire pinu ako výstup | |||
_delay_us(6); // oneskorenie pre uvoľnenie zbernice | |||
THERM_INPUT_MODE(); // uvoľnenie zbernice - nastavenie 1wire pinu ako vstup | |||
_delay_us(9); // oneskorenie pre čítanie zo zbernice | |||
return(THERM_PIN & _BV(THERM_DQ) ? 1 : 0); // vráti stav na zbernici (log 0 alebo 1) | |||
/*ak zbernica ostala stiahnutá (drží slave) stav log 0, ináč log 1*/ | |||
} | |||
</source> | |||
'''Vysielanie bajtu a bitu''' | |||
Principiálne znázornenie možného riešenia na vývojovom diagrame <br /> | |||
[[Súbor:vysielanie_na_1_wire.png]] | [[Súbor:vysielanie_na_1_wire.png]] | ||
<br /> | |||
(pzn. nekorešponduje úplne s kódom nižšie) <br /> | |||
Funkcia pre zápis bajtu: <br /> | |||
<source lang="c"> | |||
/*----------------------------------------------------------------------------- | |||
* Zápis bajtu na 1-wire zbernicu | |||
*/ | |||
void | |||
OWWriteByte(uint8_t data) { // data - obsahuje vysielaný bajt | |||
uint8_t i; | |||
/* vyslanie bitu s najnižšou váhou (LSB)*/ | |||
for (i = 0; i < 8; i++) { // cyklus pre rotáciu posielaného bitu na najnižsiu úroveň | |||
OWWriteBit(data & 0x01); // maska pre určenie či sa posiela log 0 alebo 1 | |||
data >>= 1; // rotácia (vysielaného bajtu) o jeden bit doprava | |||
} | |||
} | |||
</source> | |||
Funkcia pre zápis bitu: <br /> | |||
<source lang="c"> | |||
/*----------------------------------------------------------------------------- | |||
* Zápis jedneho bitu na 1-wire zbernicu | |||
*/ | |||
void | |||
OWWriteBit(uint8_t bit) { | |||
OWdelay(); | |||
if (bit) { // testovanie, aký bit sa posiela (0 alebo 1) | |||
// ak sa posiela log 1 | |||
THERM_LOW(); // ztiahnutie zbernice | |||
THERM_OUTPUT_MODE(); // nastavenie 1wire pinu ako výstup | |||
_delay_us(6); // oneskorenie pre log 1 | |||
THERM_INPUT_MODE(); // uvoľnenie zbernice - nastavenie 1wire pinu ako vstup | |||
_delay_us(64); | |||
} else { | |||
// ak sa posiela log 0 | |||
THERM_LOW(); // ztiahnutie zbernice | |||
THERM_OUTPUT_MODE(); // nastavenie 1wire pinu ako výstup | |||
_delay_us(60); // oneskorenie pre log 0 | |||
THERM_INPUT_MODE(); // uvoľnenie zbernice - nastavenie 1wire pinu ako vstup | |||
_delay_us(10); | |||
} | |||
} | |||
</source> | |||
===='''main.c'''==== | |||
Hlavný program. Načítava adresy snímačov na zbernici, Meria telotu a vypisuje na displej. | |||
<br /> | <br /> | ||
Funkcie potrebné k obsluhe displeja sú v súbre lcd.c. Je možné ho stiahnuť nižšie spolu s ostatnými súbormi v jednom archíve. | |||
<br /> | <br /> | ||
<source lang="c"> | <source lang="c"> | ||
#define F_CPU 8000000L | |||
#include <util/delay.h> | |||
#include <avr/io.h> | |||
#include <stdio.h> | |||
#include <stdlib.h> | |||
#include "lcd.h" | |||
#include "1wire.h" | |||
uint8_t ROM1[2][8],pocet_cidel=0; | |||
int8_t cidla; | |||
int16_t teplota1,teplota2; | |||
char text[16]; | |||
char cele[16]; | |||
char desatine[16]; | |||
int p=0; | |||
int main(void) | |||
{ | |||
lcd_init(LCD_DISP_ON); // inicializácia dipleja | |||
_delay_ms(100); | |||
/* hľadanie snímačov na zbernici*/ | |||
cidla = OWFirst(ROM1[0],1,0); // hľadanie prvneho snimaca | |||
if(cidla) // ak bol najdeny | |||
pocet_cidel++; // počet snímačov + 1 | |||
cidla = OWNext(ROM1[pocet_cidel],1,0); // hľanie ďalších snímačov | |||
if(cidla) // ak bol najdeny | |||
pocet_cidel++; // počet snímačov + 1 | |||
do | |||
{ | |||
cidla = OWNext(ROM1[pocet_cidel],1,0); // hľanie ďalších snímačov | |||
if(cidla) // ak bol najdeny | |||
pocet_cidel++; // počet snímačov + 1 | |||
}while(cidla); // dokiaľ boli nájdené dalšie snímače | |||
_delay_ms(10); | |||
while(1) | |||
{ | |||
/* Vypis na disp Senzor 1 a senzor 2 */ | |||
lcd_clrscr(); // zmazanie displeja | |||
lcd_gotoxy(0,0); // pozícia kurzora | |||
lcd_puts("Senzor:1"); | |||
lcd_gotoxy(0,1); // pozícia kurzora | |||
lcd_puts("Senzor:2"); | |||
_delay_ms(2000); | |||
for (p = 0; p < 10; p++) // Cyklus pre načítanie a zobrazenie (10krat) | |||
{ | |||
teplota1=DS18B20_read_temp(ROM1[0]); // načítanie teploty1 zo senzora 0 | |||
_delay_ms(100); | |||
teplota2=DS18B20_read_temp(ROM1[1]); // načítanie teploty2 zo senzora 1 | |||
_delay_ms(100); | |||
//----Vypis zo Senzora 1---- | |||
itoa(teplota1/10,cele,10); // Prevedie Cele cisla na znaky | |||
itoa(teplota1%10,desatine,10); // Prevedie Desatine cisla na znaky | |||
lcd_clrscr(); | |||
lcd_gotoxy(0,0); | |||
lcd_puts(cele); // vypis na disp v tvare XX.X°C | |||
lcd_puts("."); | |||
lcd_puts(desatine); | |||
lcd_putc(0b10110010); // vypis na disp: ° | |||
lcd_puts("C"); | |||
//----Vypis zo Senzora 2---- | |||
itoa(teplota2/10,cele,10); // Prevedie Cele cisla na znaky | |||
itoa(teplota2%10,desatine,10); // Prevedie Desatine cisla na znaky | |||
lcd_gotoxy(0,1); // vypis na disp v tvare XX.X°C | |||
lcd_puts(cele); | |||
lcd_puts("."); | |||
lcd_puts(desatine); | |||
lcd_putc(0b10110010); // vypis na disp: ° | |||
lcd_puts("C"); | |||
_delay_ms(500); | |||
} | |||
} | |||
} | |||
</source> | |||
<br /> | |||
'''Súbory na stiahnutie''' <br /> | |||
[[Médiá: Main.c | main.c]] <br /> | |||
[[Médiá: Lcd2.c | lcd.c]] <br /> | |||
[[Médiá: 1wire.c | 1wire.c]] <br /> | |||
[[Médiá: Lcd2.h | lcd.h]] <br /> | |||
[[Médiá: 1wire.h | 1wire.h]] <br /> | |||
=== '''Realizácia''' === | |||
Najprv sme overovali spravnosť zapojenia a funkčnosť programu cez simulačný software ISIS Proteus 7. | |||
V tomto simulačnom prostredí sme využili možnosti pozorovania zbernice pomocou osciloskopu čo nám veľmi uľahčilo hľadanie chyby pri pri nesprávnej (nefunkčnej) komunikácii. | |||
Výsledkom simulácie je zobrazenie teplôt z dvoch senzorov DS18B20, ako je vidieť na obrázku nižšie. | |||
[[Súbor:VysledokSimulacie.png]] | |||
Po úspešnom doladení programu za pomoci simulácie sme zrealizovali aj skutočné zapojenie, kde používame: | |||
*Procesor ATmega16 | |||
*Dva teplotné snímače DS18B20 | |||
*Displej 16x1 znakov | |||
[[Súbor:Realanezapojenei1Wire.png]] | |||
Aktuálna revízia z 14:05, 18. november 2013
Zadanie
- Zobrazte teplotu z dvoch snímačov teploty pripojených na zbernicu 1-Wire.
Literatúra:
- Vypracovali
- Bc. Ján Baláž
- Bc. Jozef Kupčiha
- Študijný odbor: Aplikovaná mechatronika
- Ročník: 2. Ing.
Vypracovanie
1-Wire Zbernica
Ako už z názvu vyplýva ide o jednovodičové sériove rozhranie s možnosťou polo duplexnej obojsmernej komunikácie. Zbernica sa skladá v podstate z dvoch vodičov a to dátového a zemiaceho. Dátový vodič slúži zároveň na napájanie zariadeni pripojených na tuto zbernicu.
Oblasti použitia napr:
- identifikačné systémy
- senzory (teploty, vlhkosti a podobne )
- digitálne potenciometre a iné
Vlastnosti:
- dĺžka vodiča až 100m
- na jednu linku je možné pripojiť do 150 zariadení s unikátnym sériovým číslom zabezpečenie pomocou 8-bitového CRC kódu
- obojsmerná poloduplexná prevádzka
- identifikácia zariadenia na základe 8-bajtového sériového čísla a 1- bajtovej informácie o type zariadenia
- realizácia prepojenia je pomocou krútenej dvoj linky – twisted pair
Zapojenie:
Zariadenia sú trvalo pripojené na napájacie napätie „PullUp“ rezistor obr.1
Komunikacia
Komunikácia je inicializovaná mikropočítačom zmenou úrovne napätia na zbernici na 0 V. Komunikácia je založená na takzvaných „časových slotoch“, čiže od závislosti doby trvania poklesu úrovne napätia je slave zariadením identifikovaný typ operácie (zápis log.1 alebo log.0, čítanie log.1 alebo log.0, reset a identifikácia zariadenia).
Inicializácia
- - Na začiatku uPC (master) ztiahne zbernicu k zemi (cez pull up rezistor) na minimálne 480us, potom ju uvoľní.
- - Na uvoľnenie zbernice a vrátenie do kľudového stavu je potrebných 60us. Po tejto dobe je možné prečítať stav zbernice.
- - Ak je na zbernici pripojené nejaké zariadenie, odpovedá ztiahnutím zbernice na dobu 60 až 240 us. Ak sa na zbernici nenacháda žiadne zariadenie, zbernica ostáva po celú dobu v kľudovom stave.
- - Celková dĺžka trvania inicializačného procesu je minimálne 2x480us, teda až po dobe 960us môže prísť ďalší signál od mástra.
Vysielanie
- Log 1
- - stiahnutie zbernice po dobu mnimálne 1us.
- - uvoľnenie zbernice.
- - dĺžka slotu pre zápis je v rozsahu 60 až 120us.
- Log 0
- - stiahnutie zbernice po dobu mnimálne 60us.
- - uvoľnenie zbernice.
- - dĺžka slotu pre zápis je v rozsahu 60 až 120us.
Čítanie
- - čítanie je inicializované mástrom. Ten najprv stiahne zbernicu po dobu minimálne 1us, následne ju uvoľní.
- - následuje čítanie zbernice mástrom. To je inicializované po minimálne 15us od začiatku slotu (ten je určený počiatkom stiahnutia zbernice mastrom).
- - ak slave chce vyslať log 1, ponechá zbernicu uvoľnenú až do konca slotu (master prečíta log 1 - uvoľnená zbernica).
- - ak slave chce vyslať log 0, ztiahne zbernicu (master prečíta log 0 - ztiahnutá zbernica).
- - celková dĺžka slotu čítania je 60 až 120us.
V našom prípade sme pracovali so snímačmi teploty s označením DS18B20. Preto sú na obrázkoch vyššie použité pre lepšie pochopenie komunikácie na zbernici informácie z datasheetu snímača DS18B20
Priebeh komunikacie na zbernici 1Wire
Každé zariadenie obsahuje výrobcom nastavenú 64-bitovú informáciu v internej ROM pamäti. Prvých horných 8 bitov slúži na zabezpečenie CRC kódom, potom nasleduje 48-bitové sériové číslo zariadenia a dolných 8 bitov tvorí kód identifikujúci typ zariadenia. Táto 64-bitová informácia je unikátna pre každé vyrobené zariadenie s možnosťou tak jednoznačnej identifikácie aj viacerých zariadení rovnakého typu pripojených na jednu linku.
Komunikácia má tri stupne:
- Inicializácia
Vykonáva sa pri resete PRESENCE pulsom od slave zariadenia
- ROM príkaz
V prípade, že je na jednej zbernici viac zariadení tak použíjme tieto príkazy pre prácu s jednotlivými zariadeniam. Príkazy: a) Search ROM [F0h] - Vyhladavanie adries zariadení pripojených na zbernicu b) Read ROM [33h] – tento príkaz môže byť použitý iba pri jednom zariadení 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 zariadenie 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 s zariadením bez adresácie – iba jedno zariadenie 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íkaz
Tieto príkazy umožňujú čítať, zapisovať do pamäte, merať teplotu a zisťovať (stav) napájanie. Napr: a) CONVERT [44h] – zmeria sa teplota a zapíše do pamäte. b) READ SCRATCHPAD [BEh] - Čítanie pamäte (data o teplote). Čítajú sa postupne bajty od LSB. c) A iné
Senzor teploty DS18B20
Popis
- napájanie je 3,0V – 5,5V
- rozsah meranej teploty od –55°C do +125°C (-67°F do +257°F)
- presnosť 0,5°C v rozmedzí –10°C do +85°C
- rozlíšenie senzora je voliteľné v rozsahu 9 až 12 bit
- meranie teploty s rozlíšením 12 bit trvá 750ms
Všetky informácie su uvedené v DataSheete obvodu Ktorý si môžte stiahnuť tu
Vyhotovenie senzora
Senzor sa vyrába v troch púzdrach: TO-92, SO-8 a uSOP-8.
Pamäť senzora
Pamäť senzora – nazvaná SCRATCHPAD obsahuje 8 bajtov.
Bajt 0 a 1 obsahujú 16 bitové číslo s údajom o teplote. Ďalšie Bajty sú vysvetlené v obrázku nižšie
Bajt číslo 4
Nastavenia konfiguračných bitov v Bajte čislo 4
Obsah Bajtu 0 a 1
Vysvetlenie obsahu bajtu 0 a 1
Príklady získania teploty
Zapojenie a Program
Funkcia zariadenia
Zariadenie ma za úlohu odmerať teplotu na viacerých snímačoch (v tomto prípade dvoch). Následne tieto hodnoty zobraziť na displeji.
Snímače sú pripojené k zberici 1-wire. Identifikácia jednotlivých snímačov je základe ich jedinečného sériového čísla.
Snímače využívajú v zapojení tri vodiče. Dátový vodič, vodič pre napájanie
snímača a spoločný neutrálny vodič.
Schéma celého zapojenia v simulaćnom programe ISIS Proteus
Program
Program je písaný v jazyku C, v AVR Studio 4, určenom pre prácu so zariadeniami firmy Atmel.
Použitý je 8-bitový mikrokontrolér s označením ATmega16.
Pre komunikáciu so snímačmi teploty je použitý pin 0 portu A.
Pre komunikáciu s LCD displejom sú využívané piny 0 až 5 portu C.
Využívané piny
Port A
pin 0: 1-wire komunikacia
Port C
pin 0: treti datovy bit
pin 1: druhy datovy bit
pin 2: prvy datovy bit
pin 3: nulty datovy bit
pin 4: enable pin
pin 5: RS pin
(poznámka: čísla pinov nekorešpondujú s číslami vývodov mikrokontroléra, tie sú uvedené v datasheete)
Štruktúra programu
Program je pre lepšiu prehľadnosť napísaný vo viacerých súboroch.
Skladá sa z týchto časti:
- main.c ktorý obsahuje hlavný program
- lcd.c ktorý obsahuje funkcie pre obsluhu a komunkáciu s LCD displejom
- 1wire.c ktorý obsahuje funkcie potrebné pre správnu komunikáciu na zbernici
(z pohľadu mástra)
- hlavičkové subory k 1wire zbernici a LCD displeju (1wire.h a lcd.h)
V následujúcej časti nižšie sú popísané vybrané (najdôležitejšie) časti programu.
1wire.c
Inicializácia na zbernici
Principiálne znázornenie možného riešenia na vývojovom diagrame
(pzn. nekorešponduje úplne s kódom nižšie)
Funkcia pre 1-wire reset:
/*-----------------------------------------------------------------------------
* Generovanie 1-wire reseru. Vráti 0 ak bol zaznamenaý presence impulz, ináč vráti 1
*/
uint8_t
OWTouchReset(void) {
_delay_us(1);
THERM_LOW(); // ztiahnutie zbernice
THERM_OUTPUT_MODE(); // nastavenie 1wire pinu ako výstup
_delay_us(480); // oneskorenie pre resetovaci impulz
THERM_INPUT_MODE(); // nastavenie 1wire pinu ako vstup - uvoľnenie zbernice
_delay_us(70);
return(THERM_PIN & _BV(THERM_DQ) ? 1 : 0); //podmienene vyhodnotenie
}
Čítanie bajtu a bitu
Principiálne znázornenie možného riešenia na vývojovom diagrame
(pzn. nekorešponduje úplne s kódom nižšie)
Funkcia pre čítanie bajtu:
/*-----------------------------------------------------------------------------
* Čítanie bajtu z 1-wire zbernice
*/
uint8_t
OWReadByte(void) {
int i, result = 0; // result - prijatý bajt
for (i = 0; i < 8; i++) { //cyklus pre načítavanie po bitoch
result >>= 1; // rotácia doprava lebo načítava sa od LSB (poslený bit sa zapise na HSB)
/*testovanie vráteného bitu z funkcie pre čítanie bitu na zbernici*/
if (OWReadBit()) // volanie funkcie na čítanie bitu zo zbernice (či vráti log 1)
result |= 0x80; // použitie masky (1000 0000) - zapis log 1
}
return(result); // vráti prečítaný bajt
}
Funkcia pre čítanie bitu:
/*-----------------------------------------------------------------------------
* Čítanie jedného bitu na 1-wire zbernici a jeho vrátenie
*/
uint8_t
OWReadBit(void) {
OWdelay();
// začiatok slotu čítania bitu
THERM_LOW(); // ztiahnutie zbernice
THERM_OUTPUT_MODE(); // nastavenie 1wire pinu ako výstup
_delay_us(6); // oneskorenie pre uvoľnenie zbernice
THERM_INPUT_MODE(); // uvoľnenie zbernice - nastavenie 1wire pinu ako vstup
_delay_us(9); // oneskorenie pre čítanie zo zbernice
return(THERM_PIN & _BV(THERM_DQ) ? 1 : 0); // vráti stav na zbernici (log 0 alebo 1)
/*ak zbernica ostala stiahnutá (drží slave) stav log 0, ináč log 1*/
}
Vysielanie bajtu a bitu
Principiálne znázornenie možného riešenia na vývojovom diagrame
(pzn. nekorešponduje úplne s kódom nižšie)
Funkcia pre zápis bajtu:
/*-----------------------------------------------------------------------------
* Zápis bajtu na 1-wire zbernicu
*/
void
OWWriteByte(uint8_t data) { // data - obsahuje vysielaný bajt
uint8_t i;
/* vyslanie bitu s najnižšou váhou (LSB)*/
for (i = 0; i < 8; i++) { // cyklus pre rotáciu posielaného bitu na najnižsiu úroveň
OWWriteBit(data & 0x01); // maska pre určenie či sa posiela log 0 alebo 1
data >>= 1; // rotácia (vysielaného bajtu) o jeden bit doprava
}
}
Funkcia pre zápis bitu:
/*-----------------------------------------------------------------------------
* Zápis jedneho bitu na 1-wire zbernicu
*/
void
OWWriteBit(uint8_t bit) {
OWdelay();
if (bit) { // testovanie, aký bit sa posiela (0 alebo 1)
// ak sa posiela log 1
THERM_LOW(); // ztiahnutie zbernice
THERM_OUTPUT_MODE(); // nastavenie 1wire pinu ako výstup
_delay_us(6); // oneskorenie pre log 1
THERM_INPUT_MODE(); // uvoľnenie zbernice - nastavenie 1wire pinu ako vstup
_delay_us(64);
} else {
// ak sa posiela log 0
THERM_LOW(); // ztiahnutie zbernice
THERM_OUTPUT_MODE(); // nastavenie 1wire pinu ako výstup
_delay_us(60); // oneskorenie pre log 0
THERM_INPUT_MODE(); // uvoľnenie zbernice - nastavenie 1wire pinu ako vstup
_delay_us(10);
}
}
main.c
Hlavný program. Načítava adresy snímačov na zbernici, Meria telotu a vypisuje na displej.
Funkcie potrebné k obsluhe displeja sú v súbre lcd.c. Je možné ho stiahnuť nižšie spolu s ostatnými súbormi v jednom archíve.
#define F_CPU 8000000L
#include <util/delay.h>
#include <avr/io.h>
#include <stdio.h>
#include <stdlib.h>
#include "lcd.h"
#include "1wire.h"
uint8_t ROM1[2][8],pocet_cidel=0;
int8_t cidla;
int16_t teplota1,teplota2;
char text[16];
char cele[16];
char desatine[16];
int p=0;
int main(void)
{
lcd_init(LCD_DISP_ON); // inicializácia dipleja
_delay_ms(100);
/* hľadanie snímačov na zbernici*/
cidla = OWFirst(ROM1[0],1,0); // hľadanie prvneho snimaca
if(cidla) // ak bol najdeny
pocet_cidel++; // počet snímačov + 1
cidla = OWNext(ROM1[pocet_cidel],1,0); // hľanie ďalších snímačov
if(cidla) // ak bol najdeny
pocet_cidel++; // počet snímačov + 1
do
{
cidla = OWNext(ROM1[pocet_cidel],1,0); // hľanie ďalších snímačov
if(cidla) // ak bol najdeny
pocet_cidel++; // počet snímačov + 1
}while(cidla); // dokiaľ boli nájdené dalšie snímače
_delay_ms(10);
while(1)
{
/* Vypis na disp Senzor 1 a senzor 2 */
lcd_clrscr(); // zmazanie displeja
lcd_gotoxy(0,0); // pozícia kurzora
lcd_puts("Senzor:1");
lcd_gotoxy(0,1); // pozícia kurzora
lcd_puts("Senzor:2");
_delay_ms(2000);
for (p = 0; p < 10; p++) // Cyklus pre načítanie a zobrazenie (10krat)
{
teplota1=DS18B20_read_temp(ROM1[0]); // načítanie teploty1 zo senzora 0
_delay_ms(100);
teplota2=DS18B20_read_temp(ROM1[1]); // načítanie teploty2 zo senzora 1
_delay_ms(100);
//----Vypis zo Senzora 1----
itoa(teplota1/10,cele,10); // Prevedie Cele cisla na znaky
itoa(teplota1%10,desatine,10); // Prevedie Desatine cisla na znaky
lcd_clrscr();
lcd_gotoxy(0,0);
lcd_puts(cele); // vypis na disp v tvare XX.X°C
lcd_puts(".");
lcd_puts(desatine);
lcd_putc(0b10110010); // vypis na disp: °
lcd_puts("C");
//----Vypis zo Senzora 2----
itoa(teplota2/10,cele,10); // Prevedie Cele cisla na znaky
itoa(teplota2%10,desatine,10); // Prevedie Desatine cisla na znaky
lcd_gotoxy(0,1); // vypis na disp v tvare XX.X°C
lcd_puts(cele);
lcd_puts(".");
lcd_puts(desatine);
lcd_putc(0b10110010); // vypis na disp: °
lcd_puts("C");
_delay_ms(500);
}
}
}
Súbory na stiahnutie
main.c
lcd.c
1wire.c
lcd.h
1wire.h
Realizácia
Najprv sme overovali spravnosť zapojenia a funkčnosť programu cez simulačný software ISIS Proteus 7. V tomto simulačnom prostredí sme využili možnosti pozorovania zbernice pomocou osciloskopu čo nám veľmi uľahčilo hľadanie chyby pri pri nesprávnej (nefunkčnej) komunikácii. Výsledkom simulácie je zobrazenie teplôt z dvoch senzorov DS18B20, ako je vidieť na obrázku nižšie.
Po úspešnom doladení programu za pomoci simulácie sme zrealizovali aj skutočné zapojenie, kde používame:
- Procesor ATmega16
- Dva teplotné snímače DS18B20
- Displej 16x1 znakov