help breaking down number inti 100s 10, 1s

this is probably easy to do but i cant think how at the moment.

how could i take an 8 bit number in a file and break it down into the 100s

10s and 1s and put the results into three other files so for example if i had 11001011 which is 203, how can i put 2 in the hundreds file, 0 in the tens and 3 in the units file.

would this be done best in a lookup table?

thanks in advance for any advice

Hayley

Reply to
Hayley
Loading thread data ...

Hmm, can you elaborate? What would this be used for (I smell homework :-), and how exactly are your files encoded - is this "11001011" a byte, or 8 bytes (e.g. 31 31 30 30 31 30 31 31)? How should the resulting files be encoded?

I don't think so, unless you have 768 bytes to spare and need to compute this really fast - since there apparently are files involved, the file system operations will use most of the time anyway.

I'd do it like this:

- Divide the value (assuming you already have it "verbatim" and not as "text") by ten. Keep the integer division result and the remainder.

- write the remainder into the current file (the first time you do this, it'll be the units file, then the tens, then the hundreds)

- for the next file, repeat the above with the division result as the new number.

(Another way to do it, if your micro does not have division, would be to subtract 100 until you end up with a value below 100, and count how often you can to do that. Repeat with 10 and 1 keeping the final result of the previous steps. The files are written to in the reverse order in this case.)

Regards, Gilles.

Reply to
Gilles Kohl

Surely not! Offhand I can't think of any schools in Cambridgeshire...

Reply to
Rich Webb

Hi thanks for the replies,

this is a home project for a telescope, im making a device that counts the number of times the focus knob is turned and then displayed on 3x 7 segment displays that was why i needed the binary counting number broken down into the 100s 10s and 1s so they can be sent to the correct display segment. the focus knob is geared down and motorised you have the turn it many times for just a slight adjustment so to keep track of different focal points i want to put a counter on it. i can put the number in the EEdata so it wont be lost during powerdown.

Reply to
Hayley

Hi Haley,

Interesting project and apologies for the "assignment assumption" :-)

the

focal

The "files" had me confused, where do they come in? I'd store the current focus setting in the EEdata as a single byte (in case that is the persistent "file" storage), converting to three digits for 7 segment display only as needed. (on the fly)

What programming language are you using? If C, something along the following lines would compute the values to output to the 7 segment decoders given an 8 bit unsigned number:

void DisplayValue(unsigned char number, unsigned char digits) { unsigned char currentSegment;

for(currentSegment = 0; currentSegment < digits; currentSegment++) { SetSegmentValue(currentSegment, number % 10); number /= 10; } }

You would pass 3 for "digits" in this case. (the maximum that makes sense with 8 bit integers. You could also make the currently hardcoded "10" a into a "base" parameter, and alternatively pass 16 to show values in hex - assuming your digit decoding mechanism/hardware supports it)

"void SetSegmentValue(unsigned char segment, unsigned char value)"

is a hardware-specific routine you must provide that sets a segment given by number (starting with 0 at the right) to a certain value (0-9 resp. 0-15)

Regards, Gilles.

P.S.: Caution: untested code ...

Reply to
Gilles Kohl

Hi,

I am using assembler with a pic 16f84, my idea was to have a register address with the focus count position in it. which is incremented or decremented accordingly. the bit i am stuck on is when i want to send the 3 digit number to the outside world to some 7 segment displays i need to convert the binary number into the 100s

10s and 1s.

I am ok with the input to the pic, counting, driving the display, its just the breaking down the number i am stuck with

thanks for your reply

Reply to
Hayley

I'm not familiar with that chip unfortunately, and its been some time I did assembly (6502, 6809, 8080, Z80, 68000, you can probably tell how long its been).

Had a quick glance at the datasheet - no division instruction, so method number 2 (subtract 100 as long as value is larger than 100, keep track of how many times that worked, this is digit 2, repeat same principle for 10 and 1 yielding digits 1 and 0 respectively) could work.

In pseudo-assembler:

reserve three registers or memory locations for the 100s, 10s and 1s values. An additional tempory location (maybe that weird "W" register that seems to play the role of a "wrong side of the equation accumulator" :-) is needed for computation.

"Code" for the first (leftmost) digit clear register for 100s digit loop100: subtract 100 from current value if result is negative jump to done100

increment register for the 100s digit goto loop100

done100: add 100 to current value (to recover the value before it got negative, may need to clear carry here before proceeding)

repeat code above for loop10/done10 and loop1/done1 accordingly.

You should end up with the 3 7 seg values in the three registers.

Hope this helps / makes sense / actually works, good luck! Regards, Gilles.

Reply to
Gilles Kohl

Hi Gilles

thats great,

thanks very much for your help, i will give that approach a go, it looks good to me.

Regards

Reply to
Hayley

You should have just said this to begin with. ;-) To use the following code, just put your binary value into binX, binU, binH, and binL. Then "call binary_to_bcd". The output will be stored as two BCD digits per byte. To turn the values into ASCII, you can simply "addlw 0x30" for each 4-bit BCD value. This code treats the 32-bit input as unsigned.

*******************************************

; ; Variables for binary to BCD conversion ;

count temp

; 32 bit binary value binX binU binH binL

; 10 digit BCD conversion output billions_and_hundredmillions tenmillions_and_millions hundredthousands_and_tenthousands thousands_and_hundreds tens_and_ones

; ; binary_to_bcd - convert 32bit unsigned binary value to 10 digits of BCD ;

binary_to_bcd

bcf STATUS, 0 ; clear the carry bit movlw .32 movwf count clrf billions_and_hundredmillions clrf tenmillions_and_millions clrf hundredthousands_and_tenthousands clrf thousands_and_hundreds clrf tens_and_ones loop32 rlf binL, F rlf binH, F rlf binU, F rlf binX, F rlf tens_and_ones, F rlf thousands_and_hundreds, F rlf hundredthousands_and_tenthousands, F rlf tenmillions_and_millions, F rlf billions_and_hundredmillions, F ; decfsz count, F goto adjDEC RETLW 0 ; adjDEC bcf STATUS, IRP

movlw tens_and_ones movwf FSR call adjBCD ; movlw thousands_and_hundreds movwf FSR call adjBCD ; movlw hundredthousands_and_tenthousands movwf FSR call adjBCD

movlw tenmillions_and_millions movwf FSR call adjBCD

movlw billions_and_hundredmillions movwf FSR call adjBCD ; goto loop32 ; adjBCD movlw 3 addwf INDF,W movwf temp btfsc temp,3 ; test if result > 7 movwf INDF movlw 0x30 addwf INDF,W movwf temp btfsc temp,7 ; test if result > 7 movwf INDF ; save as MSD RETLW 0

***********************************************************************
Reply to
Anthony Fremont

Hi Anthony,

thanks for the code, its given me someth>> Hi,

Reply to
Hayley

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.