Longloop
CLRF Delay1 ;
CLRF Delay2 ;
LOOP
DECFSZ Delay1,F ; 1 inst cycle, when delay1=0 => test = true skip next line.
GOTO LOOP ; 2 inst cycles, this is looped 256 times before skipping to next line => 768 microsec at 1 MIP
CALL GETSWITCH ; approx ~768 cycle intervals
CALL Strobe ; strobe the display based on 2 lsb's of Delay2 <-- where is this used?
DECFSZ Delay2,F ; 1 inst cycle
GOTO LOOP ; 2 inst cyles, by adding the loops = 256 * 768 + (256*3) = 257* 768 = 197376 microsec = .2 sec. Simple Substitute for ISR time control.
Goto Longloop ; CONTINUE
;*******************************************************************
; main loop *
;*******************************************************************
loop
decfsz Delay1,F ; delay ~768 usecs (4-MHz) |B0
goto loop ; |B0
call GETSWITCH ; sample & debounce inputs |B0
call Strobe ; refresh the display |B0
goto loop ; |B0
Hi Mosaic:
May I ask about the purpose of this section of code, please? It appears you're calling the GETSWITCH and Strobe subroutines at approximately ~768 usec intervals (plus the overhead of the subroutines) but you're not doing anything at the longer ~199 msec interval. I'm just curious what you may have had planned for that ~199 msec interval? Comments suggest you're using the least significant two bits of the Delay2 variable in the Strobe subroutine but I haven't found that in the code. Am I missing something?
If you're not using the ~199 msec interval, why not simplify the "main loop"? You wouldn't even need to preset the Delay1 variable;
Well, the program certainly deserves a cleanup. It's difficult to figure out what it's doing with the sloppy formatting and several extraneous code fragments.The 'delay2' comment seems to be a mistake it should be 'Digitstrobe', I had prev. used Delay2 in an older variant of the code (which made the code dependent on the delay loop) and the comment slipped by getting updated.
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; 739 cycles (isochronous) ~
radix dec ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Bin2Dec
movf ClickL,W ; click count lo |B0
movwf Blo ; |B0
movf ClickH,W ; click count hi |B0
movwf Bhi ; |B0
call Div10 ; |B0
movwf Units ; save 'ones' |B0
call Div10 ; |B0
movwf Tens ; save 'tens' |B0
call Div10 ; |B0
movwf Hundreds ; save 'hundreds' |B0
Div10
movlw 16 ; |B0
movwf Ctr ; repeat for 16 bits |B0
clrf Rem ; clear 'remainder' |B0
DivLoop
rlf Blo,W ; |B0
rlf Bhi,F ; |B0
rlf Rem,F ; move MSB of number into Rem |B0
movlw 10 ; |B0
subwf Rem,W ; does 10 go in? |B0
skpnc ; no, skip, else |B0
movwf Rem ; update remainder |B0
rlf Blo,F ; shift in the borrow bit |B0
decfsz Ctr,F ; all 16 bits? yes, skip, else |B0
goto DivLoop ; loop |B0
movf Rem,W ; note Rem equates to Thousands |B0
return ; |B0
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Bindec ;calculate decimal# for each 7seg led block
clrf Thousands
clrf Hundreds
clrf Tens
clrf Units
movf ClickL,w
movwf TempL
movf ClickH,w
movwf TempH
call Thou ; get thousands in decimal
movlw .10 ; check for 10,000 or more
subwf Thousands,w; if Thousands < 10, carry is clr.
btfsc STATUS,C ;
goto Overrange ;
Call Hundred ; get hundreds
call Ten ; get tens & units.
return
Overrange
movlw 0x79 ; E pattern
movwf Thousands
movlw b'01010000' ; r pattern
movwf Hundreds
Movwf Tens
movlw 0x06 ; '1' pattern (error 1)
movwf Units
return
Thou movlw .3 ; high byte set to 3 = 768
movwf FixedH ; high byte of # to be subtracted.
movlw .232 ; low byte
movwf FixedL ; 768 + 232 = 1000's column
ThouCount
call Subtract
xorlw .1 ; check for returned wreg value. A zero occurs if a 1 was returned
btfss STATUS,Z ; branch if 1 was returned, else
goto Fixremainder ; due to last subtraction the remainder went -ve, so we fix this.
incf Thousands,f
goto ThouCount
Fixremainder ;restore remainder to continue calculating for next decimal column.
movf FixedL,w ; low byte
addwf TempL,f ; TempL=TempL + FixedL
movf FixedH,w ; hi byte
btfsc STATUS,C ; check for carry, set if TempL + FixedL >255
incfsz FixedH,w ; Increment due to carry set ,if zero skip next.
addwf TempH,f ; TempH=TempH+FixedH (+1 if carry was set)
return
Hundred movlw 0 ; high byte set to 0
movwf FixedH ; high byte of # to be subtracted.
movlw .100 ; low byte
movwf FixedL ; 0 + 100 = 100's column
HdrdCount
call Subtract
xorlw .1 ; check for returned wreg value. A zero occurs if a 1 was returned
btfss STATUS,Z ; branch if 1 was returned, else
goto Fixremainder ; due to last subtraction the remainder went -ve, so we fix this.
incf Hundreds,f
goto HdrdCount
Ten movlw .10
subwf TempL,f; test for 10 if carry clr wreg is under 10
btfsc STATUS,C ;skip if carry clr (-ve result) , else
incf Tens,f; incr the tens column
btfsc STATUS,C ; skip if carry clr (-ve result), else
goto Ten ; now check for 20,30 etc
movf TempL,w
addlw .10; as last calc was -ve recreate +ve number.
DispLEDS
call Dpattern
Movwf Units ; store 7 seg display pattern for units
movf Tens,w
call Dpattern
movwf Tens; store 7 seg display pattern for tens
movf Hundreds,w
call Dpattern
movwf Hundreds; store 7 seg display pattern for tens
movf Thousands,w
call Dpattern
movwf Thousands
return
Subtract ; 2byte subtraction to determine decimal 7 seg columns
movf FixedL,W
subwf TempL,f ; TEMPL= TEMPL-FIXEDL
movf FixedH,W
btfss STATUS,C ; branch if TEMPL>FIXEDL, else
incfsz FixedH,W ; setup to reduced TempH by 1 extra (sim. a borrow).
subwf TempH,f ;TempH=TempH-FixedH
btfss STATUS,C ;branch if TempH>FixedH, else
retlw .0 ; if carry is clr return with a 0 in wreg
retlw .1 ; if carry is set return with a 1 in wreg.
Yes, there are some easy-to-reconcile differences. For example, the "DispLEDS" routine at the tail end of your binary-to-decimal routine performs four separate conversions of numeric data in the "Thousands", "Hundreds", "Tens", and "Units" variables into LED segment data;That's a bit of apples vs oranges.
My code u quoted does more than just Bin to Dec. Apart from being faster, it does 3 other things.
It handles the 7 segment LED pattern display updates, the over-range error condition msg as well as provides a gen purpose 16 bit subtract (& compare routine for bubble sorting values) which is often reused for other parts of application dev.
Around 35 lines extra for just those items.
;
; excerpt from Mosaic's binary-to-decimal subroutine
;
DispLEDS
call Dpattern
Movwf Units ; store 7 seg display pattern for units
movf Tens,w
call Dpattern
movwf Tens ; store 7 seg display pattern for tens
movf Hundreds,w
call Dpattern
movwf Hundreds ; store 7 seg display pattern for tens
movf Thousands,w
call Dpattern
movwf Thousands
return
;
; excerpt from Mosaic's "Strobe" subroutine
;
Chk_Dcount
bsf Tmp1,4 ; initialize the bitmask to 0001XXXX
clrc ; clear Carry
decfsz Offset,F ; digit number, 1..4 on entry
goto ShiftDigit ;
bsf Offset,3 ; make offset=8 for # of bits in Character pattern to send serially in Transmit routine called next.
movf INDF,W ; get digit value, 0..9
-> call Dpattern ; get LED segment data
movwf Tmp ; store in Tmp, clearing this GPR here can cause an empty display, useful for PWM Dimming.
call Transmit ; setup Shift register with character data pattern.
You must note that you are looking at an extract from a much larger application used as an example.Yes, there are some easy-to-reconcile differences. For example, the "DispLEDS" routine at the tail end of your binary-to-decimal routine performs four separate conversions of numeric data in the "Thousands", "Hundreds", "Tens", and "Units" variables into LED segment data;
Since this code doesn't have anything to do with binary-to-decimal conversion, it seems out-of-place tacked onto the end of the binary-to-decimal subroutine. As an alternative... is there a reason why you couldn't leave numeric data in the "Thousands", "Hundreds", "Tens", and "Units" variables and eliminate this section of code, replacing it with a single "call Dpattern" instruction in the "Strobe" subroutine where the segment data is actually used?Code:; ; excerpt from Mosaic's binary-to-decimal subroutine ; DispLEDS call Dpattern Movwf Units ; store 7 seg display pattern for units movf Tens,w call Dpattern movwf Tens ; store 7 seg display pattern for tens movf Hundreds,w call Dpattern movwf Hundreds ; store 7 seg display pattern for tens movf Thousands,w call Dpattern movwf Thousands return
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?