PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Auslesen des DS18S20 mit dem PIC16F84A



schally
12.04.2007, 21:33
Hi,

also meine Problem besteht darin das ich den 1-Wire Baustein nicht auslesen kann bzw das ich die Funktionweise dieses Bausteins nicht verstehe!

Kann mir vvl jemand von euch ein Flussdiagramm malen wie man diesen Ansteuert nur zum verständniss?

mfg
schally

PICture
13.04.2007, 10:31
Hallo schally!

Das alles ist sehr kompliziert, kannst Du aber finden in Datenblatt (data sheet) als .pdf Datei vom Dallas Semiconductors / MAXIM:

http://www.datasheetarchive.com

MfG

schally
14.04.2007, 20:31
hi,
habe soweit jetzt alles fertig und stehe ich vorm nächsten prob wie kann ich den Binär Code in einen BCD Code umwandeln?

PICture
14.04.2007, 21:03
Hallo schally!

Ich habe mal ein ASM Programm fur hex->dec Wandlung geschrieben. Das werde ich in dem entstehendem Wiki Artikel "PIC Assembler" beschreiben. Aber wenn Du es nötig brauchst, kann ich es schon jetzt machen, bloss die Kommentare nicht reich sind.

MfG

schally
14.04.2007, 21:12
Hallo schally!

Ich habe mal ein ASM Programm fur hex->dec Wandlung geschrieben. Das werde ich in dem entstehendem Wiki Artikel "PIC Assembler" beschreiben. Aber wenn Du es nötig brauchst, kann ich es schon jetzt machen, bloss die Kommentare nicht reich sind.

MfG

Hi
das ware richtig cool von dir!

mfg
schally

PICture
14.04.2007, 22:09
O.K.

Kurze Eiführung:
Das ist ein Unterprogramm der mit call Hex_Dec aufgerufen wird. Es gibt 4 Register mit 32 Bits, sie müssen (wegen FSR) so wie im Code nacheinander liegen (die absolute Adressen sind nicht wichtig). In erstes Register "A" wird die bin Zahl eingeschrieben und im "D" befindet sich die umgewandelte dec Zahl. A3 und D3 sind MSB und A0 und D0 sind LSB. Die "B" und "C" sind Hifsregister. Wachrscheinlich nicht alle aufgelisteten Register (ausser A,B,C,D und Flags) sind nötig, aber ich habe es bloss aus meinem Programm schnell kopiert. Schau mal bitte, was in dem Unterprogramm vorkommt. Ich Glaube, dass alle DTmpX, FTmp und TTmp nicht und Unterprogramm Copy DC auch nicht, aber das ist ein Teil grösseres Programms und kann noch kleiner gemacht werden.

MfG


#define _RP0 STATUS,RP0
#define _C STATUS,C
#define _Z STATUS,Z
#define _DC STATUS,DC
#define _Fcra Flags,0
#define _Fcrp Flags,1
#define _Fdca Flags,2
#define _Ferr Flags,3
A3 EQU 0x20
A2 EQU 0x21
A1 EQU 0x22
A0 EQU 0x23
B3 EQU 0x24
B2 EQU 0x25
B1 EQU 0x26
B0 EQU 0x27
C3 EQU 0x28
C2 EQU 0x29
C1 EQU 0x2A
C0 EQU 0x2B
D3 EQU 0x2C
D2 EQU 0x2D
D1 EQU 0x2E
D0 EQU 0x2F
Flags EQU 0x30
DTmp1 EQU 0x31
DTmp2 EQU 0x32
DTmp3 EQU 0x33
DTmp4 EQU 0x34
ATmp EQU 0x35
FTmp EQU 0x36
HTmp EQU 0x37
RTmp EQU 0x38
TTmp EQU 0x39

Hex_Dec call CClr ;Hex>A, D>Dec
call DClr
movlw 1
movwf C0
movlw 0x20 ;32 bit Hex > 32 bit Dec (8 digits)
movwf HTmp
HexDecL btfsc A0,0
call AddDC
call CopyCB
call AddCB
call ARotRb
decfsz HTmp,1
goto HexDecL
return
CClr clrf C0
clrf C1
clrf C2
clrf C3
return
DClr clrf D0
clrf D1
clrf D2
clrf D3
return
CopyCB movf C0,0
movwf B0
movf C1,0
movwf B1
movf C2,0
movwf B2
movf C3,0
movwf B3
return
CopyDC movf D0,0
movwf C0
movf D1,0
movwf C1
movf D2,0
movwf C2
movf D3,0
movwf C3
return
AddCB movlw B0 ;C+B>C
movwf FSR
goto AddR
AddDC movlw C0 ;D+C>D
movwf FSR
AddR bcf _Ferr ;add two register
bcf _Fcrp
movlw 4 ;4 bytes long
movwf ATmp
AddRL bcf _Fdca
bcf _Fcra
movf INDF,0
movwf RTmp
movlw 4
addwf FSR,1
btfss _Fcrp
goto AddRN
movlw 1
addwf INDF,1
call DecCor
AddRN movf RTmp,0
addwf INDF,1
call DecCor
btfss _Fdca
goto AddCor1
movlw 6
addwf INDF,1
AddCor1 btfss _Fcra
goto AddCor2
movlw 0x60
addwf INDF,1
btfsc _C
bsf _Fcra
AddCor2 movf INDF,0
andlw 0xF0
sublw 0xA0
btfss _Z
goto AddCor3
movf INDF,0
andlw 0x0F
clrf INDF
addwf INDF,1
bsf _Fcra
AddCor3 bcf _Fcrp
btfsc _Fcra
bsf _Fcrp
movlw 5
subwf FSR,1
decfsz ATmp,1
goto AddRL
btfsc _Fcra
bsf _Ferr
return
DecCor btfsc _DC ;decimal correction (equ DAW)
bsf _Fdca
btfsc _C
bsf _Fcra
movf INDF,0
andlw 0x0F
sublw 9
btfss _C
bsf _Fdca
movf INDF,0
andlw 0xF0
sublw 0x90
btfss _C
bsf _Fcra
return
ARotRb movlw A3 ;rotate A register 1 bit right
movwf FSR
RRotRb movlw 4 ;rotate 4 bytes
movwf ATmp
bcf _Fcrp
btfsc A0,0
bsf _Fcrp
RRotRbL bcf _Fcra
btfsc INDF,0
bsf _Fcra
bcf _C
btfsc _Fcrp
bsf _C
rrf INDF,1
bcf _Fcrp
btfsc _Fcra
bsf _Fcrp
incf FSR,1
decfsz ATmp,1
goto RRotRbL
return

schally
14.04.2007, 22:59
Hi,
erstmal THX für den CODE.
Hab heir Hilfe gefunden...
http://www.piclist.com/techref/microchip/math/radix/b2oth-8b3d-jsv.htm

mfg
schally

schally
15.04.2007, 11:31
Hi,
habe den Code mal ausprobiert und nun bekomme ich dieses hier ausgegeben.
http://steffen-schalhorst.de/Bild1.jpg

und die tatsächliche Temp ist
http://steffen-schalhorst.de/Bild2.jpg

Hier ist mein Code:


;************************************************* ******************************
;* Bestimmung des Prozessortyps für den Assembler und das Programmiergerät *
;************************************************* ******************************
LIST p=16F84A
;************************************************* ******************************
;* Includedatei für den 16F84A einbinden (vordef. Reg. und Konst.) *
;************************************************* ******************************

#include <p16f84A.INC>

; Diese Datei enthält Vordefinitionen für wichtige Register und Konstanten.
; (Z.B. gibt es die Konstante PORTB mit der sich ohne Angabe der
; absoluten Adresse H'0006' der Port B des Prozessors ansprechen lässt)


;************************************************* ******************************
;* Konfigurationseinstellungen für IC-Prog vordefinieren *
;************************************************* ******************************

__CONFIG _PWRTE_ON & _CP_OFF & _HS_OSC & _WDT_OFF

; Hier werden verschiedene Prozessoreigenschaften festgelegt:
; PWRTE_ON schaltet den Power Up Timer ein, d.h. der Prozessor wartet nach
; dem Einschalten ca. 70ms mit dem Programmstart, um sicher zu sein,
; dass alle angeschlossene Peripherie bereit ist.
; CP_OFF schaltet die Code-Protection des Prozesors aus. Damit ist das im Prozessor
; befindliche Programm jederzeit auslesbar und überschreibbar.
; HS_OSC spezifiziert einen Quarzoszillator (Highspeed) als Zeitbasis für den Prozessor.
; WDT_OFF schaltet den Watchdog-Timer des Prozesors aus.


;************************************************* ******************************
;* Register / Variablen festlegen *
;************************************************* ******************************
; hier werden Adressen von Registern / Variablen festgelegt. Diese werden beginnend
; mit der Adresse H'20' aufsteigend vergeben.
CBLOCK H'20'

d0
d1
d2
zaehler ;Variable für einen Zähler
temp1 ;Variable für die Temp. des Sensors in Binärer Form
temp2 ;Variable zum Merken ob die Temp POS/NEG ist
DS18S20 ;Variable an die die Commands geschrieben werden
w2




ENDC
;************************************************* ******************************
;* Konstanten festlegen *
;************************************************* ******************************

; Hier sollten alle im Verlauf des Programms verwendeten Konstanten deklariert werden.
; Die Deklaration sieht z.B. folgendermaßen aus:

;************************************************* ******************************
;* Definition von einzelnen Bits in einem Register / in einer Variable *
;************************************************* ******************************
; hier kann mit Hilfe der #DEFINE Direktive einzelnen Bits in einem Register ein
; Name zugewiesen werden.
; Eine Definition sieht z.B. folgendermaßen aus:
;
rest EQU 0x18
loops EQU 0x0C
loops2 EQU 0x0D
huns EQU 0x1D
tens EQU 0x1E
ones EQU 0x1F
;************************************************* ******************************
;* Name * Port * Bedeutung / Funktion *
;************************************************* ******************************
#DEFINE Sensor PORTA,0 ;Anschluss für 1-Wire Sensor
#DEFINE TH PORTA,1 ;Taster für höchste Temperatur -->TH =Temp High
#DEFINE TL PORTA,2 ;Taster für niedrigste Temperatur -->TL =Temp Low

#DEFINE T1 PORTB,7 ;Transistor T1 --> Für Anzeige 1
#DEFINE T2 PORTB,6 ;Transistor T2 --> Für Anzeige 2
#DEFINE T3 PORTB,5 ;Transistor T3 --> Für Anzeige 3
#DEFINE bank1 STATUS, RP0 ;Spezielle Register Bank
;************************************************* ******************************
;************************************************* ******************************
;* Programmstart *
;************************************************* ******************************
ORG H'00' ; Das Programm wird ab Speicherstelle 0 in den Speicher geschrieben
GOTO init ; Springe zur Grundinitialisierung der Ports A und B
;************************************************* ******************************
;* Initialisierung *
;************************************************* ******************************
init BSF bank1 ; wechsle zu Registerbank 1 (spezielle Register)
MOVLW B'00011111'
MOVWF TRISA ; RA0 .. RA4 Eingänge
MOVLW B'00000000'
MOVWF TRISB ; RB0-RB7 Ausgänge
BCF bank1 ; wechsle zu Registerbank 0 (normaler Speicherbereich)

CLRF PORTA ; Port A löschen
CLRF PORTB ; Port B löschen

; Die Register TRISA und TRISB legen fest, welche Bits in den jeweiligen Ports Ein- bzw.
; Ausgänge sind. Eine '1' an der entsprechenden Stelle setzt das Bit des Ports als Ein-
; gang eine '0' setzt das Bit als Ausgang.
;************************************************* ******************************
;* Hauptprogramm *
;************************************************* ******************************

main
clrf rest ; rest löschen

CALL UP_read_temp
CALL UP_convert_temp
CALL UP_Send_Temp

GOTO main






;************************************************* ******************************
;* Unterprogramme *
;************************************************* ******************************

;*****************************Schleifen*********** ******************************
UP_Wait_1s
;4999993 cycles
movlw 0x2C
movwf d0
movlw 0xE7
movwf d1
movlw 0x0B
movwf d2
UP_Wait_1s_0
decfsz d0, f
goto $+2
decfsz d1, f
goto $+2
decfsz d2, f
goto UP_Wait_1s_0

;3 cycles
goto $+1
nop

;4 cycles (including call)
return
;************************************************* ******************************
UP_WAIT_480µs ;
;2393 cycles
movlw 0xDE
movwf d0
movlw 0x02
movwf d1
UP_WAIT_480µs_0
decfsz d0, f
goto $+2
decfsz d1, f
goto UP_WAIT_480µs_0

;3 cycles
goto $+1
nop

;4 cycles (including call)
return
;************************************************* ******************************
UP_WAIT_60µs ;
;295 cycles
movlw 0x62
movwf d0
UP_WAIT_60µs_0
decfsz d0, f
goto UP_WAIT_60µs_0

;1 cycle
nop

;4 cycles (including call)
return
;************************************************* ******************************
UP_Wait_50µs
;244 cycles
movlw 0x51
movwf d0
UP_Wait_50µs_0
decfsz d0, f
goto UP_Wait_50µs_0

;2 cycles
goto $+1

;4 cycles (including call)
return
;************************************************* ******************************
UP_Wait_600µs
;2993 cycles
movlw 0x56
movwf d0
movlw 0x03
movwf d1
UP_Wait_600µs_0
decfsz d0, f
goto $+2
decfsz d1, f
goto UP_Wait_600µs_0

;3 cycles
goto $+1
nop

;4 cycles (including call)
return
;************************************************* ******************************
UP_Wait_80µs
;394 cycles
movlw 0x83
movwf d0
UP_Wait_80µs_0
decfsz d0, f
goto UP_Wait_80µs_0

;2 cycles
goto $+1

;4 cycles (including call)
return
;************************************************* ******************************
UP_Wait_3µs
;10 cycles
movlw 0x03
movwf d0
UP_Wait_3µs_0
decfsz d0, f
goto UP_Wait_3µs_0

;1 cycle
nop

;4 cycles (including call)
return
;*************************Sensor Unterprogramme*********************************
UP_init_ds18s20;Dient zur Initialisierung des 1-Wire Sensors DS18S20
CALL UP_Ausgang
BCF PORTA, 0
CALL UP_Wait_600µs ;600 µs low -> Reset
BSF PORTA, 0
CALL UP_Eingang
CALL UP_Wait_50µs ;50 us Pause

init_ds18s20_loop
BTFSC PORTA, 0
GOTO init_ds18s20_loop ;Warten bis Presence = Low
Return
;************************************************* ******************************
UP_write_ds18S20
CALL UP_Ausgang ;Setze PORTA,0 als Ausgang
MOVLW D'8' ;Lade 8 in die Variable
MOVWF zaehler ;zaehler

write_ds18S20_loop
RRF DS18S20, f ;Nach rechts verschieben
BTFSS STATUS, C ;Prüfe Carrybit auf 1...
GOTO write_zero ;ist es nicht auf 1 dann rufe UP_write_zero auf
CALL UP_write_one ;wenn es auf ist dann Rufe UP_write_one auf
GOTO verkleinere ;
write_zero CALL UP_write_zero ;
verkleinere DECFSZ zaehler, f ;Verkleinere Zähler
GOTO write_ds18S20_loop ;Weitermachen, bis alle 8 Bits gesendet
CALL UP_Eingang ;Setze nun PORTA,0 wieder als Eingang
RETURN
;************************************************* ******************************
UP_read_ds18S20
CLRF DS18S20 ;lösche den Inhalt von der Variable
BCF STATUS, C ;setze Carrybit auf 0
MOVLW D'8' ;Lade 8 in die Variable zaehler
MOVWF zaehler

read_ds18S20_loop
CALL UP_Ausgang
BCF PORTA, 0 ;Ziehe ihn nun auf Low
nop
CALL UP_Eingang
BSF PORTA, 0 ;High, wird nicht ausgegeben
CALL UP_Wait_3µs
BSF STATUS, C
BTFSS PORTA,0 ;Prüfe auf 1
BCF STATUS, C ;setze Carrybit auf 0
RRF DS18S20, f ;Nach rechts verschieben ins File Register
CALL UP_Wait_80µs ;80 µs Pause
DECFSZ zaehler, f
GOTO read_ds18S20_loop ;Weitermachen, bis alle 8 Bits empfangen

RETURN
;************************************************* ******************************
UP_read_temp;Lese aus dem Sensor die Temperatur aus -->Binär Daten
CALL UP_init_ds18s20 ;DS1820 initialisieren & erkennen
CALL UP_Wait_600µs ;Warte 600µs

MOVLW 0xCC ;ROM-Kommando 0xCC: Skip ROM
MOVWF DS18S20
CALL UP_write_ds18S20
CALL UP_Wait_600µs

MOVLW 0x44 ;Kommando 0x44: Convert Temperature
MOVWF DS18S20
CALL UP_write_ds18S20
CALL UP_Wait_1s

CALL UP_init_ds18s20
CALL UP_Wait_600µs

MOVLW 0xCC ;ROM-Kommando 0xCC: Skip ROM
MOVWF DS18S20
CALL UP_write_ds18S20

MOVLW 0xBE ;Kommando 0xBE: Read Scratchpad
MOVWF DS18S20
CALL UP_write_ds18S20
CALL UP_read_ds18S20 ;Aufruf des Unterprogrammes UP_read_ds18S20

MOVWF DS18S20
MOVF temp1 ;Temperatur LSB

CALL UP_read_ds18S20
MOVWF DS18S20
MOVLW temp2 ;Temperatur MSB

Return
;************************************************* ******************************
UP_convert_temp
;This routine will return the number of decimal
;hundreds from an 8-bit binary
;Input: w
;Output: w
;RAM:2
;Cycles: 12-24

GETHNDS movwf temp1
clrf w2
gethnds_loop movlw .100
incf w2,f
subwf temp1,f
btfsc STATUS,C
goto gethnds_loop
decf w2,w
return
;---
;This routine will return the number of decimal
;tens from an 8-bit binary
;Loop based, so it might take some time...
;It needs getones too
GETTENS movwf temp1
clrf w2
gettens_loop movlw .10
incf w2,f
subwf temp1,f
btfsc STATUS,C
goto gettens_loop
decf w2,w
goto GETONES

;---
;This routine will return the number of decimal
;ones from an 8-bit binary
GETONES movwf w2
movlw .10
deltens_loop subwf w2,f
btfsc STATUS,C
goto deltens_loop
addwf w2,w
return
;************************************************* ******************************
UP_Send_Temp ;Dient zum Senden der Temperatur
MOVLW temp1
MOVWF PORTB
call UP_Wait_1s


Return

;************************************************* ******************************
UP_Eingang ;Unterprogramm das dazu dient einen Ausgang als Eingang zusetzen
BSF STATUS, RP0
BSF TRISA,0
BCF STATUS, RP0
Return

;************************************************* ******************************
UP_Ausgang ;Unterprogramm das dazu dient einen Eingang als Ausgang zusetzen
BSF STATUS, RP0
BCF TRISA,0
BCF STATUS, RP0
Return

;************************************************* ******************************
UP_write_zero ;Dient zum Schreiben einer log 0.
BCF TRISA,0
CALL UP_WAIT_60µs
BSF TRISA,0
Return
;************************************************* ******************************
UP_write_one ;Dient zum Schreiben einer log 1.
BCF TRISA, 0
CALL UP_WAIT_60µs
BSF TRISA,0
CALL UP_WAIT_60µs
Return
;************************************************* ******************************
END


Habe ich irgendwas vergessen bzw gebe ich den BCD Code falsch aus?

mfg
schally

PICture
15.04.2007, 17:30
Hallo shally!

Deine Frage kannst Du selber am schnellsten beantworten, wenn Du ein kleines Testprogramm für Ausgabe von dem Register wo sich die bin Zahl befindet, schreibst. Ein Fehler kann am schnellsten gefunden werden, wenn man von Ende eines Programms anfängt. Wenn die Ausgabe i.O. ist, dann kann das Auslesen des DS 18S20 fehlerhaft sein, u.s.w. Jeder ausser Dich selber braucht viel mehr Zeit um ein Fehler zu finden, weil keiner das Programm so gut, wie Du, kennt. :)

MfG

schally
16.04.2007, 16:47
Hi,
also ich habe mal geschaut irgendwie ändert sich die Temp garnicht.
Der Code ist im Anhang komme echt nicht mehr weiter.

Mfg
schally

schally
16.04.2007, 19:30
also ich glaube das Problem liegt beim Auslesen des Sensors
da er zwar angesprochen wird jedoch immer wieder den gleichen Wert in die Variable schreibt.

mfg
schally

schally
16.04.2007, 19:30
also ich glaube das Problem liegt beim Auslesen des Sensors
da er zwar angesprochen wird jedoch immer wieder den gleichen Wert in die Variable schreibt.
Jedoch wie bekomme ich das weg habe keine Ahnung.

mfg
schally