PIC16F628A a 1-wire pro 18S20-jak nastavit pullup rezistory?

Zdravim Vas,

prave se trapim (cely den) se zprovoznenim 1-wire na MCU PIC16f628a s dig. sensorem teploty 18S20. Problem je v tom, ze nemuzu nejak prijit na to jak nastavovat pullup rezistory. Procetl jsem dokumentaci k MCU, ale moc tam doho neni. Jedine co jsem vycetl bylo, ze se musi nastavit 7. bit v registruOPTION_REG, abych povolil nastavovani pullup rezistoru na PORTB. A jestli jsem to dobre pochopil, tak zapinani a vypinani pullup rezistoru se dela pomoci TRISB, je to tak? A predpokladam, ze cteni hodnoty na portu budu cist pres PORTB repr. RB6.

#include <htc.h>

void oneWireReset() {
 char b;
 TRISB6 = 0;
 __delay_us(480);
 TRISB6 = 1;
 __delay_us(70);
 b = RB6;
 __delay_us(410);
 if (b) {
  printString(1,"No device");
 } else {
  printString(1,"Device detected");
 }
}

void main() {
 OPTION_REG = 0b01111111;
 TRISB = 0b11000000;
 oneWireReset();
}

Pozn.: Zapojeni sensoru je podle.

:arrow_right: administrator: přejmenováno z "PIC16F628A a 1-wire"

Neni to tak, TRIS urcuje zda vyvod bude vstup nebo vystup.

no dasa spravit nieco take… na porte B povolis pullup. RB6 nastavis na log0.

Vysledkom bude: ak tris RB6 nastavis na log1 port je v vstupnom rezime na vystupe je +5V koli zapnutim pullup odporom, daju sa nacitavat data z DS cidla.

Ak tris RB6 nastavis na 0… zbernica je stiahnuta na log0 … prepinanim medzi Tris RB6 rovne 0 a tris rb6 rovne 1 vies vysielat 0 a jednotky.

Dekuji za pomoc :wink: Nakonec se mi taky podarilo preci jen neco najit na netu. Coz potvrzuje to co jste sem napsali.

Jeste prikladam zajimavy odkaz pro nastavovani casu pro 1-wire:
maxim-ic.com/app-notes/index.mvp/id/126

Tak jsem nejak asi predpokladam dobre rozchodil 1-wire, ale, je tu preci jen jeden problem. Na sbernici mam zapojene jen jedno zarizeni a kdyz provedu sekvenci prikazu pro nacteni teploty tak mi to vzdy vraci jednu a tu samou hodnotu FFFF, coz je podle meho uplna hloupost. Mohl by mi nekdo zkotrolovat kod pls? Ja si myslim, ze je to v poradku, ale clovek nikdy nevi …
New Text Document.txt (1.73 KB)

mas tam namontovany 4k7 odpor na +5V ?

Ahoj

Na 1W sběrnici se interní pullup nepoužívá. Předepsaný je externí upínací odpor 4k7, jak píše správně Atlan. Proto se na této sběrnici s výhodou používají pouze dva stavy. Horní úroveň, která je držena externím upínacím odporem a dolní úroveň, která je aktivním stavem. Tento aktivní stav je pak poměrně zajímavě řízen časovými závislostmi, kdy synchronizace je tvořena sestupnou hranou a info o 1/0 délkou pulzu. Provoz sběrnice je vždy zahájen masterem (slave vždy pouze čeká na pokyny mastera, sám nikdy nic nevyvolá), tvořeným procesorem, který stáhne sběrnici do nuly na dobu minimálně 480 us (Reset pulz), pak jí na minimálně 70 us uvolní a zároveň přejde do čtení a čeká na Presence pulz. Pokud tento pulz přijde, je to správně a slave očekává povel, v opačném případě master vyhodí chybu, že na sběrně nic nevysí. Při správném vyhodnocení Presence pulzu se dokončí čekací stavy a na sběrnu se pošle některý z pokynů pro čtení ROM (tj. vyčte se family kód - 8b, sériové číslo 48b a CRC 8b). Důležité je, že se hodnoty čtou vždy od nejméně významného bitu a rotací se seskládají do hodnot bajtů. Pokud na sběrně vysí pouze jedno zařízení DS, jako předpokládám u Tebe jeden teploměr, tak nemusíš identifikovat zařízení a dáš jen povel k převodu hodnoty v teploměru a pak ke čtení hodnoty z teploměru.

No jediny odpor co mam zapojeny je 4K7 mezi 2 a 3 pinem cisla, coz je mezi +5 V a datovym vodicem senzoru.

Tak jsem to nakonec vyresil. Problem byl v tom, ze jsem u funkce oneWireReadByte() a oneWireWriteBit() pouzil nazacatku misto registru TRISB, registr TRISA :wink: Je to usmevne, ale je zvlastni, ze si toho nikdo nevsiml, kdo prochazel muj zdrojak :wink: ale nevadi o to vic me tesi, ze jsem na to prisel sam :wink:

Tak jsem narazil na dalsi problem a tim je vypisovani promenne typu float pomoci funkce sprinf. Pro zjednoduseni vypada kod nejak takto:


#include <htc.h>
#include <stdio.h>

void main() {

	float t;
	char string[16];

	t = 125.3263;

	sprintf(string,"%3.2f",t);	

}

Tak kdyz toto zkompiluji tak mi to vyhodi nekolik chyb 1347. Hledal jsem na netu co to muze znamenat a nasel jsem, ze se jedna o nedostatek pameti RAM. Je to mozne? Kdyz zkompiluji kod bez poslednich dvou prikazu tak mi to zabira 22% datove pameti. Taky jsem nekde vycetl, ze se mozna jedna o chybu prekladace. Mate s timto nekdo zkusenosti nebo nevite jak to vyresit?

Vecer sa ti na to pozriem … Ak sa k tomu nikto nevyjadri. Je nejaky dovod pchat na 4 desatine miedta ak zobrazujes len 2.

No toto je jen priklad, ktery taky hlasi uplne stejnou chybu. Merim teplotu pomoci DS18B20 po 1-wire a ten dava presnost na 4 desetina mista, ale ve finale bych chtel pouzit jen jedno desitinne misto, coz bohate staci. Ale abych mohl merit teplotu na jednu desetinu stupne v rozsahu 0.0 - 0.9 tak musim mit vypocet na 4 desetinna mista viz. datasheet ds18b20 (nasobek 0.0625).

Pomoci float to proste nefunguje a nechapu proc, zkousel jsem stejny kod pro ruzne MCU a vysledek je stejny. Mam takovy pocit ze je to nejaky bug kompilatoru … mam Hi-tech C verzi 9.83

At to jeste upresnim, ten senzor mi vraci teplotu ve dvou bytech. Horni byte obsahuje:
byteH = [S S S S S X X X]

kde S je znamenko (1 - minus, 0 - plus), X jsou bity teploty pred desetinou carkou.

V dolni byte obsahuje:
byteL = [X X X X Y Y Y Y]

kde X jsou bity teploty pred desetinou carkou (celociselna hodnota) a Y jsou bity teploty za desetinnou carkou.
Takze kdyz chci zjistit celociselnou hodnotu teploty musim provest toto:

char t1 = ((byteH << 4)  & 0b01110000) | (byteL >> 4);

Pro vypocet desetinne casti udelam toto:

float t2 = (byteL & 0b00001111) * 0.0625;

takze cele by to melo byt takto:

float t = ((byteH << 4) & 0b01110000) | (byteL >> 4) + (byteL & 0b00001111) * 0.0625; sprintf(string,"Teplota: %.1f C",t);

Toto je ten duvod proc to resim. Ani v jednoduchem prikladu uvedenem vyse to nefunguje resp. haze to stejnou chybu.

Vystup je na lcd? Co chces merat ze potrebujes taku prrsnost, inak uz len napajanie a samotny prevod zohrieva cidlo…

Ano, vystup je na lcd a merim tim jen teplotu vzduchu nic vic. Vetsina teplomeru tak meri. Nevim jak jinak zmerit teplotu na jedno desetinne misto reps. jak to urcit z tech 2 bajtu :frowning:

das sem cely kod nechce sa mi to prepisovay… ten tvoj super prevod zaberie 2,8k programu… z hladiska toho ze pouzity procesor ma 2k :smiley:

Není lepší si v ASM oddělit ty 4 bity bokem, prohodit je úplně nejjednodušší vyhledávací tabulkou a pak pokračovat v C? Není to sice kdovíjak přesný, ale je to rychlý a zabírá to málo místa. Do C to v pohodě dopíšeš.

         MOVLW        HIGH        table
         MOVWF        PCLATH                     ;nastavení pclath
         MOVLW        0x0F
         ANDWF        byteL,W                     ;zamaskuje nepotřebné bity
         ADDWF        PCL,F                        ;vytáhni desetinu z tabulky

table  RETLW         0x00
         RETLW         0x00
         RETLW         0x01
         RETLW         0x01
         RETLW         0x02
         RETLW         0x03
         RETLW         0x03
         RETLW         0x04
         RETLW         0x05
         RETLW         0x05
         RETLW         0x06
         RETLW         0x06
         RETLW         0x07
         RETLW         0x08
         RETLW         0x08
         RETLW         0x09

Těch pár žádek si vytáhne desetinný bity z byteL, zamaskuje nepotřebný bity a pomocí tabulky ti do W přesune desetinku.

Dobre, beru ze p16f628a ma asi malou pameti, znamena to tedy ze neni nejaka moznost jak pracovat realnymi cisly? Teda jen s jednim :frowning:

Není jednodušší T*10/16?

Promin, co to? :wink: Nevyznam se v tom tak …