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.

How should I attempt this question

Status
Not open for further replies.

Spadez

New Member
Hi.

There is a question which comes up in the mock exam which involves doing maths. Attached is the exact question. From what I understand, doing any kind of addition, division etc on a PIC in assembly is extremely difficult, this is some example code ive found:



Does this question really have to be this difficult, or is there any easier way of doing it?

- James
 

Attachments

  • Untitled.png
    Untitled.png
    1.1 MB · Views: 323
Last edited:
This particular problem is quite straight forward : As (L) and (S) are 25% this a simple divide by 4 or (shift right 2), and (A) is 50) or divide by 2 (shift right 1). To do it properly you need two routines Multiply and divide.You must remember that with fixed point arithmetic you need to take care of the decimal place.

Just use the two routines needed by Peter Hemsley.

Cheers Ian
 
Thank you for the reply. So I understand this correctly, to divide a number by two, you shift the binary once to the right, so 0100 would become 0010. To divide by four it would be 0001.

If we had the following:

Logbook (L) = 25%
Software (S) = 25%
Arteface (A) = 50%

The test scores were:
L = 40
S = 50
A = 60

Then in binary we would have:
L = 0010 1000
S = 0011 0010
A = 0011 1100

In order to get the right percentages:
L = 0000 1010 (moved twice to the right)
S = 0000 1100 (moved twice to the right)
A = 0001 1110 (moved once to the right)

Then we need to add them up and divide by the number of entries, in this case, 3. Is this all right up to this point?

James
 
Yes! but if you look at S then you will notice that 50 * 25% = 12.5, but as this is integer math you have lost the 0.5, so your end calculation will be wrong. In this case you are going to need Multiplication!!

Look at it this way 50 * 25 = 12500 or (for precision ) 12.500, No division needed. You really need to know how precise they need the results.

Cheers Ian

Look at this post
https://www.electro-tech-online.com/threads/count-pulse-in-input-porta-in-15second.117705/

The division and multiplication routines are all there
 
Last edited:
To prevent loss of accuracy do multiplication first.

Answer = (L+S+(A*2))/4

So, shift A left once, add L and S then shift it right twice.

Unfortunately this requires a two byte location for the answer so a compromise might be,

Answer = (L/2+S/2+A)/2

In the example
Answer = (40/2+50/2+60)/2 = 52.5 rounded = 52%

in code,
Code:
	bcf	STATUS,C	;clear Carry
	rrf	L,W		;get L/2
	movwf	Temp		;save it
	bcf	STATUS,C
	rrf	S,W		;get S/2
	addwf	Temp,W		;add L/2
	addwf	A,W		;Add A
	movwf	Temp		;save it
	bcf	STATUS,C
	rrf	Temp,W		;divide by 2
;answer in W
But, don't be tempted to use this code as your answer. It's far too efficient to have been done by someone at your level and your lecturer just won't believe you. He will probably ask so many questions until he knows it's not you code.:D


Mike.
 
Good one Pommie! The only thing here is, If the tutor changes any percentages, the logic understanding all this... will be out the window.

Cheers Ian

I assume (hope) the percentages were chosen specifically with shifting in mind.

Mike.
 
Last edited:
I appreciate the help more than you can imagine, I was really having a hard time getting my head around this.

From the last three years, all percentages have been either 50%'s or 25%'s so I believe bit shifting is the required solution.

Ill work to understand this and be able to apply it to new exam questions.

Regards,

James
 
For the sake of keeping it simple, rather than efficient, I have modified the code:

For the most simple maths, it would be something like this:

(L/4)+(S/4)+(S/2) = Total

I believe I do not need to worry about the remainders. I have tried to write my own code based on the information provided.

// Divide L by 4
bcf STATUS,C
rrf L,W
movwf TempL2
rrf TempL2,W
movwf TempL4

// Divide S by 4
bcf STATUS,C
rrf S,W
movwf TempS2
rrf TempS2,W
movwf TempS4

//Divide A by 2
bcf STATUS,C
rrf A,W
movwf TempA2

// Add A/2 to L/4 then add total to S/4
addwf TempL4,W
addwf TempS4,W

I know not an ideal solution, but would it give me the answer I need?
 
Normally it would be something like:
Push L
Push 4
DIV
Push S
Push 4
DIV
PLUS
PUSH S
PUSH 4
DIV
PLUS

Everything is based on a stack. DIV divides the last two numbers on the stack and modifies the stack pointer. PLUS does the same.

Could be done by maco definitions or subroutines or manually. The stack model makes it very easy.
 
KISS im quite confused by some of the terminology in your post, like "Push", stack and stack pointer. I really think this is too advance for me, even if it may seem simple.

Can I get any feedback on the code I wrote?
 
Your code should work fine. The method of pushing variables and functions onto a stack is how some systems function but it is not suitable for a pic microcontroller.

Mike.
 
On the contrary, Mike!! I program in C (like most people) and the stack on the pic needs due consideration..

Spadez there are two types of stack Hardware and software. On the pic the hardware stack is used EVERY function call and EVERY loop. All you need to do is keep an eye on stack is to remeber how many "nested" routines there are example..

Code:
SomeFunction				// program counter on stack stack = 1
	do one thing
	call otherfunction
	do something else
return

otherFunction				// program counter on stack stack = 2
	do another thing
	call yetAnotherFunction
	finish
return

yetanotherFunction			// program counter on stack stack = 3
	do				        // program counter on stack stack = 4
		adjust someting
		call adjustFunction	// program counter on stack stack = 5
	while
return

adjustFunction
	make adjustment
return

On small pics there are ONLY 8 levels you can see how quickly they disappear, dosn't matter what language you're programming in!!
When an interrupt fires It takes two!! stack will equal 7

The software stack is the one you really don't need to know about just yet!!

Cheers Ian
 
Last edited:
I think you will find that all C compilers for the 16 series pic avoid the use of the stack as much as possible and they would definitely not use it for a do ... while loop.Whilst the stack may be used on PCs and the like for this kind of thing, it isn't on pics. You may program in C but you obviously haven't looked at the compiled code.

Mike.
 
I ditched the pic16f877a for that reason, I moved to the pic18f4520 with a 256 level hardware stack.. I suppose the type of compiler is ass an issue, first c compiler I used was SDCC open sourced (a bit buggy), I now use C18 and C24.

Anyway this is definitely a pit fall in SOME compilers.

Cheers Ian
 
I think you will find that all C compilers for the 16 series pic avoid the use of the stack as much as possible and they would definitely not use it for a do ... while loop.Whilst the stack may be used on PCs and the like for this kind of thing, it isn't on pics. You may program in C but you obviously haven't looked at the compiled code.

I would agree, C compilers on the PIC use a simulated software stack, not the PIC hardware one.
 
Sorry I stand corrected!! 31 level hardware stack, its the software stack that is 256 by default, I was under the impression that the software stack was for function arguments and local variables only!

Ian
 
An alternative solution would be to do this;

L = (L+2) / 4
S = (S+2) / 4
A = (A+1) / 2

answer = (L+S+A)

This has the advantage of only requiring 3 byte sized variables and can never overflow any var.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top