PIC byte to 3 digit ascii

Looking for some code to go from single byte to 3 digit ascii

for example

register has "124"

send "1" "2" "4" Ascii

Andrew

Reply to
Andrew Rich
Loading thread data ...

If you are "sending" the ASCII via the serial port then in C simply use the printf command which goes to STDOUT.

In HI-TECH PIC C this would be something like:

#include #include

void putch(unsigned char byte) { while(!TXIF) continue; TXREG = byte; }

main() { set up serial port UART etc printf("%i", registervariable); }

What *exactly* do you want to do?

Dave :)

Reply to
David L. Jones

Am I correct in assuming you want to convert (for example) the value D'124' (H'7C' or B'0111 1100') into the three ASCII characters "1" (which is D'49' or H'31' or B'0011 0001'), "2" (which is D'50' or H'32' or B'0011 0010'), and "4" (which is D'52' or H'34' or B'0011

0100') ???

Reply to
chinsta00

yes

Reply to
Andrew Rich

So what's your problem then? You don't like the answer Dave gave you?

Oh, you are trying to do it using PIC assembler?

There would be more to it then, and it depends, to some extent, on which PIC you are using.

Below is a fragment of code that may give you a starting point. The divide routine, that I thoughtlessly omitted is from Microchip Application Notes. Darn, it seems I left out the RAM fields as well.

movwf ACCbLO clrf ACCbHI call OUTDEC . . .

OUTDEC ; display number in ACCb as a 3 digit decimal number (max

999) ; - write it to current lcd ram addr bcf GFLAGS,GFNZSP ; to suppress leading zeroes clrf ACCaHI movlw .100 call DECDIG ; ascii 100s digit call LCDWD8 ; output one character

movf ACCcLO,W ; remainder movwf ACCbLO movlw .10 call DECDIG ; ascii 10s call LCDWD8

movf ACCcLO,W ; remainder addlw '0' ; ascii units call LCDWD8

DECDIG movwf ACCaLO ; set divisor call DIV ; b = b/100 c = remainder movf ACCbLO,W ; MSD btfsc GFLAGS,GFNZSP ; had more significant non-zero? goto decdig1 btfsc STATUS,Z movlw ' '-'0' ; blank leading zero btfss STATUS,Z bsf GFLAGS,GFNZSP ; to suppress leading zeroes decdig1 addlw '0' ; ascii return ; DECDIG

;******************************************************************* ; Double Precision Divide ( 16/16 -> 16 ) ; ; ( ACCb/ACCa -> ACCb with remainder in ACCc ) : 16 bit output ; with Quotiont in ACCb (ACCbHI,ACCbLO) and Remainder in ACCc (ACCcHI,ACCcLO). ; ; NOTE : Before calling this routine, the user should make sure that ; the Numerator(ACCb) is greater than Denominator(ACCa). If ; the case is not true, the user should scale either Numerator ; or Denominator or both such that Numerator is greater than ; the Denominator. ; ; DIV Andy Wood snipped-for-privacy@trap.ozemail.com.au

Reply to
Andy Wood

formatting link

--
Posted via a free Usenet account from http://www.teranews.com
Reply to
john jardine

Grouping the bits like split octal, that is, the byte is broken up as follows: group 1 consists of bits 7 & 6 group 2 consists of bits 5, 4 & 3 group 3 consists of bits 2, 1 & 0

377 would be the biggest number that need be displayed. To change a binary 0 through 7 to an ASCII 0 through 7 simply OR each group with 00110000

binary 00000000 + 00110000 becomes 0011 0000 which is an ascii 0 binary 00000001 + 00110000 becomes 0011 0001 which is an ascii 1 . . . binary 00000111 + 00110000 becomes 0011 0111 which is an ascii 7

----------------------------------------------------------------------------

------------------------

To convert 1111 1111 to ascii 00110010 00110101 00110101 will require more work.

Perhaps a series of compare instructions:

is byte < 00001010 if true write ascii 0 into output register 2 and 1. The byte is 0 through 9 jump to the 1's convert area.

is byte < 11001000 if false write ascii 2 into output register 2. The byte is between 200 and 255. Subtract 200 and jump to the 10's compare area.

is byte < 01100100 if false write ascii 1 into output register 2. The byte is between 100 and 199. Subtract 100

10's compare area:

is byte < 01011010 if false write an ascii 9 into output register 1. The byte is between 90 and 99. Subtract 90 and jump to the 1's convert area.

is byte < 01010000 if false write an ascii 8 into output register 1. The byte is between 80 and 89. Subtract 80 and jump to the 1's convert area.

is byte < 01000110 if false write an ascii 7 into output register 1. The byte is between 70 and 79. Subtract 70 and jump to the 1's convert area.

is byte < 00111100 if false write an ascii 6 into output register 1. The byte is between 60 and 69. Subtract 60 and jump to the 1's convert area.

is byte < 00110010 if false write an ascii 5 into output register 1. The byte is between 50 and 59. Subtract 50 and jump to the 1's convert area.

is byte < 00101000 if false write an ascii 4 into output register 1. The byte is between 40 and 49. Subtract 40 and jump to the 1's convert area.

is byte < 00011110 if false write an ascii 3 into output register 1. The byte is between 30 and 39. Subtract 30 and jump to the 1's convert area.

is byte < 00010100 if false write an ascii 2 into output register 1. The byte is between 20 and 29. Subtract 20 and jump to the 1's convert area.

is byte < 00001010 if false write an ascii 1 into output register 1. The byte is between 10 and 19. Subtract 10 and jump to the 1's convert area.

1's convert area:

byte OR 00110000 write into output register 0

Your decimal number is in output registers 2, 1 & 0 in that order. Your subtraction can be a decrement loop for the required number of iterations.

There you are in 12 compares.

Reply to
Lord Garth

Thanks to all that replied. I worked it out and is working.

I have one question tho, I have my code to do the maths, and then send to the serial port,

and then I have:-

goto barry

barry end;

but when i run it, it just keeps outputiing the serial code over and over.

instead of ending

why ?

Reply to
Andrew Rich

Is there an interrupt that is taking you back to the output routine?

Reply to
Lord Garth

What are you trying to "end"? Do you want the entire program to simply stop?, if so you need an endless loop, not an "end" statement. What assembler/compiler are you using?

If you just want to exit from a subroutine then it could be anything, and we can' tell you without seeing the full source code.

Dave :)

Reply to
David L. Jones

Sounds like the program is reaching the end of its code, then because it doesn't have an endless looping function after your program has finished, the program (or instruction) counter is looping back to the start. You probably should have something like this

Start: . . program instructions . . goto finish . possible more program instructions . . finish:

goto finish End

"End" doesn't mean that the clock in the controller will stop. In this case it tells the compiler to stop converting instructions to machine code. Since the clock in the microcontroller hasn't stopped (unless explicitly told to do so) the program counter will reach the end of the address space in the code and loop back to the start of the program.

Reply to
dmm

Here's a trick I discovered yonks ago. Instead of:

barry goto barry

try the following:

goto $

Saved me from thinking up of extra labels to use when doing something like:

bittest btfss register,0 goto bittest

which waits for bit 0 to be set (by interrupt routine, external pin, uC status flag, etc...) before continuing

I now replace that with:

btfss register,0 goto $ - 1

You could even try something as simple as the following if you want to stop the processor:

sleep

As to why your code keeps outputting and outputting, others have said that "end" is not actually a uC instruction. It tells MPASM or whatever assembler you're using where to stop assembling.

Your last intentional instruction is "goto barry", but the uC will keep running into your free program space, which is most likely filled with 0x3FFF for the 14-bit PICs (all bits high). This corresponds to the instruction "addlw 0xFF" so imagine the rest of your program memory filled with this code. By the time it reaches the end of program memory it will jump back to the start of the program again, and send your serial character again, etc....

Reply to
chinsta00

Thanks

END was not end, but end of code

I did and endless loop

Reply to
Andrew Rich

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.