Number converting

Status
Not open for further replies.

Robotix

New Member
Hi all, i have been trying to use a PIC16F84A to count pulses and display on two 7 segment displays with an overflow LED. I am stuck on how to convert a number incremented at an address into hundreds, tens & units. I know it would be easier to use three seperate memory locations but i would prefer to use just 1 to store my number.

Anyone have any ideas as how this can be done ?.
 
Division is the answer.
Count/100 is the hundreds digit
(Count%100)/10 is the tens digit
(count%100)%10 is the units digit

Where / is the quotient of integer division
and % is the remainder of integer division
 
Since you're driving 7-segment displays and only counting from 00 to 99 with overflow, you might want to consider using and incrementing a single "packed BCD" byte.

Code:
;******************************************************************
;*                                                                *
;*  Increment packed BCD number from 00 to 99 with overflow       *
;*                                                                *
;******************************************************************

IncNumber
        incf    Number,f        ; increment number                |B0
        movf    Number,W        ;                                 |B0
        addlw   h'06'           ; lo nybble < 10 ?                |B0
        bndc    IncDone         ; yes, branch, else               |B0
        movwf   Number          ; update Number                   |B0
        xorlw   d'100'          ; overflow from 99 to 100 ?       |B0
        bnz     IncDone         ; no, branch, else                |B0
        movwf   Number          ; reset Number to 00 and          |B0
        bsf     Flags,Overflow  ; indicate overflow               |B0
IncDone
It's also relatively easy to translate each BCD nybble into 7-segment data to drive your displays;

Code:
Display
        swapf   Number,W        ; get left nybble (10's) in W     |B0
        call    SegData         ; get 7-segment display data      |B0
; set 1st display
        movf    Number,W        ; get right nybble (1's) in W     |B0
        call    SegData         ; get 7-segment display data      |B0
; set 2nd display
        return                  ;                                 |B0

SegData
        andlw   b'00001111'     ;                                 |B0
        movwf   TEMP            ;                                 |B0
        movlw   high SegTable   ;                                 |B0
        movwf   PCLATH          ;                                 |B0
        movlw   low  SegTable   ;                                 |B0
        addwf   TEMP,W          ;                                 |B0
        skpnc                   ;                                 |B0
        incf    PCLATH,f        ;                                 |B0
        movwf   PCL             ;                                 |B0

SegTable
        dt      b'00111111'     ; "0"   -|F|E|D|C|B|A
        dt      b'00000110'     ; "1"   -|-|-|-|C|B|-
        dt      b'01011011'     ; "2"   G|-|E|D|-|B|A
        dt      b'01001111'     ; "3"   G|-|-|D|C|B|A
        dt      b'01100110'     ; "4"   G|F|-|-|C|B|-
        dt      b'01101101'     ; "5"   G|F|-|D|C|-|A
        dt      b'01111101'     ; "6"   G|F|E|D|C|-|A
        dt      b'00000111'     ; "7"   -|-|-|-|C|B|A
        dt      b'01111111'     ; "8"   G|F|E|D|C|B|A
        dt      b'01101111'     ; "9"   G|F|-|D|C|B|A
Good luck with your project. Regards, Mike
 
Last edited:
Papabravo said:
Division is the answer.
Count/100 is the hundreds digit
(Count%100)/10 is the tens digit
(count%100)%10 is the units digit

Where / is the quotient of integer division
and % is the remainder of integer division

Hm i kind of worked that one out but will it be easy to do that for a pic16f84a ?

thanks for the help tho.
 
Hi mike-k8lh, many many thanks for the help i will try this out and see how it works, seems quite easy when i look at it, bit puzzled on a couple of lines of your code tho. skpnc & bndc - are they usable on the PIC16F84A ?
 
Robotix said:
Hi mike-k8lh, many many thanks for the help i will try this out and see how it works, seems quite easy when i look at it, bit puzzled on a couple of lines of your code tho. skpnc & bndc - are they usable on the PIC16F84A ?

Check your MPASM helpfile, they are assembler 'macro's that are built-in to MPASM - those words are replaced by PIC code when it's assembled. Personally I tend not to use them, I'd sooner just insert the code as it is - but it's a personal thing!.
 
Nigel Goodwin said:
Check your MPASM helpfile, they are assembler 'macro's that are built-in to MPASM - those words are replaced by PIC code when it's assembled. Personally I tend not to use them, I'd sooner just insert the code as it is - but it's a personal thing!.


Hi Nigel, many thanks for the help. Looks like i have a bit to learn still.
 
Robotix said:
Hi mike-k8lh, many many thanks for the help i will try this out and see how it works, seems quite easy when i look at it, bit puzzled on a couple of lines of your code tho. skpnc & bndc - are they usable on the PIC16F84A ?
Sorry for the confusion.

I use several of the pseudo instructions in my PIC16 apps' because they seem a little more intuitive (to me). For example, I use the skpz (skip zero) and skpnz (skip not zero) pseudo instructions instead of the btfss STATUS,Z and btfsc STATUS,Z instructions.

Also, several of the pseudo instructions for PIC16 (14-bit instruction core) correspond to "real" instructions on the PIC18 (16-bit instruction core) processors (bz, bnz, bc, bnc, to name just a few) so code seems more intuitive and transportable as I move between PIC16 and PIC18 projects. The PIC16 'branch' pseudo instructions actually translate to two instructions, a btfss or btfsc instruction followed by a goto instruction, while the PIC18 'branch' instructions are single word instructions.

As Nigel says, it's a personal preference.

Good luck with your project. Regards, Mike
 
Last edited:
Solved at last

Thanks for all the help i have received, i have now managed to solve the issue i had by :-

Code:
GETHNDS		movwf	t1
                         clrf         w2
gethnds_loop	incf	0x10 
		movlw	.100
		incf	w2,f
		subwf	t1,f
		btfsc	STATUS,0
		goto 	gethnds_loop
		movlw	.100
		addwf	t1,f
		decf	0x10
		movfw	0x0c
GETONES		movwf	w2		 
		movlw	.10
deltens_loop	incf	0x11
		subwf	w2,f		 
		btfsc	STATUS,0
		goto 	deltens_loop
		addwf	w2,w
		movwf   0x12
		decf      0x11 
                          return

I have almost solved all my problems in my project with the help of all who have helped me from this forum.
 
Hola Mike,

As far as I understand, Microchip is somehow discouraging the use of those built in macros. While very useful, thanks God, I never used them. (Mine instead). Perhpas because of that, I have to stop, when running across them, and think what their meaning is...

Different styles of work, isn't it?
 

With HTPICC, you can do like this:

void convert()
{
char j;
unsigned tg;

tg=number;
for(j=0;j<=3;j++)
{
a[j]=tg%10;
tg=tg-a[j];
tg=tg/10;
}
}

number: is a number you want to convert, it a variable or const.
array a storage that number.

You can display it on LED 7 SEG, or convert it to ASCII code to display on LCD.
 
Last edited:
Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…