ppater
Super Member
- Total Posts : 1002
- Reward points : 0
- Joined: 2006/08/26 10:33:06
- Location: Ivry, France
- Status: offline
Tip: Divide WREG by 10, PIC18
Here's a wonderful tip that I must share: Given WREG = number to divide by 10, MULLW .51 MOVLW .50 ADDWF PRODH, W RRNCF WREG, W It gives (number / 10) in WREG!!!
Any comment?
|
DarioG
Allmächtig.
- Total Posts : 54081
- Reward points : 0
- Joined: 2006/02/25 08:58:22
- Location: Oesterreich
- Status: offline
RE: Tip: Divide WREG by 10, PIC18
2009/12/18 10:59:51
(permalink)
Hmmm, it does not work with 69... or am I missing something? 69*51=3519 PRODH=13 +50=63 /2=31
|
ppater
Super Member
- Total Posts : 1002
- Reward points : 0
- Joined: 2006/08/26 10:33:06
- Location: Ivry, France
- Status: offline
RE: Tip: Divide WREG by 10, PIC18
2009/12/18 11:09:59
(permalink)
ORIGINAL: DarioG Hmmm, it does not work with 69... or am I missing something?  69*51=3519 PRODH=13 +50=63 /2=31 [&:] My fault, I have not tested... 50 must be added to the 16 bits result: Given WREG = number to divide by 10, MULLW .51 MOVLW .50 ADDWF PRODL, F MOVLW .0 ADDWFC PRODH, W RRNCF WREG, W
post edited by ppater - 2009/12/18 11:12:42
|
BitWise
Super Member
- Total Posts : 1238
- Reward points : 0
- Joined: 2004/11/09 13:24:20
- Location: UK
- Status: offline
RE: Tip: Divide WREG by 10, PIC18
2009/12/18 12:06:40
(permalink)
How about... addlw .1 mullw .51 bcf STATUS,C rrcf PRODH,W
Provided WREG is not 255 on entry
post edited by BitWise - 2009/12/18 12:07:52
Throughout your life advance daily, becoming more skillful than yesterday, more skillful than today. This is never-ending. Yamamoto Tsunetomo (1659-1719)
|
ppater
Super Member
- Total Posts : 1002
- Reward points : 0
- Joined: 2006/08/26 10:33:06
- Location: Ivry, France
- Status: offline
RE: Tip: Divide WREG by 10, PIC18
2009/12/18 12:08:33
(permalink)
Given WREG = number to divide by 10, ; First "divide by 5" MULLW .51 MOVLW .50 ADDWF PRODL, F MOVLW .0 ADDWFC PRODH, W ; Now divide by 2 RRNCF WREG, W ... It's also easy to compute the remainder (modulo): ; save number MOVWF Temp ; First "divide by 5" MULLW .51 MOVLW .50 ADDWF PRODL, F MOVLW .0 ADDWFC PRODH, W ; Now divide by 2 RRNCF WREG, W ; Now multiply by 10 MULLW .10 ; Now get remainder MOVF PRODL, W SUBWF Temp, W
|
Stefan Uhlemayr
Super Member
- Total Posts : 4292
- Reward points : 0
- Joined: 2005/05/12 12:25:46
- Location: Germany
- Status: offline
RE: Tip: Divide WREG by 10, PIC18
2009/12/18 14:28:02
(permalink)
ORIGINAL: BitWise How about... addlw .1 mullw .51 bcf STATUS,C rrcf PRODH,W
Provided WREG is not 255 on entry Thanks for this neat DIV10-routine, done in 4 instructions!  And thanks for Philippe for having the initial-idea.  Of course, this will be added to the neat asm-tricks in the software-gallery! Thanks, Stefan
|
ppater
Super Member
- Total Posts : 1002
- Reward points : 0
- Joined: 2006/08/26 10:33:06
- Location: Ivry, France
- Status: offline
RE: Tip: Divide WREG by 10, PIC18
2009/12/18 14:55:45
(permalink)
ORIGINAL: BitWise How about... addlw .1 mullw .51 bcf STATUS,C rrcf PRODH,W
Provided WREG is not 255 on entry How about... addlw .1 mullw .51 rrcf PRODH,W  Provided WREG is not 255 on entry, there is no carry ...
|
Stefan Uhlemayr
Super Member
- Total Posts : 4292
- Reward points : 0
- Joined: 2005/05/12 12:25:46
- Location: Germany
- Status: offline
RE: Tip: Divide WREG by 10, PIC18
2009/12/18 15:06:11
(permalink)
ORIGINAL: ppater How about... addlw .1 mullw .51 rrcf PRODH,W
Provided WREG is not 255 on entry, there is no carry ... Very nice.  And how about: addlw .1 btfsc STATUS,C addlw .255 mullw .51 rrcf PRODH,W
5 instructions then, but nothing provided... EDIT: Corrected mistake, thanks Philippe!
post edited by Stefan Uhlemayr - 2009/12/18 15:26:15
|
ppater
Super Member
- Total Posts : 1002
- Reward points : 0
- Joined: 2006/08/26 10:33:06
- Location: Ivry, France
- Status: offline
RE: Tip: Divide WREG by 10, PIC18
2009/12/18 15:18:50
(permalink)
|
ppater
Super Member
- Total Posts : 1002
- Reward points : 0
- Joined: 2006/08/26 10:33:06
- Location: Ivry, France
- Status: offline
RE: Tip: Divide WREG by 10, PIC18
2009/12/18 15:22:12
(permalink)
|
Stefan Uhlemayr
Super Member
- Total Posts : 4292
- Reward points : 0
- Joined: 2005/05/12 12:25:46
- Location: Germany
- Status: offline
RE: Tip: Divide WREG by 10, PIC18
2009/12/18 15:25:31
(permalink)
ORIGINAL: ppater So: addlw .1 btfsc STATUS,C addlw .255 mullw .51 rrcf PRODH,W
Yes, this way works. Thanks for correction (I shouldn't write code without simulator [8|]). Greetings, Stefan
|
ppater
Super Member
- Total Posts : 1002
- Reward points : 0
- Joined: 2006/08/26 10:33:06
- Location: Ivry, France
- Status: offline
RE: Tip: Divide WREG by 10, PIC18
2009/12/18 15:49:51
(permalink)
ORIGINAL: Stefan Uhlemayr Yes, this way works. Thanks for correction (I shouldn't write code without simulator [8|]). Me too  ... Great piece of collaborative work!
post edited by ppater - 2009/12/18 15:51:47
|
barbiani
Super Member
- Total Posts : 246
- Reward points : 0
- Status: offline
RE: Tip: Divide WREG by 10, PIC18
2009/12/18 17:18:38
(permalink)
How about divide by 100 and modulo? In a new thread of course
|
DarioG
Allmächtig.
- Total Posts : 54081
- Reward points : 0
- Joined: 2006/02/25 08:58:22
- Location: Oesterreich
- Status: offline
RE: Tip: Divide WREG by 10, PIC18
2009/12/18 17:37:16
(permalink)
ok  been away for a while and now we get it all working!! good job
|
ppater
Super Member
- Total Posts : 1002
- Reward points : 0
- Joined: 2006/08/26 10:33:06
- Location: Ivry, France
- Status: offline
RE: Tip: Divide WREG by 10, PIC18
2009/12/19 02:29:44
(permalink)
ORIGINAL: future56k How about divide by 100 and modulo? In a new thread of course  It's straight forward: ; First "divide by 5" ADDLW .1 BTFSC STATUS, C ADDLW .255 MULLW .51 ; Now "divide by 10" RRCF PRODH, W ; Now "divide by 50" MULLW .52 ; Now "divide by 100" BCF STATUS, C Edited: here clearing status is mandatory... RRCF PRODH, W ... For remainder (modulo 100): If the divide was just made before, the same method as modulo 10 can be used, else I guess that a classic sub/add sequence is the most effective : MOVWF Temp MOVLW .200 SUBWF Temp, F BTFSS STATUS, C ADDWF Temp, F MOVLW .100 SUBWF Temp, F BTFSS STATUS, C ADDWF Temp, F MOVF Temp, W
post edited by ppater - 2009/12/19 02:41:42
|
ppater
Super Member
- Total Posts : 1002
- Reward points : 0
- Joined: 2006/08/26 10:33:06
- Location: Ivry, France
- Status: offline
RE: Tip: Divide WREG by 10, PIC18
2009/12/19 05:01:59
(permalink)
 And now... A full 8 bits binary to 3 digits routine based on previous code: (provided bank selection is good) ADDLW .1 ; adjust for 255? BTFSS STATUS, C ADDLW .255 ; yes, set to 255 MULLW .51 ; "div by 5" RRCF PRODH, W ; div by 2 MOVWF Tens ; save tens and ones MULLW .52 ; "div by 5" BCF STATUS, C RRCF PRODH, W ; div by 2 MOVWF Hunds ; save hunds MOVF Tens, W ; get back tens and ones MOVWF Ones ; save it in ones MULLW .51 ; "div by 5" RRCF PRODH, W ; div by 2 MOVWF Tens ; save tens MULLW .10 ; restore power of 10 MOVF PRODL, W ; get result SUBWF Ones, F ; adjust ones
post edited by ppater - 2009/12/19 07:32:51
|
DarioG
Allmächtig.
- Total Posts : 54081
- Reward points : 0
- Joined: 2006/02/25 08:58:22
- Location: Oesterreich
- Status: offline
RE: Tip: Divide WREG by 10, PIC18
2009/12/19 06:28:00
(permalink)
nice
|
K8LH
Super Member
- Total Posts : 1887
- Reward points : 0
- Joined: 2004/03/26 05:12:34
- Location: Michigan, USA
- Status: offline
RE: Tip: Divide WREG by 10, PIC18
2009/12/19 06:36:08
(permalink)
Here's a 12 word "loop" version I came up with for a very resource limited 10F200 project which should work on 12/14/16 bit core devices (using lots more instruction cycles); Regards, Mike ;****************************************************************** ; * ; 8 bit to 3 digit half-packed BCD, Mike McLaren, K8LH (Jan-09) * ; * ; input: WREG, 0x00..0xFF, 0..255 * ; output: tens, 0x00..0x25, packed bcd * ; ones, 0x00..0x09 * ; * ; 12 words, 2 variables, 12/14/16 bit core devices * ; * Bin2Bcd clrf tens ; decf tens,F ; preset 'tens' to -1 div10 movwf ones ; incf tens,F ; bump 'tens', 0x00..0x25 movlw 6 ; using "packed bcd" format addwf tens,W ; bcd "digit carry"? skpndc ; no, skip, else movwf tens ; fix 'tens' movlw 10 ; ones = ones - 10 subwf ones,W ; borrow? bc div10 ; no, branch, else And here's the companion routine for sending the 3-digit decimal number out your PutLCD or Put232 routine with leading zero suppression; ; ; print number right justified and suppress leading zeros ; PutDec movlw " " ; seed leading zero 'mask' movwf mask ; mask = 0x20 = " " (space char) swapf tens,W ; get hundreds, 0..2 call PutDigit ; print " " or "1".."2" movf tens,W ; get tens, 0..9 call PutDigit ; print " " or "0".."9" movf ones,W ; get ones, 0..9 goto PutNumber ; always print "0".."9" PutDigit andlw 0x0F ; skpz ; zero? yes, skip, else PutNumber bsf mask,4 ; mask = 0x30 = "0" iorwf mask,W ; wreg = " " or "0".."9" goto Put232 ; Put232 or PutLCD
|
1and0
Access is Denied
- Total Posts : 12108
- Reward points : 0
- Joined: 2007/05/06 12:03:20
- Location: Harry's Gray Matter
- Status: offline
RE: Tip: Divide WREG by 10, PIC18
2009/12/19 07:39:42
(permalink)
ORIGINAL: Stefan Uhlemayr ORIGINAL: ppater So: addlw .1 btfsc STATUS,C addlw .255 mullw .51 rrcf PRODH,W
Yes, this way works. Thanks for correction (I shouldn't write code without simulator [8|]). How about... mullw .205 ;W = W*205/2048 rlncf PRODH,w swapf WREG andlw 0x1F
Tested with WREG = 0 to 255 in the simulator.
post edited by 1and0 - 2009/12/19 07:55:39
|
Stefan Uhlemayr
Super Member
- Total Posts : 4292
- Reward points : 0
- Joined: 2005/05/12 12:25:46
- Location: Germany
- Status: offline
RE: Tip: Divide WREG by 10, PIC18
2009/12/19 10:29:21
(permalink)
ORIGINAL: 1and0 How about... mullw .205 ;W = W*205/2048 rlncf PRODH,w swapf WREG andlw 0x1F Tested with WREG = 0 to 255 in the simulator. 5 stars for this!  I think, now we've got the perfect implementation of W DIV 10. ORIGINAL: ppater Great piece of collaborative work!  I can only second this!
|