Meranie teploty pomocou teplomera DS18S20: Rozdiel medzi revíziami

Z Kiwiki
Skočit na navigaci Skočit na vyhledávání
Riadok 54: Riadok 54:
 
Program je napísaný v jazyku C, chcel by som pridať aj kód v assembleri, ale zatiaľ aspoň takto.
 
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" 
  
 +
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);
 +
 
 +
}
 +
 +
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)
 +
{
 +
PRT1DR=0;
 +
if(PRT1DR==1) p++;
 +
if (p>2) p=1;
 +
OW_Reset();
 +
if(p==1)
 +
{
 +
OW_WriteByte(0x55);
 +
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); // Start Conversion
 +
OW_Delay10mTimes(75);
 +
OW_Reset();
 +
OW_WriteByte(0x55);
 +
OW_WriteByte(0x10);
 +
OW_WriteByte(0x5F);
 +
OW_WriteByte(0xD4);
 +
OW_WriteByte(0xCD);
 +
OW_WriteByte(0x01);
 +
OW_WriteByte(0x08);
 +
OW_WriteByte(0x00);
 +
OW_WriteByte(0xC9);
 +
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(prazdny);
 +
LCD_Position(0,0);
 +
LCD_PrString(eteplota);
 +
LCD_Position(1,1);
 +
if(znamienko==0x00)
 +
LCD_PrString(plus);
 +
else
 +
LCD_PrString(minus);
 +
PREVOD(vystup, znamienko, count_remain);
 +
}
 +
if(p==2)
 +
{
 +
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>
  
 
== Odkazy a referencie ==
 
== Odkazy a referencie ==
 
<references/>
 
<references/>

Verzia zo dňa a času 10:58, 5. júl 2010

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"  

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);
  
}

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)
	{	
		PRT1DR=0;
		if(PRT1DR==1) p++;
		if (p>2) p=1;
		OW_Reset();
		if(p==1)
		{
		OW_WriteByte(0x55); 
		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); // Start Conversion
		OW_Delay10mTimes(75);
		OW_Reset();
		OW_WriteByte(0x55);
		OW_WriteByte(0x10);
		OW_WriteByte(0x5F);
		OW_WriteByte(0xD4);
		OW_WriteByte(0xCD);
		OW_WriteByte(0x01);
		OW_WriteByte(0x08);
		OW_WriteByte(0x00);
		OW_WriteByte(0xC9);
		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(prazdny);
		LCD_Position(0,0);
		LCD_PrString(eteplota);
		LCD_Position(1,1);
		if(znamienko==0x00)
		LCD_PrString(plus);
		else
		LCD_PrString(minus);
		PREVOD(vystup, znamienko, count_remain);
		}
		if(p==2)
		{
		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);
		}

	} 
}

Odkazy a referencie