im missing something. wheres 0x391Taking your example of 0x391 from your program
im missing something. wheres 0x391
As this program/system will display temperature to 1 decimal place, the lower nibble of the LSbyte
; is used for the decimal number, (xxxxxxxx xxxx0000). While the upper nibble of the LSbyte and the
; lower nibble MBbyte are used for the whole number, (xxxx0000 0000xxxx).
; Note that 12-bit resolution gives increments of 0.0625�C per bit
;
; Example, 0000 0011 1001 0001 ; 913 x .0625 = 57.0625�C
; (MS byte) (LS byte)
;
I thought you were referring to the post above that where i loaded a dummy 25.0... I didnt read your post clearly, sorry my mistake.hi Jake,
0000 0011 1001 0001 binary is 0x0391. [decimal 913]
I thought you were referring to the post above that where i loaded a dummy 25.0... I didnt read your post clearly, sorry my mistake.
REARRANGE_RESULT ; This routine rearranges the 2 Temperature result bytes into useable data
; After the DS18B20 finishes a Temperature Conversion, the 12-bit result is stored in two 8-bit
; registers. Providing the temperature is a positive number (in Degrees C) the upper nibble of the
; MSbyte (SCRATCHPAD_BYTE1) will always be 0000. (0000xxxx xxxxxxxx)
; As this program/system will display temperature to 1 decimal place, the lower nibble of the LSbyte
; is used for the decimal number, (xxxxxxxx xxxx0000). While the upper nibble of the LSbyte and the
; lower nibble MBbyte are used for the whole number, (xxxx0000 0000xxxx).
; Note that 12-bit resolution gives increments of 0.0625°C per bit
;
; Example, 0000 0011 1001 0001 ; 913 x .0625 = 57.0625°C
; (MS byte) (LS byte)
;
; So, this routine re-arranges the nibbles of both bytes so that tables can be used to obtain
; numbers to display.
; i.e. The MSbyte is used for the 1's and 10's digit (57), and the LSbyte is used for the rounded
; decimal digit (.1)
; Note that the upper nibble of the LSbyte is masked.
;
; Data after rearrangement 0011 1001 0000 0001
; (MS byte) (LS byte)
;
MOVF SCRATCHPAD_BYTE0, W ; MOVE Temperature LSbyte to W
MOVWF TEMPLO ; MOVE W to Temp0 GPR
MOVF SCRATCHPAD_BYTE1, W ; MOVE Temperature MSbyte to W
MOVWF TEMPHI ; MOVE W to Temp0 GPR
; EXAMPLE, TEMPHI = 0000 0001 TEMPLO = 1001 0001
MOVLW 0XF0 ; W = 1111 0000
ANDWF TEMPLO, W ; F = 1001 0001 W = 1001 0000,
IORWF TEMPHI, F ; F = 0000 0001 F = 1001 0001
SWAPF TEMPHI, F ; F = 1001 0001 F = 0001 1001=TEMPHI
MOVLW 0X0F ; W = 0000 1111
ANDWF TEMPLO, F ; W = 1001 0001 F = 0000 0001=TEMPLO
HOW_MANY_TENS ; This routine counts how many 10's are in the TEMPHI register
INCF TEMPHI ; Preload TEMPHI + 1
CLRF TENS ; TENS GPR = 0000 0000
MOVLW D'246' ; MOVE Decimal'246' to W
MOVWF ONES ; Store in ONES GPR (I would end up moving this register to ONES register anyway so here I'm using it as a 'count up' register
BCF STATUS, Z ; Clear Zero bit of STATUS register
DECF TEMPHI, F ; DECement TEMPHI register
BTFSC STATUS, Z ; Test Zero bit if Zero to see if last instruction = 0000 0000
GOTO HOW_MANY_ONES ; IS 0, number less than 10 so GOTO HOW_MANY_ONES to count the ones
BCF STATUS, Z ; Clear Zero bit of STATUS register
INCF ONES, F ; Effects Zero bit, therefore we can test if Zero. Remember, using ONES GPR as a countup register for now
BTFSS STATUS, Z ; Test Zero bit if Zero to see if last instruction = 0000 0000
GOTO $-D'7' ; NOT 0, GOTO here - 7 instructions
INCF TENS, F ; INCrement TENS register which represents 10 per increment. Will use this to CALL table
GOTO $-D'11' ; TENS INCremented in previous instruction, GOTO here - 11 instructions
HOW_MANY_ONES ; This routine counts how many 1's are in the TEMPHI register
MOVLW D'246' ; Because the ONES register is preloaded with D'246' to begin with & then INCremented every time TEMPHI is DECremented, we can
SUBWF ONES, F ; simply SUBtract D'246' from the ones register to see how many ones are left over, then use this when calling the table
; TENS holds amount of tens (i.e. 0000 0010 = 2x10) ONES holds amount of ones (i.e. 0000 0101 = 5x1)
out of curiosity how many instructions roughly would your x10 /16 routine take?
yeah......Also found one mistake in your ISR.
; Refresh display
CLRF PORTB ; Blank the display
MOVF PORTA, W ; MOVE PORTA's current state to W
ANDLW B'11110000' ; Clear ONLY Column Select Bits & leave upper nibble unchanged
IORWF COLSEL, W ; Inclusive OR above with COLSEL register
MOVWF PORTA ; Leave upper nibble of PORTA unchanged & select new Column
MOVF DIGIT, W ; Column number, 0..3
[COLOR=Red]ADDLW HUNS_ARRANGEMENT[/COLOR] ; Add to 'HUNS_ARRANGEMENT' address
MOVWF FSR ; FSR = HUNS + 0forHUNS, 1forTENS, 2forONES & 3forTENTHS as they are in sequencial order in RAM
MOVF INDF, W ; W register now holds 7 Segment arrangement for corresponding digit
BTFSC COLSEL, 1 ; Are we display ONES Column
IORLW B'00000001' ; YES, so display deciaml point
MOVWF PORTB ; NO, hide deciaml point and display new column
; Prepare for next column interrupt
BCF STATUS, C ; Clear C bit of STATUS register
RRF COLSEL, F ; Advance column select bit
INCF DIGIT, F ; INCrement Digit jump pointer (used when indirect addressing above)
[COLOR=Red]BTFSS STATUS,C[/COLOR] ; Was that the last column?
GOTO $+4 ; NO, do not reset DIGIT and COLumnSELect
CLRF DIGIT ; Reset Digit jump pointer
[COLOR=Red]; CLRF COLSEL [/COLOR][COLOR=Red]; Clear COLumnSELect <- unneccessary, COLSEL already 0[/COLOR]
BSF COLSEL, 3 ; Reset COLumnSELect to Hundreds column 1 (00001000)
; Prepare for next column interrupt
[COLOR=RoyalBlue]INCF DIGIT, F ; INCrement Digit jump pointer (used when indirect addressing above)
BCF DIGIT,2 ; range 0..3, inclusive (pseudo DIGIT = DIGIT % 4)
BCF STATUS, C ; Clear C bit of STATUS register
RRF COLSEL, F ; Advance column select bit
[/COLOR][COLOR=RoyalBlue]BTFSC STATUS,C ; shifted last column bit into Carry? no, skip, else
BSF COLSEL, 3 ; Reset COLumnSELect to Hundreds column 1 (00001000) [/COLOR]
;
; "tenths" = fraction * 10 / 16 (Pommie's fraction routine)
;
movlw 0x0F ;
andwf TempLo,F ;
movf TempLo,W ;
addwf TempLo,F ; *2, C=0
rlf TempLo,F ; *4, C=0
addwf TempLo,F ; *5, C=0
rlf TempLo,F ; *10
[COLOR="red"]movlw 8 ;=0.5 in 4.4 format
addwf TempLo,F ;add it[/COLOR]
swapf TempLo,W ; pseudo divide by 16
andlw 0x0F ;
movwf tenths ;
It's the label "Delay" address minus one.Where is: Delay-1? This is the last instruction in the program.
I originally had this: which was right (as 0x20 is the location for HUNS_ARRANGEMENT) but changed it to a lable and changed it incorectly.Code:MOVF DIGIT, W ; Column number, 0..3 ADDLW [COLOR="red"]HUNS_ARRANGEMENT[/COLOR] ; Add to 'HUNS_ARRANGEMENT' address MOVWF FSR ; FSR = HUNS + 0forHUNS, 1forTENS, 2forONES & 3forTENTHS as they are in sequencial order in RAM MOVF INDF, W ; W register now holds 7 Segment arrangement for corresponding digit
MOVF DIGIT, W ; Column number
ADDLW [COLOR="red"]0x20[/COLOR] ; Add to 'HUNS' GPR address
MOVWF FSR ; FSR = HUNS + 0forHUNS, 1forTENS, 2forONES & 3forTENTHS as they are in sequencial order in RAM
MOVF INDF, W ; W register now holds 7 Segment arrangement for corresponding digit
; ; Prepare for next column interrupt
BCF STATUS, C ; Clear C bit of STATUS register < not needed
RRF COLSEL, F ; Advance column select bit
INCF DIGIT, F ; INCrement Digit jump pointer (used when indirect addressing above)
BTFSS DIGIT, 3 ; Was that the last column?
GOTO $+4 ; NO, do not reset DIGIT and COLumnSELect
CLRF DIGIT ; Reset Digit jump pointer
CLRF COLSEL ; Clear COLumnSELect register
BSF COLSEL, 3 ; Reset COLumnSELect to Hundreds column 1 (00001000)
INCF DIGIT, F ; INCrement Digit jump pointer (used when indirect addressing above)
BCF STATUS, C ; Clear C bit of STATUS register
RRF COLSEL, F ; Advance column select bit
BTFSS STATUS,C ; Was that the last column? (or, Is Carry Flag Set?)
GOTO $+3 ; NO, do not reset DIGIT and COLumnSELect
CLRF DIGIT ; Reset Digit jump pointer
BSF COLSEL, 3 ; Reset COLumnSELect to Hundreds column 1 (00001000)
You're actually testing the fourth bit which would test for the transition from 7 (00000111) to 8 (00001000).And my advance routine: Even though longer than need be, It should've still worked.
Tesing the 3rd bit of DIGIT reg will tell the program when to reset DIGIT and COLSEL. (when DIGIT = 0000 0100 = 4 = too many, reset.) shown below;
Code:; ; Prepare for next column interrupt BCF STATUS, C ; Clear C bit of STATUS register < not needed RRF COLSEL, F ; Advance column select bit INCF DIGIT, F ; INCrement Digit jump pointer (used when indirect addressing above) [COLOR=Red]BTFSS DIGIT, 3[/COLOR] ; Was that the last column? GOTO $+4 ; NO, do not reset DIGIT and COLumnSELect CLRF DIGIT ; Reset Digit jump pointer CLRF COLSEL ; Clear COLumnSELect register BSF COLSEL, 3 ; Reset COLumnSELect to Hundreds column 1 (00001000)
We can use this simple two instruction increment / modulo function when the variable value range is a binary weighted value minus 1 (0..1, 0..3, 0..7, 0..15, 0..31, etc.). Here's a quick-n'-dirty analysis;... that shorter code you have writen in blue... Will that work? where and when does DIGIT get reset to zero?
;
; 1st 'bump' -> 00000000 + 1 = 00000001, clear bit 2 -> 00000[COLOR=RoyalBlue]0[/COLOR]01, result 1
; 2nd 'bump' -> 00000001 + 1 = 00000010, clear bit 2 -> 00000[COLOR=RoyalBlue]0[/COLOR]10, result 2
; 3rd 'bump' -> 00000010 + 1 = 00000011, clear bit 2 -> 00000[COLOR=RoyalBlue]0[/COLOR]11, result 3
; 4th 'bump' -> 00000011 + 1 = 00000100, clear bit 2 -> 00000[COLOR=RoyalBlue]0[/COLOR]00, result 0
;
[COLOR=RoyalBlue]incf DIGIT,F ; DIGIT = (DIGIT + 1) % 4
bcf DIGIT,2 ; [/COLOR]
Cheerful regards, MikeOk, so thats fixed.Code:MOVF DIGIT, W ; Column number ADDLW [COLOR=red]0x20[/COLOR] ; Add to 'HUNS' GPR address MOVWF FSR ; FSR = ... MOVF INDF, W ; W register now holds 7 Segment arrangement for corresponding digit
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?