Even voorstellen, mijn naam is Jurgen en als ik wat tijd kan vinden speel ik wat met microcontrollers en lees ik wat mee op CO
.
Nu zou ik een thermometer willen maken met een DS18B20, een PIC16F690 en 3 7-segment displays.
ASM code is geschreven, maar wat blijkt, ik kan er langs geen kanten een correcte temperatuur opkrijgen. De data dat ik uitlees springt van 18°C naar 151°C naar 20°C,... Ik zit al meer dan een week vanalles te proberen en heb ik al 10 keer de datasheet van voor naar achter gelezen, maar ik kan het maar niet vinden. Voor zover ik kan zien zit ik juist met de timing, de pic draait op de 8Mc interne klok (deze heb ik ook nagezien met een blokgolf op de scoop)
Kan er iemand met een frisse geest eens de code nalezen of die iets kan vinden?
PS, de sensor is met een pull-up van 4K7 op PORTA,5 aangesloten en heeft geen parasitaire voeding.
De code was iets te groot om hier te posten, maar je kan ze hier downloaden : http://users.telenet.be/saskia-jurgen/CO/test2.asm
Alvast bedankt!
WilToyo
Maak me niet gek, ik ben al gek.
Even een gedachte spinsel van mijn kant. Zit het niet in de aansturing van de diplays perongeluk? Als je (ruwe) data eens doorstuurd via de uart naar je PC. Dan weet iig of je de communicatie met DS1820 goed gaat.
Nee, ik denk het niet, want als ik de variabelen zelf invul komt dit wel correct op het display.
Ik kan trouwens niet meer aan de uart, die pinnen zijn al bezet...
Arco
Special Member
Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Zo te zien maak je de DS18 pin nergens laag bij output. Dat moet natuurlijk wel, anders is de status onbepaald. (Hangt af van of de input op dat moment toevallig hoog of laag is...)
Na een BCF TRISDS18 moet je een BCF DS18 geven...
Arco, ik had goede hoop dat dit inderdaad het probleem was, maar ik krijg nog steeds dezelfde vreemde waardes... 
Nog een idee? Ik ben er zeker van dat het iets simpel is waar ik steeds maar over kijk...
@kombucha De pull up gaat inderdaad naar de plus.
Nieuwe versie met de tip van Arco staat online op dezelfde locatie.
Mischien nog een aanvulling, als ik gewoon het scratchpad uitlees krijg ik wel mooi 85 terug, dus dat gedeelte zou moeten werken...
Wat het natuurlijk nog vreemder maakt...
Arco
Special Member
Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Nog een update, heb net een nieuwe sensor gehaald, en probleem blijft bestaan...
Nog iets waar het niet aan ligt denk ik dan maar...
Even een kickje, mischien zien jullie er wat meer in als ik enkel de routines verantwoordelijk voor de communicatie hier post?
Eerst de hoofdlus :
main
banksel INTCON
bcf INTCON,T0IE ;Interupts negeren
bcf STATUS,RP0
call ClearDigit
call GetTemp ;Haal temperatuur op van DS18
call Cond_Data ;Verwerk 2 bytes naar 3 getallen BCD
banksel INTCON ;Interupts terug toelaten
bsf INTCON,T0IE
bcf STATUS,RP0
call Delay1s ;2Seconden wachten
call Delay1s
goto main ;Terug naar begin
Dan de hoofdroutine die voor de communicatie :
GetTemp
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; goto DEBUG ;Spring direct naar scratchpad lezen (85 terug)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
call DS_Reset ;Reset DS18
bcf STATUS,RP0
movlw 0xCC ;Skip ROM
movwf DS_Data_L
call DS_Out ;0xCC naar DS18
movlw 0x44 ;Convert T
movwf DS_Data_L
call DS_Out ;0x44 naar DS18
banksel TRISA
bsf TRISDS18 ;DQ hoog
bcf STATUS,RP0
call Wait_Temp ;Wacht tot temperatuur
btfss DS_Data_L,0 ;conversie klaar is
goto $-2
DEBUG
call DS_Reset ;Reset DS18
movlw 0xCC ;Skip ROM
movwf DS_Data_L
call DS_Out ;0xCC naar DS18
movlw 0xBE ;Read Scratchpad
movwf DS_Data_L
call DS_Out ;0xBE naar DS18
call DS_IN ;Haal data op van DS18
banksel TRISA
bsf TRISDS18 ;DQ hoog
bcf STATUS,RP0
RETURN
Deze reset de DS18
DS_Reset
banksel TRISA
bcf TRISDS18 ;DQ laag voor 500µS
banksel PORTA
bcf DS18
movlw d'100' ;Delay500µs
movwf d1
call Delay
decfsz d1
goto $-2
banksel TRISA
bsf TRISDS18 ;DQ hoog
bcf STATUS,RP0
movlw d'20' ;Delay100µs
movwf d1
call Delay
decfsz d1
goto $-2
banksel PORTA
btfss DS18 ;Test op presence puls na 100µS,
goto $-1 ;en wacht daarna nog 400µS
movlw d'80' ;Delay400µs
movwf d1
call Delay
decfsz d1
goto $-2
bcf STATUS,RP0
RETURN
Deze wacht tot de sensor klaar is met de temperatuur conversie (ja ik kan gewoon 750mS wachten maar deze routine is een spinsel uit het foutzoeken)
Wait_Temp
bcf STATUS,RP0
clrf DS_Data_L ;Clear DS_Data_L
banksel TRISA
bcf TRISDS18 ;DQ laag voor 4µS
banksel PORTA
bcf DS18
call Delay
bsf TRISDS18 ;DQ terug hoog
call Delay
call Delay
banksel PORTA
btfsc DS18 ;Controleer na 8µS als DQ laag is
;(temp conversie klaar)
bsf DS_Data_L,0 ;Zet een vlag
movlw d'12' ;Delay60µs
movwf d1
call Delay ;Wacht nog 60µS tot einde Read time slot
decfsz d1
goto $-2
RETURN
Deze verstuurt een byte naar de sensor
DS_Out
movlw 0x08 ;8 bits versturen
movwf Teller1
DS_Out_1
btfsc DS_Data_L,0 ;Test als de bit die klaarstaat 0 of 1 is
goto $+3
call DS_Out_LO ;Bij 0, spring naar DS_Out_LO
goto $+2
call DS_Out_HI ;Bij 1, spring naar DS_Out_HI
rrf DS_Data_L,f
decfsz Teller1,f ;decrease teller, bij teller=0 spring verder
goto DS_Out_1
banksel TRISA
bsf TRISDS18 ;DQ terug hoog
bcf STATUS,RP0
RETURN
DS_Out_LO
banksel TRISA
bcf TRISDS18 ;DQ laag voor 70µS
banksel PORTA
bcf DS18
movlw d'14' ;Delay70µs
movwf d1
call Delay
decfsz d1
goto $-2
banksel TRISA
bsf TRISDS18 ;DQ terug hoog, en wacht nog 4µS
call Delay ;Delay4µs
bcf STATUS,RP0
RETURN
DS_Out_HI
banksel TRISA
bcf TRISDS18
banksel PORTA
bcf DS18 ;DQ laag voor 8µS
call Delay ;Delay8µs
call Delay
banksel TRISA
bsf TRISDS18 ;DQ terug hoog, en wacht nog 60µS
bcf STATUS,RP0 ;tot einde write slot
movlw d'12' ;Delay60µs
movwf d1
call Delay
decfsz d1
goto $-2
bcf STATUS,RP0
RETURN
Deze ontvangt 2 bytes van de sensor
DS_IN
bcf STATUS,RP0
clrf DS_Data_L ;Wis variabelen
clrf DS_Data_H
movlw d'16' ;16 bits inlezen
movwf Teller1
DS_IN_1
bcf STATUS,C
rrf DS_Data_L,f ;Roteer Data_L naar rechts
bcf STATUS,C
rrf DS_Data_H,f ;Roteer Data_H naar rechts
btfsc STATUS,C ;Bij carry, zet bit bij Data_L
bsf DS_Data_L,7
banksel TRISA
bcf TRISDS18 ;DQ laag voor 4µS
banksel PORTA
bcf DS18
call Delay ;Delay4µs
banksel TRISA
bsf TRISDS18 ;DQ terug hoog
call Delay ;Delay8µs
call Delay
banksel PORTA
btfsc DS18 ;Test na 8µS of er een bit klaarstaat
bsf DS_Data_H,7 ;Bij 1, zet bij Data_H, en wacht nog
;60µS tot einde Read slot
movlw d'12' ;Delay60µs
movwf d1
call Delay
decfsz d1
goto $-2
decfsz Teller1 ;Decrease Teller, bij 0 spring verder
goto DS_IN_1
call DS_Reset ;Na 2 bytes gelezen, afbreken door Reset
RETURN
Deze zet de ontvangen data om in 3 bytes BCD, de tienden worden momenteel gebruikt om hondertallen te tellen.
Cond_Data
bcf STATUS,RP0
clrf Tientallen ;Variabelen resetten
clrf Eenheden
clrf Tienden
swapf DS_Data_L ;Nibbles van Data_L omwisselen
btfsc DS_Data_H,0 ;Relevante bits van Data_H verplaatsen
bsf DS_Data_L,4
btfsc DS_Data_H,1
bsf DS_Data_L,5
btfsc DS_Data_H,2
bsf DS_Data_L,6
bcf DS_Data_L,7
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;Test op hondertallen;;;;;;;;;DEBUG;;;;;;;;;;;;;;;;;;;;;;
movlw d'100'
subwf DS_Data_L,f ;Zet de hondertallen in tienden
btfss STATUS,C
goto $+3
incf Tienden
goto $-4
addwf DS_Data_L,f
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
movlw d'10' ;Tientallen Tellen
subwf DS_Data_L,f
btfss STATUS,C
goto $+3
incf Tientallen
goto $-4
addwf DS_Data_L,f
movlw d'1' ;Eenheden Tellen
subwf DS_Data_L,f
btfss STATUS,C
goto $+3
incf Eenheden
goto $-4
movlw d'10' ;Test op meer dan 9 in variabelen
subwf Tientallen,w ;bij meer dan 9 zet E op display
btfss STATUS,C
goto $+3
movlw d'10'
movwf Tientallen
movlw d'10'
subwf Eenheden,w
btfss STATUS,C
goto $+3
movlw d'10'
movwf Eenheden
movlw d'10'
subwf Tienden,w
btfss STATUS,C
goto $+3
movlw d'10'
movwf Tienden
bcf STATUS,RP0
RETURN
Het zal wel iets onnozels zijn waar ik blijf over kijken, maar ik hoop er op dat er iemand me op mijn fout kan wijzen. (Ik zal hem eeuwig dankbaar zijn
)
Arco
Special Member
Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Als je de interrupt routine uit de startpost gebruikt, moet je wel de w_temp en status_temp in shared memory zetten en niet in bank 0.
Gebruik bij jumps ook eens labels in je code; dan is het tenminste enigszins begrijpelijk.
(Op gebruik van het '$+' en '$-' directive zou eigenlijk straf moeten staan. Je krijgt er onvermijdelijk fouten door, en is zeer onoverzichtelijk...)
bij een vaste voeding hoef
je volgens mij niet op de presence puls te wachten
en kun je dat gewoon schrappen.
( bij mij ging het spul in een loop lopen )
ik denk overigens niet dat het invloed heeft op jou probleem
maar je weet nooit
sk
@Arco Ik w-temp & status_temp op 0x70 & 0x71 geplaatst (shared memory als ik de datasheet juist interpreteer) en heb nog steeds hetzelfde effect 
Ivm met de labels, ik dacht dat dit de gebruikelijke manier was om over en weer te springen, omdat er anders een warboel aan labels ontstaat... Moet ik mijn code eens aanpassen ter betere lezing...?
@Burner Wat bedoel je met 'bij mij ging het spul in een loop lopen'? Wacht je gewoon een tijdje na het resetten om verder te gaan met de communicatie?
Arco
Special Member
Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Ivm met de labels, ik dacht dat dit de gebruikelijke manier was om over en weer te springen, omdat er anders een warboel aan labels ontstaat...
Nee, het is nu juist een warboel. Als er staat 'goto $-5' moet je eerst gaan rekenen, terwijl 'goto mijn_label' meteen duidelijk is. Zeker als je je code na een jaar of zo terug ziet om iets aan te wijzigen, heb je alleen al een halve dag nodig om te begrijpen wat er precies allemaal gebeurt...
Helemaal in de problemen kom je als je een extra instructie toevoegt, en vergeet de sprong aan te passen. Dat is meestal goed voor een paar uurtjes genoeglijk zoeken naar de oorzaak van het ineens niet meer werken...
@Burner Wat bedoel je met 'bij mij ging het spul in een loop lopen'? Wacht je gewoon een tijdje na het resetten om verder te gaan met de communicatie?
het bleef maar wachten op een presence puls, die maar niet kwam..
Arco
Special Member
Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
het bleef maar wachten op een presence puls, die maar niet kwam..
Nooit eindeloze loops gebruiken, altijd een time-out inbouwen...
Eindelijk nog eens tijd gevonden om wat met de hobby bezig te zijn, en :
Probleem gevonden!
Heb de boel eens op een breadboard gemaakt met een andere PIC, die ik kon debuggen met mijn elektuur ICD2 kloon, en de fout kwam al na 2 minuten bovendrijven!
Het probleem zat hem hier :
Cond_Data
bcf STATUS,RP0
clrf Tientallen ;Variabelen resetten
clrf Eenheden
clrf Tienden
swapf DS_Data_L ;Nibbles van Data_L omwisselen
btfsc DS_Data_H,0 ;Relevante bits van Data_H verplaatsen
bsf DS_Data_L,4
btfsc DS_Data_H,1
bsf DS_Data_L,5
btfsc DS_Data_H,2
bsf DS_Data_L,6
bcf DS_Data_L,7
............
Ik had bij mijn eerste test van de communicatie de bits van de getallen na de komma genegeerd, met het idee 'dat komt straks wel, eerst de gehele getallen', met als gevolg dat na het wisselen van de nibbles van de low byte ik had vergeten de bits van de tienden te wissen, en zodoende een volledig verkeerde waarde op het display kreeg! 
Zoals bij mijn eerste vermoeden dus een stomme fout waar ik maar bleef overkijken!
Positief punt is wel dat de code verantwoordelijk voor de communicatie wel blijkbaar direct juist was!
Toch bedankt aan diegenen die wat tijd in mijn geklooi hebben gestopt!