Sida 1 av 2
ASM och MCP9701
Postat: 14 oktober 2010, 11:16:44
av PHermansson
Detta lyckas jag inte klura ut. MCP9701 ger 19,5mV per grad, min Pic har en A/D med 10 bitar. Spänningen ut från tempsensorn är 0,86V, från ADC:n får jag 00:B6. MSB är alltså 00 och LSB B6. I en gammal tråd läste jag att man kan omvandla detta till celsiusgrader genom att rotera två gånger till höger. Mätvärdena varierar lite, men vid nästa test får jag LSB=B4. Sen roterar jag två gånger:
Kod: Markera allt
rrf voltslo, f
rrf voltslo, f
movf voltslo,w
call prthex
(Rutinen prthex skriver ut värdet i W på en LCD). Svaret blir då 6D hexadecimalt, vilket blir 109 decimalt. Och så varmt är det definitivt inte här, en riktig termometer säger 22.1. Hur gör man?
Re: ASM och MCP9701
Postat: 14 oktober 2010, 11:34:13
av TomasL
AD-Omvandlarens resultat beror på dina referensspänningar.
Re: ASM och MCP9701
Postat: 14 oktober 2010, 11:40:17
av stekern
Men det är nåt annat som är skumt
0.86V/19.5mV = 44
och 0xb6 skiftat höger två steg = 45
så att man skall skifta två steg åt höger verka stämma, men din kod kanske inte gör det
och sen verkar tempsensorn ge fel värden ut
Edit: ändrade "AD-omvandlaren" till "tempsensorn"
Re: ASM och MCP9701
Postat: 14 oktober 2010, 11:46:52
av TomasL
Jo men ad-omvandlingen beror ju på referens spänningen, har du 5 V referens blir ju varje steg 5/1024=dvs 4,88mV/bit
Och om du får 0x00B6 ut blir det vid 5V referens 0,888V.
violket tyder på att din verkliga referens spänning är 4,8 V typ.
De där generella reglerna gäller enbart vid rätt utspänningsomfång, rätt matningsspänning och rätt referensspänning (både positiv och negativ)
Re: ASM och MCP9701
Postat: 14 oktober 2010, 11:55:55
av stekern
Givetvis, men jag gjorde (det kanske felaktiga) antagandet att TS hade fått 0,86V när han mätte på utgången, och då stämmer det inte.
Och är inte 19,5>>2 ungefär 4.88?
Re: ASM och MCP9701
Postat: 14 oktober 2010, 14:52:31
av Marta
När Du roterar värdet så roteras carryn in. Du måste föregå båda två rrf med att nolla carry. Alternativt kan Du maska resultatet av de två rrf med hex 3F.
Re: ASM och MCP9701
Postat: 14 oktober 2010, 22:19:57
av PHermansson
Jo 4.8V Vref stämmer bra. Kör med Vcc som ref och matar via USB, som i vanlig ordning inte lämnar 5.0V ut.
Så om jag lägger till "bcf status, c" före varje "rrf" så ska det funka?
Re: ASM och MCP9701
Postat: 15 oktober 2010, 11:35:56
av PHermansson
Har testat nu, svaret blir nu '2E', alltså 46 decimalt. Vref=Vcc= 4,76V, ut från MCP9701 är 0,87V.
0,87 - 0,4 (9701 ger 400mV ut vid 0 grader) = 0,47V. 470mV/19,5mV = 24,1, den andra termometern visar 22.0.
Men vad gör jag med värdet 46? Måste jag dra av de 0,4 volten??
Re: ASM och MCP9701
Postat: 15 oktober 2010, 12:23:50
av stekern
Ja, det låter väl vettigt.
Jag skulle dragit av 82 innan du skiftar (400/19,5)*4
så kan du använda de 2 nedersta bitarna som decimaler och tecknet blir rätt när resultatet underflowar (tempen <0)
så länge som du shiftar in 1:or om den översta biten är 1
Re: ASM och MCP9701
Postat: 15 oktober 2010, 13:44:20
av PHermansson
Hur räknar du fram 82? Typ var kommer fyran ifrån?
Själv tänkte jag att 4,76V/1024 ger 0,0046V/bit, 400mV är alltså 0,4/0,0046=86,95 bitar.
6Bh - 57h = 14h = 20dec? Men då har jag inte roterat?
Ska jag verkligen rotera 2ggr när jag bara använder de 8 LSB? Jag har ju valt att helt ignorera de 2 MSB då de aldrig kommer att behövas. 9701:an maxar på 125 grader och ger då knappt tre volt ut. (Intressant notering förresten om Figure 2-16 i databladet: En 9701 är värdelös som utetempgivare i Sverige, kurvan slutar vid ca -10 grader...)
Re: ASM och MCP9701
Postat: 15 oktober 2010, 13:54:43
av stekern
skifta åt höger 2 steg är samma som att dela med 4, skifta åt vänster 2 steg är samma som att multiplicera med 4
alltså multiplicerar jag resultatet med 4 för att få det i samma skala som resultatet från AD-omvandlaren.
Alternativt kan du ju ta ((400e-3)/(Vref/1024)), vilket ger i stort sett samma resultat.
Edit: Alternativ metoden var ju det du hade gjort ser jag nu när jag läste ditt inlägg lite nogrannare.
Re: ASM och MCP9701
Postat: 15 oktober 2010, 14:33:57
av stekern
PHermansson skrev:6Bh - 57h = 14h = 20dec? Men då har jag inte roterat?
Du har vänt på siffrorna, B6h - 57h = 5Fh = 95dec
95/4 = 23.75
Re: ASM och MCP9701
Postat: 15 oktober 2010, 15:05:37
av PHermansson
Ahh nu funkar det, tack!
Koden nu:
Kod: Markera allt
banksel adresl
movf adresl,w
banksel voltslo
movwf voltslo
movlw b'00000001' ; Clear display
fcall lcd_send_cmd
movlw H'57'
subwf voltslo, F
bcf status, C
rrf voltslo, f
bcf status, C
rrf voltslo, f
movf voltslo,w
call prthex
Nu visar displayen 16, den andra termometern 19,9. 16h=22dec, så det är hyfsat i alla fall. Hur kan jag få med decimalerna?
Re: ASM och MCP9701
Postat: 15 oktober 2010, 17:37:58
av stekern
De två bitarna som du skiftar ut innehåller decimalen i 4:e-delar.
Om vi tar dit exempel 0xB6-0x57 = 0x5F = 0b1011111
De två bitarna som skiftats ut är alltså 0b11 = 3, dvs decimaldelen är 3/4 = 0.75 (vilket stämmer överens med beräkningarna ovan där 0x5F/4 = 23.75)
Alltså kan du multiplicera de utskiftade bitarna med 25 för att få decimaldelen i heltal
Re: ASM och MCP9701
Postat: 20 oktober 2010, 08:06:50
av PHermansson
Ok just det. Har ändrat koden så att den tar tillvara på dessa bitar:
Kod: Markera allt
bcf status, C
rrf voltslo, f
clrf decimals
btfsc status,c
bsf decimals, 1
bcf status, C
rrf voltslo, f
btfsc status,c
bsf decimals, 0
Detta fungerar bra. Sen satte jag mig och klurade på hur jag skulle göra om 0-3 i decimals till 0, 25, 50 eller 75. Funderade en bra stund och kodade en stund, sen hade jag fått ihop detta:
Kod: Markera allt
; decimals = 0-3
movf decimals, W
;addlw H'30'
;call lcd_send_data
btfsc decimals, 1
goto twth ; 2 or 3, bit 1 set
;btfsc decimals, 0
goto zeon ; 0 or 1, bit 0 set but not bit 1
zeon
btfsc decimals, 0
goto zero ; Zero
goto one
zero
movlw 0
movwf tens_and_ones
goto prtdec
one
movlw 25
movwf tens_and_ones
goto prtdec
twth
btfsc decimals, 0
goto three ; bit 0 and bit 1 set = 3
; bit 1 set but not bit 0 = 2
goto two
two
movlw 50
movwf tens_and_ones
goto prtdec
three
movlw 75
movwf tens_and_ones
goto prtdec
prtdec
; Send ten's
swapf tens_and_ones, W
andlw H'F'
addlw H'30'
call lcd_send_data
; Send one's
movf tens_and_ones, W
andlw H'F'
addlw H'30'
call lcd_send_data
Nu idag när jag funderar på det inser jag hur enkelt det skulle bli om man använde en lookup-table istället
