Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

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?
 
Robotix said:
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 ?.

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.

Latest threads

New Articles From Microcontroller Tips

Back
Top