Meranie teploty pomocou teplomera DS18S20: Rozdiel medzi revíziami

Z Kiwiki
Skočit na navigaci Skočit na vyhledávání
d
 
(7 medziľahlých úprav od 2 ďalších používateľov nie je zobrazených)
Riadok 1: Riadok 1:
 +
[[Kategória:Konfigurovateľné mikroprocesorové systémy]]
 +
[[Kategória:Sériové komunikačné zbernice]]
 +
{{sablona_mikroprocoserove_systemy|Sériové komunikačné zbernice|Synchrónna komunikácia I2C|Meranie teploty pomocou LM92|Hodiny reálneho času|Synchrónna komunikácia SPI|Distribuovaný systém zber dát 1-Wire|Protokol 1-Wire|Meranie teploty pomocou teplomera DS18S20}}
 
== Základný popis úlohy ==
 
== Základný popis úlohy ==
  
Riadok 41: Riadok 44:
  
 
Po umiestnení tohto bloku do projektu musíme vykonať zopár nastavení. Názorne sú ukázané na obr. 2.
 
Po umiestnení tohto bloku do projektu musíme vykonať zopár nastavení. Názorne sú ukázané na obr. 2.
 +
 +
[[Súbor:Nastavenia_1-wireSW.jpg|center|thumb|400px|Obr. 2. Nastavenia 1-wireSW]]
 +
 +
 +
'''LCD blok'''
 +
 +
Pre komunikáciu s LCD musíme použiť blok LCD. Jeho nastavenie je jednoduché, nastavíme len, ktorý port sa na komunikáciu bude používať a či chceme povoliť alebo zakázať bar grafy.
 +
 +
 +
== Samotný program teplomera ==
 +
 +
Program je napísaný v jazyku C, chcel by som pridať aj kód v assembleri, ale zatiaľ aspoň takto.
 +
 +
<source lang="C">
 +
#include <m8c.h>     
 +
#include "PSoCAPI.h"
 +
 +
// funkcia PREVOD služi na výpis teploty v desiatkovej sústave na LCD
 +
// a zároveň počíta vyššiu presnosť nameranej teploty
 +
 +
void PREVOD(BYTE vstup, BYTE znamienko, BYTE count_remain) 
 +
{
 +
long a, b=0, c, i, d;
 +
char vystup[]="00.0", cisla[]="0123456789";
 +
float teplota, remain, presnost;
 +
remain=count_remain;
 +
teplota=vstup;
 +
teplota=(teplota/2.0)-0.25;
 +
presnost=(16.0-remain)/16.0;
 +
teplota=teplota+presnost;
 +
if(znamienko==0xFF)
 +
{
 +
teplota=256-vstup;
 +
teplota=(teplota/2.0)-0.25;
 +
teplota=teplota+presnost;
 +
}
 +
teplota=teplota*10.0;
 +
for(i=100;i>=1;i=i/10)
 +
 +
a=teplota/i;
 +
c=a-b*10;
 +
b=a;
 +
if(i==100) d=0;
 +
if(i==10) d=1;
 +
if(i==1) d=3;
 +
 +
 +
if(c==0)vystup[d]=cisla[0];
 +
if(c==1)vystup[d]=cisla[1];
 +
if(c==2)vystup[d]=cisla[2];
 +
if(c==3)vystup[d]=cisla[3];
 +
if(c==4)vystup[d]=cisla[4];
 +
if(c==5)vystup[d]=cisla[5];
 +
if(c==6)vystup[d]=cisla[6];
 +
if(c==7)vystup[d]=cisla[7];
 +
if(c==8)vystup[d]=cisla[8];
 +
if(c==9)vystup[d]=cisla[9];
 +
}
 +
 +
  LCD_Position(1,3);
 +
  LCD_PrString(vystup);
 +
 
 +
}
 +
// začiatok hlavnej funkcie
 +
 +
void main(void)
 +
{
 +
BYTE vystup, znamienko,count_remain,byte;
 +
int p=1;
 +
char eteplota[]="Teplota vonku:", plus[]="+", minus[]="-";
 +
char prazdny[]="                ", iteplota[]="Teplota vnutri";
 +
M8C_EnableGInt ;
 +
OW_Start();
 +
LCD_Start();
 +
LCD_Init();
 +
while(1)
 +
{                       //na pin P1.0 privedieme cez tlačitko 5V
 +
PRT1DR=0;            //na port 1 sa zapíše 0
 +
if(PRT1DR==1) p++;    //ak sa na porte 1 objaví 1, inkrementuje sa p
 +
if (p>2) p=1;        //pre správnu funkčnosť musí byť pin P1.0 nastavený na režim Hi_Z digital
 +
OW_Reset();
 +
if(p==1)              //ak bude p=1, komunikácia bude prebiehať s vonkajším teplomerom
 +
{
 +
OW_WriteByte(0x55);  //príkaz Match ROM
 +
OW_WriteByte(0x10);  //zadanie adresy teplomera
 +
OW_WriteByte(0x5F);
 +
OW_WriteByte(0xD4);
 +
OW_WriteByte(0xCD);
 +
OW_WriteByte(0x01);
 +
OW_WriteByte(0x08);
 +
OW_WriteByte(0x00);
 +
OW_WriteByte(0xC9);
 +
OW_WriteByte(0x44);  //príkaz pre konverziu teploty
 +
OW_Delay10mTimes(75); //čakanie 750us
 +
OW_Reset();          //reset rozhrania
 +
OW_WriteByte(0x55);  //Match ROM
 +
OW_WriteByte(0x10);  //zaddanie adresy teplomera
 +
OW_WriteByte(0x5F);
 +
OW_WriteByte(0xD4);
 +
OW_WriteByte(0xCD);
 +
OW_WriteByte(0x01);
 +
OW_WriteByte(0x08);
 +
OW_WriteByte(0x00);
 +
OW_WriteByte(0xC9);
 +
OW_WriteByte(0xBE);  //príkaz pre čítanie Scratch Pad
 +
vystup = OW_ReadByte(); // čítanie jednotlivých bytov (teplota)
 +
znamienko = OW_ReadByte(); //(znamienko)
 +
byte = OW_ReadByte();
 +
byte = OW_ReadByte();
 +
byte = OW_ReadByte();
 +
byte = OW_ReadByte();
 +
count_remain = OW_ReadByte(); //(byte pre zvýšenie presnosti teplomera)
 +
LCD_Position(0,0);    //nastavenie kurzora na LCD na pozíciu 0,0
 +
LCD_PrString(prazdny); //vytlacenie prázdneho reťazca na LCD
 +
LCD_Position(0,0);    //nastavenie kurzora na LCD na pozíciu 0,0
 +
LCD_PrString(eteplota);//vytlacenie retazca eteplota na LCD
 +
LCD_Position(1,1);    //nastavenie kurzora na LCD na pozíciu 1,1
 +
if(znamienko==0x00)    //ak bude znamienko=0, vytlaci sa na LCD +
 +
LCD_PrString(plus);
 +
else
 +
LCD_PrString(minus);  //inak sa vytlaci na LCD -
 +
PREVOD(vystup, znamienko, count_remain); //nacitane 3 byty sa odovzdajú funkcií PREVOD, ktorá vyslednú teplotu vypíše na LCD
 +
}
 +
if(p==2)              //ak p=2, komunikácia bude prebiehať s vnútorným teplomerom
 +
{                      //postup je presne taký ako aj pri predchádzajúcom teplomery
 +
OW_WriteByte(0x55);
 +
OW_WriteByte(0x10);    //zadanie adresy teplomera
 +
OW_WriteByte(0x59);
 +
OW_WriteByte(0xF7);
 +
OW_WriteByte(0xCD);
 +
OW_WriteByte(0x01);
 +
OW_WriteByte(0x08);
 +
OW_WriteByte(0x00);
 +
OW_WriteByte(0xCD);
 +
OW_WriteByte(0x44);    // Start Conversion
 +
OW_Delay10mTimes(75);
 +
OW_Reset();
 +
OW_WriteByte(0x55);
 +
OW_WriteByte(0x10);
 +
OW_WriteByte(0x59);
 +
OW_WriteByte(0xF7);
 +
OW_WriteByte(0xCD);
 +
OW_WriteByte(0x01);
 +
OW_WriteByte(0x08);
 +
OW_WriteByte(0x00);
 +
OW_WriteByte(0xCD);
 +
OW_WriteByte(0xBE);    // Read Scratch Pad
 +
vystup = OW_ReadByte();
 +
znamienko = OW_ReadByte();
 +
byte = OW_ReadByte();
 +
byte = OW_ReadByte();
 +
byte = OW_ReadByte();
 +
byte = OW_ReadByte();
 +
count_remain = OW_ReadByte();
 +
LCD_Position(0,0);
 +
LCD_PrString(iteplota);
 +
LCD_Position(1,1);
 +
if(znamienko==0x00)
 +
LCD_PrString(plus);
 +
else
 +
LCD_PrString(minus);
 +
PREVOD(vystup, znamienko, count_remain);
 +
}
 +
 +
}
 +
}
 +
 +
</source>
 +
 +
Teraz uvediem kód v assembleri. Tento program je podstatne dlhší a nefunguje rovnako ako vyššie uvedený program v jazyku C. Z jednotlivých teplomerov sú len vyčítané byty, ktoré sa vypíšu na LCD a aj na rozhranie RS232. Medzi jednotlivými teplomermi prepíname pomocou sériového rozhrania. Ak stlačíme i, zobrazia sa údaje z vnútorného teplomera, ak stlačíme o, zobrazia sa údaje z vonkajšieho teplomera.
 +
Na sériovom rozhrané sú údaje vypísané v napríklad nasledovnom tvare:
 +
 +
00      (znamienko)
 +
 +
3A      (teplota)
 +
 +
0D      (byte count_remain pre zvýšenie presnosti nameranej teploty)
 +
 +
Na LCD to vyzerá nasledovne:
 +
 +
Teplota vonku:
 +
 +
+  3A  0D
 +
 +
Samozrejme, údaje sú vypisované v hexadecimálnom tvare.
 +
 +
<source lang="asm">
 +
include "m8c.inc"      ; part specific constants and macros
 +
include "memory.inc"    ; Constants & macros for SMM/LMM and Compiler
 +
include "PSoCAPI.inc"  ; PSoC API definitions for all User Modules
 +
 +
export _main
 +
 +
area bss(ram) ;premenne
 +
teplota: blk 1
 +
znamienko: blk 1
 +
presnost: blk 1
 +
 +
area lit ;definovanie retazcov
 +
out: DS "Teplota vonku"
 +
DB 0x00
 +
in:  DS "Teplota vnutri"
 +
DB 0x00
 +
plus: DS "+"
 +
DB 0x00
 +
minus: DS "-"
 +
DB 0x00
 +
text: DS "Komunikacia OK"
 +
DB 0x00
 +
 +
area text
 +
 +
;--------------------------------zaciatok hlavnej funkcie--------------------------------------------
 +
_main:
 +
M8C_EnableGInt
 +
call LCD_Start
 +
mov  A, UART_PARITY_NONE 
 +
lcall  UART_Start
 +
WaitForData:         ; cakanie na povel
 +
    lcall  UART_bReadRxStatus   
 +
    and  A, UART_RX_COMPLETE   
 +
    jz    WaitForData
 +
 +
    lcall  UART_bReadRxData                    ; citanie dat   
 +
    lcall  UART_SendData 
 +
 +
cmp A,'q' ; kontrola komunikacie
 +
jz state_q
 +
 +
cmp A,'o' ; vycitanie bytov z DS18S20(vonkajsi teplomer)
 +
jz state_w
 +
 +
cmp A,'i' ; vycitanie bytov z DS18S20(vnutorny teplomer)
 +
jz state_s
 +
 +
;--------------------------------------------------------------------------------------------
 +
state_w:
 +
lcall OW_Start
 +
lcall OW_Reset
 +
mov  A,55h                            ;skip ROM 
 +
lcall  OW_WriteByte
 +
 +
mov  A,10h        ;zadanie adresy teplomera   
 +
lcall  OW_WriteByte
 +
mov  A,5Fh           
 +
lcall  OW_WriteByte
 +
mov  A,D4h           
 +
lcall  OW_WriteByte
 +
mov  A,CDh           
 +
lcall  OW_WriteByte
 +
mov  A,01h           
 +
lcall  OW_WriteByte
 +
mov  A,08h           
 +
lcall  OW_WriteByte
 +
mov  A,00h           
 +
lcall  OW_WriteByte
 +
mov  A,C9h           
 +
lcall  OW_WriteByte
 +
mov  A,44h                ;start konverzie teploty 
 +
 +
lcall  OW_WriteByte
 +
mov  A,4Bh                  ;oneskorenie 750ms
 +
 +
lcall  OW_Delay10mTimes           
 +
 +
lcall OW_Reset
 +
 +
mov  A,55h           
 +
lcall  OW_WriteByte
 +
 +
mov  A,10h        ;zadanie adresy teplomera   
 +
lcall  OW_WriteByte
 +
mov  A,5Fh           
 +
lcall  OW_WriteByte
 +
mov  A,D4h           
 +
lcall  OW_WriteByte
 +
mov  A,CDh           
 +
lcall  OW_WriteByte
 +
mov  A,01h           
 +
lcall  OW_WriteByte
 +
mov  A,08h           
 +
lcall  OW_WriteByte
 +
mov  A,00h           
 +
lcall  OW_WriteByte
 +
mov  A,C9h           
 +
lcall  OW_WriteByte
 +
 +
mov  A,BEh                ;start konverzie teploty 
 +
lcall  OW_WriteByte
 +
 +
lcall  OW_ReadByte
 +
mov [teplota], A
 +
lcall  OW_ReadByte
 +
mov [znamienko], A
 +
lcall  OW_ReadByte
 +
lcall  OW_ReadByte
 +
lcall  OW_ReadByte
 +
lcall  OW_ReadByte
 +
lcall  OW_ReadByte
 +
mov [presnost], A
 +
lcall UART_PutCRLF
 +
mov A,[znamienko]
 +
lcall UART_PutSHexByte
 +
lcall UART_PutCRLF
 +
mov A,[teplota]
 +
lcall UART_PutSHexByte
 +
lcall UART_PutCRLF
 +
mov A,[presnost]
 +
lcall UART_PutSHexByte
 +
 +
mov A,00h ; riadok
 +
mov X,00h ; bunka
 +
lcall LCD_Position
 +
mov A, >out
 +
mov X, <out
 +
call LCD_PrCString
 +
cmp [znamienko], 00h
 +
jz tlac_plus
 +
jnz tlac_minus
 +
tlac_plus:
 +
mov A,01h ; riadok
 +
mov X,00h ; bunka
 +
lcall LCD_Position
 +
mov A, >plus
 +
mov X, <plus
 +
call LCD_PrCString
 +
jmp Pokracuj
 +
tlac_minus:
 +
mov A,01h ; riadok
 +
mov X,00h ; bunka
 +
lcall LCD_Position
 +
mov A, >minus
 +
mov X, <minus
 +
call LCD_PrCString
 +
jmp Pokracuj
 +
Pokracuj:
 +
mov A,01h ; riadok
 +
mov X,03h ; bunka
 +
lcall LCD_Position
 +
mov A, [teplota] ; nacita byt pre tlac
 +
lcall LCD_PrHexByte
 +
mov A,01h ; riadok
 +
mov X,07h ; bunka
 +
lcall LCD_Position
 +
mov A, [presnost] ; nacita byt pre tlac
 +
lcall LCD_PrHexByte
 +
jmp WaitForData
 +
;------------------------------------------------------------------------------------
 +
state_s:
 +
lcall OW_Start
 +
lcall OW_Reset
 +
mov  A,55h           
 +
lcall  OW_WriteByte
 +
 +
mov  A,10h        ;zadanie adresy teplomera   
 +
lcall  OW_WriteByte
 +
mov  A,59h           
 +
lcall  OW_WriteByte
 +
mov  A,F7h           
 +
lcall  OW_WriteByte
 +
mov  A,CDh           
 +
lcall  OW_WriteByte
 +
mov  A,01h           
 +
lcall  OW_WriteByte
 +
mov  A,08h           
 +
lcall  OW_WriteByte
 +
mov  A,00h           
 +
lcall  OW_WriteByte
 +
mov  A,CDh           
 +
lcall  OW_WriteByte
 +
mov  A,44h          ;start konverzie teploty 
 +
 +
lcall  OW_WriteByte
 +
mov  A,4Bh            ; Load delay time (example 3 would be 30mSec).
 +
 +
lcall  OW_Delay10mTimes      ; Call function
 +
 +
lcall OW_Reset
 +
 +
mov  A,55h           
 +
lcall  OW_WriteByte
 +
 +
mov  A,10h        ;zadanie adresy teplomera   
 +
lcall  OW_WriteByte
 +
mov  A,59h           
 +
lcall  OW_WriteByte
 +
mov  A,F7h           
 +
lcall  OW_WriteByte
 +
mov  A,CDh           
 +
lcall  OW_WriteByte
 +
mov  A,01h           
 +
lcall  OW_WriteByte
 +
mov  A,08h           
 +
lcall  OW_WriteByte
 +
mov  A,00h           
 +
lcall  OW_WriteByte
 +
mov  A,CDh           
 +
lcall  OW_WriteByte
 +
 +
mov  A,BEh          ;start konverzie teploty 
 +
lcall  OW_WriteByte
 +
 +
lcall  OW_ReadByte
 +
mov [teplota], A
 +
lcall  OW_ReadByte
 +
mov [znamienko], A
 +
lcall  OW_ReadByte
 +
lcall  OW_ReadByte
 +
lcall  OW_ReadByte
 +
lcall  OW_ReadByte
 +
lcall  OW_ReadByte
 +
mov [presnost], A
 +
lcall UART_PutCRLF
 +
mov A,[znamienko]
 +
lcall UART_PutSHexByte
 +
lcall UART_PutCRLF
 +
mov A,[teplota]
 +
lcall UART_PutSHexByte
 +
lcall UART_PutCRLF
 +
mov A,[presnost]
 +
lcall UART_PutSHexByte
 +
 +
mov A,00h ; riadok
 +
mov X,00h ; bunka
 +
lcall LCD_Position
 +
mov A, >in
 +
mov X, <in
 +
call LCD_PrCString
 +
cmp [znamienko], 00h
 +
jz tlac_plus2
 +
jnz tlac_minus2
 +
tlac_plus2:
 +
mov A,01h ; riadok
 +
mov X,00h ; bunka
 +
lcall LCD_Position
 +
mov A, >plus
 +
mov X, <plus
 +
call LCD_PrCString
 +
jmp Pokracuj2
 +
tlac_minus2:
 +
mov A,01h ; riadok
 +
mov X,00h ; bunka
 +
lcall LCD_Position
 +
mov A, >minus
 +
mov X, <minus
 +
call LCD_PrCString
 +
jmp Pokracuj2
 +
Pokracuj2:
 +
mov A,01h ; riadok
 +
mov X,03h ; bunka
 +
lcall LCD_Position
 +
mov A, [teplota] ; nacita byt pre tlac
 +
lcall LCD_PrHexByte
 +
mov A,01h ; riadok
 +
mov X,07h ; bunka
 +
lcall LCD_Position
 +
mov A, [presnost] ; nacita byt pre tlac
 +
lcall LCD_PrHexByte
 +
jmp WaitForData
 +
;------------------------------------------------------------------------------------
 +
state_q:
 +
lcall UART_PutCRLF
 +
mov A, >text
 +
mov X, <text
 +
lcall UART_CPutString
 +
lcall UART_PutCRLF
 +
jmp  WaitForData
 +
 +
</source>
  
 
== Odkazy a referencie ==
 
== Odkazy a referencie ==
 
<references/>
 
<references/>

Aktuálna revízia z 10:02, 21. marec 2013

Predmet

Konfigurovateľné mikroprocesorové systémy
Tématická časť:
Sériové komunikačné zbernice

Základný popis úlohy

Tento systém bude obsahovať dva teplomery DS18S20 a teplota sa bude vypisovať na display. Prepínať medzi jednotlivými teplomermi budeme pomocou tlačítka. Teplota bude na LCD zobrazená v desiatkovej sústave s presnosťou na desatiny stupňa celsia.

Zapojenie teplomerov

V článku o 1-wire [1] rozhraní sú uvedené aj základné vlastnosti tohto teplomera, takže sa k tomu už nebudem vyjadrovať, snáď len uvediem zapojenie jednotlivých teplomerov, ktoré možno vidieť na obr. 1. Pull-up rezistor je nutný, nakoľko bez neho to nefunguje ako má.

Obr. 1. Zapojenie teplomerov

Na komunikáciu s viacerými teplomermi na zbernici 1-wire potrebujeme poznať adresu každého teplomera. Jednotlivé adresy sú uvedené v tabuľke 1.


Názov teplomera Adresa teplomera
Vonkajší teplomer 105FD4CD010800C9
Vnútorný teplomer 1059F7CD010800CD
Tab. 1 Názov a adresa teplomerov


Rozhranie 1-wire v PSoC

V samotnom dizajneri sa nachádza hardvérový blok pre podporu tejto zbernice. My však budeme používať softvérový blok, ktorý sa dá stiahnuť na nasledovnej adrese:

http://www.psocdeveloper.com/tools/misc-dev-tools.html

Potom ho doinštalujeme podľa návodu, ktorý sa nachádza tu:

http://www.psocdeveloper.com/forums/viewtopic.php?p=29&sid=2d053ae959fd795eaf997f498bfe3de5&view=next

Po umiestnení tohto bloku do projektu musíme vykonať zopár nastavení. Názorne sú ukázané na obr. 2.

Obr. 2. Nastavenia 1-wireSW


LCD blok

Pre komunikáciu s LCD musíme použiť blok LCD. Jeho nastavenie je jednoduché, nastavíme len, ktorý port sa na komunikáciu bude používať a či chceme povoliť alebo zakázať bar grafy.


Samotný program teplomera

Program je napísaný v jazyku C, chcel by som pridať aj kód v assembleri, ale zatiaľ aspoň takto.

#include <m8c.h>       
#include "PSoCAPI.h"

// funkcia PREVOD služi na výpis teploty v desiatkovej sústave na LCD 
// a zároveň počíta vyššiu presnosť nameranej teploty

void PREVOD(BYTE vstup, BYTE znamienko, BYTE count_remain)  
{
 long a, b=0, c, i, d;
 char vystup[]="00.0", cisla[]="0123456789"; 
 float teplota, remain, presnost;
 remain=count_remain;
 teplota=vstup;
 teplota=(teplota/2.0)-0.25;
 presnost=(16.0-remain)/16.0;
 teplota=teplota+presnost;
 if(znamienko==0xFF)
 {
 teplota=256-vstup;
 teplota=(teplota/2.0)-0.25;
 teplota=teplota+presnost;
 }
 teplota=teplota*10.0;
 for(i=100;i>=1;i=i/10)
	 {  
	 	a=teplota/i;
		c=a-b*10;
		b=a;
		if(i==100) d=0;
		if(i==10) d=1;
		if(i==1) d=3;
		
		
		if(c==0)vystup[d]=cisla[0];
		if(c==1)vystup[d]=cisla[1];
		if(c==2)vystup[d]=cisla[2];
		if(c==3)vystup[d]=cisla[3];
		if(c==4)vystup[d]=cisla[4];
		if(c==5)vystup[d]=cisla[5];
		if(c==6)vystup[d]=cisla[6];
		if(c==7)vystup[d]=cisla[7];
		if(c==8)vystup[d]=cisla[8];
		if(c==9)vystup[d]=cisla[9];
	 }

   LCD_Position(1,3);
   LCD_PrString(vystup);
  
}
// začiatok hlavnej funkcie

void main(void)
{	
	BYTE vystup, znamienko,count_remain,byte;
	int p=1;
	char eteplota[]="Teplota vonku:", plus[]="+", minus[]="-";
	char prazdny[]="                ", iteplota[]="Teplota vnutri";
	M8C_EnableGInt ;
	OW_Start();
	LCD_Start();
	LCD_Init();
	while(1)
	{	                      //na pin P1.0 privedieme cez tlačitko 5V
		PRT1DR=0;             //na port 1 sa zapíše 0
		if(PRT1DR==1) p++;    //ak sa na porte 1 objaví 1, inkrementuje sa p 
		if (p>2) p=1;         //pre správnu funkčnosť musí byť pin P1.0 nastavený na režim Hi_Z digital
		OW_Reset();
		if(p==1)              //ak bude p=1, komunikácia bude prebiehať s vonkajším teplomerom
		{
		OW_WriteByte(0x55);   //príkaz Match ROM
		OW_WriteByte(0x10);   //zadanie adresy teplomera
		OW_WriteByte(0x5F);
		OW_WriteByte(0xD4);
		OW_WriteByte(0xCD);
		OW_WriteByte(0x01);
		OW_WriteByte(0x08);
		OW_WriteByte(0x00);
		OW_WriteByte(0xC9);
		OW_WriteByte(0x44);   //príkaz pre konverziu teploty
		OW_Delay10mTimes(75); //čakanie 750us
		OW_Reset();           //reset rozhrania
		OW_WriteByte(0x55);   //Match ROM
		OW_WriteByte(0x10);   //zaddanie adresy teplomera
		OW_WriteByte(0x5F);
		OW_WriteByte(0xD4);
		OW_WriteByte(0xCD);
		OW_WriteByte(0x01);
		OW_WriteByte(0x08);
		OW_WriteByte(0x00);
		OW_WriteByte(0xC9);
		OW_WriteByte(0xBE);   //príkaz pre čítanie Scratch Pad
		vystup = OW_ReadByte(); // čítanie jednotlivých bytov (teplota)
		znamienko = OW_ReadByte(); //(znamienko)
		byte = OW_ReadByte();
		byte = OW_ReadByte();
		byte = OW_ReadByte();
		byte = OW_ReadByte();
		count_remain = OW_ReadByte(); //(byte pre zvýšenie presnosti teplomera)
		LCD_Position(0,0);     //nastavenie kurzora na LCD na pozíciu 0,0
		LCD_PrString(prazdny); //vytlacenie prázdneho reťazca na LCD
		LCD_Position(0,0);     //nastavenie kurzora na LCD na pozíciu 0,0
		LCD_PrString(eteplota);//vytlacenie retazca eteplota na LCD
		LCD_Position(1,1);     //nastavenie kurzora na LCD na pozíciu 1,1
		if(znamienko==0x00)    //ak bude znamienko=0, vytlaci sa na LCD +
		LCD_PrString(plus);
		else
		LCD_PrString(minus);   //inak sa vytlaci na LCD -
		PREVOD(vystup, znamienko, count_remain); //nacitane 3 byty sa odovzdajú funkcií PREVOD, ktorá vyslednú teplotu vypíše na LCD
		}
		if(p==2)               //ak p=2, komunikácia bude prebiehať s vnútorným teplomerom
		{                      //postup je presne taký ako aj pri predchádzajúcom teplomery
		OW_WriteByte(0x55);
		OW_WriteByte(0x10);    //zadanie adresy teplomera
		OW_WriteByte(0x59);
		OW_WriteByte(0xF7);
		OW_WriteByte(0xCD);
		OW_WriteByte(0x01);
		OW_WriteByte(0x08);
		OW_WriteByte(0x00);
		OW_WriteByte(0xCD);
		OW_WriteByte(0x44);    // Start Conversion
		OW_Delay10mTimes(75);
		OW_Reset();
		OW_WriteByte(0x55);
		OW_WriteByte(0x10);
		OW_WriteByte(0x59);
		OW_WriteByte(0xF7);
		OW_WriteByte(0xCD);
		OW_WriteByte(0x01);
		OW_WriteByte(0x08);
		OW_WriteByte(0x00);
		OW_WriteByte(0xCD);
		OW_WriteByte(0xBE);    // Read Scratch Pad
		vystup = OW_ReadByte();
		znamienko = OW_ReadByte();
		byte = OW_ReadByte();
		byte = OW_ReadByte();
		byte = OW_ReadByte();
		byte = OW_ReadByte();
		count_remain = OW_ReadByte();
		LCD_Position(0,0);
		LCD_PrString(iteplota);
		LCD_Position(1,1);
		if(znamienko==0x00)
		LCD_PrString(plus);
		else 
		LCD_PrString(minus);
		PREVOD(vystup, znamienko, count_remain);
		}

	} 
}

Teraz uvediem kód v assembleri. Tento program je podstatne dlhší a nefunguje rovnako ako vyššie uvedený program v jazyku C. Z jednotlivých teplomerov sú len vyčítané byty, ktoré sa vypíšu na LCD a aj na rozhranie RS232. Medzi jednotlivými teplomermi prepíname pomocou sériového rozhrania. Ak stlačíme i, zobrazia sa údaje z vnútorného teplomera, ak stlačíme o, zobrazia sa údaje z vonkajšieho teplomera. Na sériovom rozhrané sú údaje vypísané v napríklad nasledovnom tvare:

00 (znamienko)

3A (teplota)

0D (byte count_remain pre zvýšenie presnosti nameranej teploty)

Na LCD to vyzerá nasledovne:

Teplota vonku:

+ 3A 0D

Samozrejme, údaje sú vypisované v hexadecimálnom tvare.

include "m8c.inc"       	; part specific constants and macros
include "memory.inc"    	; Constants & macros for SMM/LMM and Compiler
include "PSoCAPI.inc"   	; PSoC API definitions for all User Modules

export _main

area bss(ram)				;premenne
	teplota:	blk 1
	znamienko:	blk 1
	presnost:	blk 1

area lit					;definovanie retazcov
	out: 		DS "Teplota vonku"
				DB 0x00
	in:  		DS "Teplota vnutri"
				DB 0x00
	plus:		DS "+"
				DB 0x00
	minus:		DS "-"
				DB 0x00
	text:		DS "Komunikacia OK"
				DB 0x00
	
area text

;--------------------------------zaciatok hlavnej funkcie--------------------------------------------
_main:
M8C_EnableGInt
call LCD_Start
mov   A, UART_PARITY_NONE  
lcall  UART_Start
WaitForData: 				        ; cakanie na povel 
    lcall  UART_bReadRxStatus    
    and   A, UART_RX_COMPLETE    
    jz    WaitForData
	
    lcall  UART_bReadRxData                     ; citanie dat    
    lcall  UART_SendData  
		
	cmp A,'q'				; kontrola komunikacie
 	jz state_q
	
	cmp A,'o'				; vycitanie bytov z DS18S20(vonkajsi teplomer)
 	jz state_w
	
	cmp A,'i'				; vycitanie bytov z DS18S20(vnutorny teplomer)
 	jz state_s

;--------------------------------------------------------------------------------------------	
state_w:
lcall OW_Start 
lcall OW_Reset 
mov   A,55h                             ;skip ROM  
lcall  OW_WriteByte

mov   A,10h        			;zadanie adresy teplomera     
lcall  OW_WriteByte
mov   A,5Fh             
lcall  OW_WriteByte
mov   A,D4h             
lcall  OW_WriteByte
mov   A,CDh             
lcall  OW_WriteByte
mov   A,01h             
lcall  OW_WriteByte
mov   A,08h             
lcall  OW_WriteByte
mov   A,00h             
lcall  OW_WriteByte
mov   A,C9h             
lcall  OW_WriteByte
mov   A,44h           		       ;start konverzie teploty  

lcall  OW_WriteByte
mov   A,4Bh            		       ;oneskorenie 750ms 

lcall  OW_Delay10mTimes            

lcall OW_Reset

mov   A,55h             
lcall  OW_WriteByte

mov   A,10h        			;zadanie adresy teplomera     
lcall  OW_WriteByte
mov   A,5Fh             
lcall  OW_WriteByte
mov   A,D4h             
lcall  OW_WriteByte
mov   A,CDh             
lcall  OW_WriteByte
mov   A,01h             
lcall  OW_WriteByte
mov   A,08h             
lcall  OW_WriteByte
mov   A,00h             
lcall  OW_WriteByte
mov   A,C9h             
lcall  OW_WriteByte

mov   A,BEh           		       ;start konverzie teploty  
lcall  OW_WriteByte

lcall  OW_ReadByte
mov [teplota], A
lcall  OW_ReadByte
mov [znamienko], A
lcall  OW_ReadByte
lcall  OW_ReadByte
lcall  OW_ReadByte
lcall  OW_ReadByte
lcall  OW_ReadByte
mov [presnost], A
lcall UART_PutCRLF
mov A,[znamienko] 
lcall UART_PutSHexByte
lcall UART_PutCRLF
mov A,[teplota] 
lcall UART_PutSHexByte
lcall UART_PutCRLF
mov A,[presnost] 
lcall UART_PutSHexByte

mov A,00h 					; riadok
mov X,00h					; bunka
lcall LCD_Position
mov A, >out
mov X, <out
call LCD_PrCString
cmp [znamienko], 00h
jz tlac_plus
jnz tlac_minus
tlac_plus:
mov A,01h 					; riadok
mov X,00h					; bunka
lcall LCD_Position
mov A, >plus
mov X, <plus
call LCD_PrCString
jmp Pokracuj
tlac_minus:
mov A,01h 					; riadok
mov X,00h					; bunka
lcall LCD_Position
mov A, >minus
mov X, <minus
call LCD_PrCString
jmp Pokracuj
Pokracuj:
mov A,01h 					; riadok
mov X,03h					; bunka
lcall LCD_Position
mov A, [teplota] 			; nacita byt pre tlac
lcall LCD_PrHexByte 
mov A,01h 					; riadok
mov X,07h					; bunka
lcall LCD_Position
mov A, [presnost] 			; nacita byt pre tlac
lcall LCD_PrHexByte 
jmp WaitForData
;------------------------------------------------------------------------------------
state_s:
lcall OW_Start 
lcall OW_Reset 
mov   A,55h             
lcall  OW_WriteByte

mov   A,10h        			;zadanie adresy teplomera     
lcall  OW_WriteByte
mov   A,59h             
lcall  OW_WriteByte
mov   A,F7h             
lcall  OW_WriteByte
mov   A,CDh             
lcall  OW_WriteByte
mov   A,01h             
lcall  OW_WriteByte
mov   A,08h             
lcall  OW_WriteByte
mov   A,00h             
lcall  OW_WriteByte
mov   A,CDh             
lcall  OW_WriteByte
mov   A,44h           		;start konverzie teploty  

lcall  OW_WriteByte
mov   A,4Bh            		; Load delay time (example 3 would be 30mSec).

lcall  OW_Delay10mTimes      ; Call function

lcall OW_Reset

mov   A,55h             
lcall  OW_WriteByte

mov   A,10h        			;zadanie adresy teplomera     
lcall  OW_WriteByte
mov   A,59h             
lcall  OW_WriteByte
mov   A,F7h             
lcall  OW_WriteByte
mov   A,CDh             
lcall  OW_WriteByte
mov   A,01h             
lcall  OW_WriteByte
mov   A,08h             
lcall  OW_WriteByte
mov   A,00h             
lcall  OW_WriteByte
mov   A,CDh             
lcall  OW_WriteByte

mov   A,BEh           		;start konverzie teploty  
lcall  OW_WriteByte

lcall  OW_ReadByte
mov [teplota], A
lcall  OW_ReadByte
mov [znamienko], A
lcall  OW_ReadByte
lcall  OW_ReadByte
lcall  OW_ReadByte
lcall  OW_ReadByte
lcall  OW_ReadByte
mov [presnost], A
lcall UART_PutCRLF
mov A,[znamienko] 
lcall UART_PutSHexByte
lcall UART_PutCRLF
mov A,[teplota] 
lcall UART_PutSHexByte
lcall UART_PutCRLF
mov A,[presnost] 
lcall UART_PutSHexByte

mov A,00h 					; riadok
mov X,00h					; bunka
lcall LCD_Position
mov A, >in
mov X, <in
call LCD_PrCString
cmp [znamienko], 00h
jz tlac_plus2
jnz tlac_minus2
tlac_plus2:
mov A,01h 					; riadok
mov X,00h					; bunka
lcall LCD_Position
mov A, >plus
mov X, <plus
call LCD_PrCString
jmp Pokracuj2
tlac_minus2:
mov A,01h 					; riadok
mov X,00h					; bunka
lcall LCD_Position
mov A, >minus
mov X, <minus
call LCD_PrCString
jmp Pokracuj2
Pokracuj2:
mov A,01h 					; riadok
mov X,03h					; bunka
lcall LCD_Position
mov A, [teplota] 			; nacita byt pre tlac
lcall LCD_PrHexByte 
mov A,01h 					; riadok
mov X,07h					; bunka
lcall LCD_Position
mov A, [presnost] 			; nacita byt pre tlac
lcall LCD_PrHexByte 
jmp WaitForData
;------------------------------------------------------------------------------------
state_q:
lcall UART_PutCRLF
mov A, >text
mov X, <text
lcall UART_CPutString
lcall UART_PutCRLF
jmp   WaitForData

Odkazy a referencie