1 - wire na 51

Aug 24, 2005 8 Replies

Hej Kupilem termometr ds18B20. Wiedzia³em, ¿e bêd± problemy, ale nie, ¿e a¿ tak d³ugo. Robiê zgodnie z instrukcja, mam at89s52, kwarc 12MHz, wiêc instrukcja ¶rednio w 1us (inkrementacja timera tez). Dostaje presence pulse, ale jak wyswietlam odebrane dane po kolei ze scratchpada to dostaje: 0, 128, 128, 0,



128, 128, 0, 0 dziesiêtnie.

Pro¶ba moja jest taka, czy kto¶ móg³by tylko sprawdziæ czy funkcje do wysy³ania i odbierania bitów i bajtów s± poprawne? Bajtów pewnie tak, ale nie wiem jak z bitami.



A mo¿e kto¶ ma jaki¶ dzia³aj±cy, jednomodu³owy kod i móg³by mi przes³aæ chocia¿ te dwie funkcje do obioru i nadania bitu?



pozdrawiam



P.S.(disp() wyswietla liczbe na lcd); czê¶c programu:



void low() { P0 &= ~0xC0; }



void high() { P0 |= 0xC0; }



void transmit(unsigned char _bit) { if(_bit) //if '1' { low(); TH1=0xFF; //60us TL1=0xC3; //60us high(); TF1=0; TR1=1; while(!TF1){} TR1=0; TF1=0; } else //if '0' { low(); TH1=0xFF; //60US TL1=0xC3; //60US TF1=0; TR1=1; while(!TF1){} high(); TR1=0; TF1=0; } }



void send(unsigned char _byte) { unsigned char i; for(i=0;i<8;i++) { transmit((_byte)&(1<<i)); }



}

unsigned char receive() { unsigned char retval=0; low(); //TH1=0xFF; //TL1=0xF8;//6; //7us dla ostatniego whilea



TH1=0xFF; TL1=0xF8;



high(); TF1=0; TR1=1; while(!TF1){} retval=(P0 & 0x80); TF1=0; TR1=0; return retval; }



unsigned char read() { unsigned char dana=0; unsigned char i; for(i=0;i<8;i++) { dana|=((receive())<<i); } return dana; }



void main() {



TMOD=0x11;


while(1) { high();



TH1=0xFE; TL1=0x1F; low(); TF1=0; TR1=1;



while(!TF1){} //czekaj 480us high(); TR1=0; TF1=0; P0|=0x01; P0&=~0x02; while(!(P0 & 0x80)){} //czekaj az bedzie high a ma byc



while(P0 & 0x80){} //czekaj na presence pulse



while(!(P0 & 0x80)){} //czekaj az zwolni for(k=0;k<400;k++){} //razem z presence pulse ma byc 480 us, to damy wiecej



send(0xCC); send(0xBE);



t1=read(); t2=read(); t3=read(); t4=read(); t5=read(); t6=read(); t7=read(); t8=read();



clr(); home(); disp(t1); write('/'); disp(t2); write('/'); disp(t3); write('/'); disp(t4);


for(k=0;k<1000;k++){} }



}

U¿ytkownik "Grodo" napisa³ :

czy to co odbierasz to nie jest przypadkiem serial number? je¶li masz tylko jeden ds na magistrali to mo¿esz wydaæ komende 'skip ROM', potem 'convert T' a potem odebraæ dwa pierwsze bajty (pierwszy to LSB temperatury, drugi to MSB temperatury), po³±czyæ w jedn± 16-bitow±, podzieliæ przez 16 (wyjdzie liczba zmiennoprzecinkowa) i to jest gotowa temperatura tu masz przyk³ad, co prawda w Bascom`ie ale mo¿e co¶ ci rozja¶ni:

dim T11(2) as byte dim T1 as single dim Temp as string * 5

config 1wire=p3.0

1wreset 1wwrite &HCC 1wwrite &H44

1wreset

1wwrite &HCC 1wwrite &HBE

T11(1) = 1wread() T11(2) = 1wread()

1wreset

T1 = Makeint(T11(1) , T11(2)) T1 = T1 / 16 Temp = Fusing(T1 , #.##)

Cls Lcd "Temp: " ; Temp

Pozdro Analyzer

Grodo <(zamienXna2000) snipped-for-privacy@poczta.onet.pl> napisał(a):

Popatrz na to ...

.. oraz na to ...

.. i pomyśl przez chwilkę ;-)

Piotrek

U¿ytkownik "Piotrek Sz." snipped-for-privacy@gazeta.pl napisa³ w wiadomo¶ci news:dehnbl$bcs$ snipped-for-privacy@inews.gazeta.pl...

formatting link
Drogi Panie Piotrku, otó¿ my¶lalem, przez chwilê i nic. To co¶ mia³o tworzyæ bajt z bitów po przez aktualnizowanie wag, ¿e tak powiem. Je¶li chodzi Ci o to, ¿e powinno byc += zamiast |= to ¶miem siê nie zgodziæ, bo efekt tych dzia³añ jest taki sam, je¶li jest wykonywany na coraz to innej pozycji. Je¶li mimo to, czego¶ nie widzê, to poprosze o zwrócenie mi uwagi. pozdrawiam

Grodo <(zamienXna2000) snipped-for-privacy@poczta.onet.pl> napisał(a):

Proszę bardzo.

Z powyższej linii wnioskuję , że linia DQ DS18B20 poczłączona jest do P0.7 (ameryki pewnie nie odkryłem). Teraz wyobraźmy sobie , że 1-szy bajt odpowiedzi DS-a = 0xFF , na co funkcja _receive_ zwróci ośmiokrotnie wartość 0x80. Wartość zmiennej "i" zmienia się w pętli "for" od "0" do "7" i popatrzmy co się dzieje: i=0 dana=0 dana|=((receive())<<i); Wartość recive = 0x80 i po wykonaniu przesunięcia w lewo "i=0" krotnie zostanie wykonana operacja "OR" z daną i w wyniku tego: dana=0x80 i++ i=1 dana=0x80 Wartość recive = 0x80 i po wykonaniu przesunięcia w lewo "i=1" krotnie zostanie wykonana operacja "OR" z daną i w wyniku tego: dana=0x80 .. mówiąc wprost wartość 0x80 , przesunięta w lewo więcej niż zero razy w wyniku da ZAWSZE 0x00.

To tyle. Jeśli nie jasno się wyraziłem , to proszę o uwagi.

Piotrek

U¿ytkownik "Piotrek Sz." snipped-for-privacy@gazeta.pl napisa³ w wiadomo¶ci news:dehpu4$olf$ snipped-for-privacy@inews.gazeta.pl...

Normalnie... Brak mi s³ów. Chylê czo³a i g³êbokie wyrazy szacunku. Dzia³a. Rzek³bym - naprawi³e¶ ;) Kurcze, coraz bardziej siê dziwiê, ¿e kto¶, kto nie pisa³ danego programu, potrafi znale¼æ w nim b³±d. Tak jak kiedy¶ chyba na tej grupie, ale ju¿ nie wiem, kto¶ mia³ oddaæ pracê dyplomow± i na dzieñ przed oddaniem mu pad³a. I kto¶ inny z netu nie widz±c tego ca³ego urz±dzenia powiedzia³: sprawd¼ napiêcie na resecie. I nastêpny post: daj adres wysy³am flache. Ech. Bardzo dziêkujê, pokaza³y siê jakie¶ liczby - teraz idê dekodowaæ ;) pozdrawiam serdecznie

Grodo <(zamienXna2000) snipped-for-privacy@poczta.onet.pl> napisał(a):

Z mojego doświadczenia wynika , że łatwiej znaleźć błąd w cudzym kodzie , niż we własnym ;-) Rzekłbym - "Najciemniej pod latarnią"

Pozdrawiam Piotrek

U¿ytkownik "Piotrek Sz." snipped-for-privacy@gazeta.pl napisa³ w wiadomo¶ci news:dehtpa$ep2$ snipped-for-privacy@inews.gazeta.pl...

W ka¿dym razie dziêki bardzo ;)

Potwierdzam w ca³ej rozci±g³o¶ci!

dziadek Ben

Join the Discussion

Have something to add? Share your thoughts — no account required.

Didn't find your answer?

Ask the community — no account required