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.

Need Help with Nested Do Loops using varaible in PIC Assembly

Status
Not open for further replies.

EvilGenius

Member
Hi Everyone
I am writing a PIC (16F628A) program and like to shrink the code by using nested loops with use of variables (number of iterations).
I am not sure if it is possible to do this in assembly. Any heads up is very much appreciated. Regards, Rom
Here is what I am trying to accomplish in BASIC language:

For I = 1 to 50 step 1
For J= 1 to I step 1
.
.
For K= 51-I to 1 step 1
.
.
Next K
Next J
Next I
 
Your only issue is nested loops require the hardware stack... This is only eight level deep on pic16fxxx devices...

Every call you make takes a stack position ( as you need to get back )

so you will have

main routine
...
...
...
call loop1
returned
...
...
end main​
loop1
...
call loop2
...
end loop1​
loop2
...
stuff to do
....
end loop2​

etc.....
As long as you can keep up with it you'll be okay.... If you use interrups just remember that the interrupts take up two stack positions, so if one is called whilst you are nested somewhere... End of program!!
 
Thanks for your response Ian. My question is how you setup the loop itself with a varying variable embedded in it. (I, J, K)
I know how to start the loop with a number and then decrement it with a skip zero goto. My question is how do you setup the loop with I, J, and K in them as variables.
This is to elaborate more as what I am trying to do:
Main loop, lets say, "I" counts from 1 to 50 (or 50 to 1 whichever is easiest). Now I want two other loops inside this loop. One to count from 50 down to 1 and the other counts from 1 to 50 at the same time. So this is how the program runs: count to 50 main loop, inside loop1 is 50 and loop2 is at 1. While loop1 decrements count loop down to 1, loop2 increments up to 50.
Simple example for clarification: I have two LEDs, one red, one green. I want red one to glow at full brightness while green at its lowest brightness. As I decrease brightness of red, I increase brightness of green until green is in full brightness. (Pseudo PWM toggle on two channels)
 
If you can kindly translate exactly what I have written in BASIC into PIC assembly, I think I can take it from there. I am looking for how to setup the syntax.
 
Check my tutorials, there are various examples of nested loops in assembler - in particular the various software delay routines.

Contrary to what Ian suggested, this doesn't cause any stack problems, unless you're calling multiple sub-routines (which isn't specified in the question).

As for 'can you do it in assembler' - of course you can :D - PIC's (like all processors) only run machine code (which is directly generated from the assembler), so anything that can be done in BASIC/C or anything else can be done in assembler, because it already is.
 
As for 'can you do it in assembler' - of course you can :D - PIC's (like all processors) only run machine code (which is directly generated from the assembler), so anything that can be done in BASIC/C or anything else can be done in assembler, because it already is.
True!! I was over thinking things.... I was assuming sub routines... you could of course use nested loops...
 
Hello Nigel
I looked at your delay subroutine in one of your tutorials. Below please find snippet:
Delay movlw d'250' ;delay 250 ms (4 MHz clock)
movwf count1
d1 call ChkKeys ;check the keys
movlw 0xC7 ;delay 1mS
movwf counta
movlw 0x01
movwf countb
Delay_0
decfsz counta, f
goto $+2
decfsz countb, f
goto Delay_0
decfsz count1 ,f
goto d1
I believe I understand the concept behind it, however that is not what I am looking for. Your variables count1, counta, and countb resemble the variables I, J, K I had in mind.
However your routine covers all permutations of count1, a,b in the 3 nested loops. That is not what I had in mind. I only need selected ones.
I need to initialize count1 as you did with d'50' and start that loop. Now counta and counb are dependent of count1. If we start count1 at 50 then counta needs to start at 50 and decrement, while at the same time countb is incrementing from 1 to 50 simultaneously. That means the permutations will be count1=50 (main loop), counta=50, countb=1. Then counta=49, countb=2, and so on until counta=1 and countb=50 simultaneously. Do you have any other examples or suggestions? Regards, Rom
 
I know the format is probably incorrect but if I was to modify your code I would do this:
movlw d'50'
d1
movwf count1
movwf counta
d2
call dosomething1
decfsz counta
goto d2
set countx= 51-count1
movlw countx
movwf countb
d3
call dosomething2
decfsz countb
goto d3
decfsz count1
goto d1
 
Last edited:
What do you gents think of the code I wrote above. What would you change to make it work?
Thanks for your help in advance. I appreciate you.
 
Write it in pseudo code ( basic if you like ) and I'll see if I can put it in ASM for you..

There will only be two nested calls in the above code.... so the stack should survive..

I need the third (count1 : outer count) for POV. Also need to keep counta+countb constant at 50. I am rapidly toggling between dosomething1 and dosomething2 and I need to repeat these numerous times to keep from flickering.
 
What Nigel is saying... Could the "call" statements be replaced with the actual routines?
I don't believe so. The call routines will do something rather complex and each will take a good bit of code lines. That is why I chose 50 for my POV as I will be modulating inside those "calls" as well (at least 12 times). In a sense I am modulating inside modulation at 50x12 times a second. If we name the code above "Transit" then my program will setup a group of variables first then calls "Transit" routine. Inside "Transit" the calls will use the variables setup initially and do something with them. Then after "Transit" is done, it goes back to the beginning of the program and selects another set of variables and repeats the process.
 
We could really do with seeing your code idea's, there are ways to do anything in assembler that can be done in high level languages...

My initial thoughts were correct! You will be nesting subroutines.... There are ways round it though..
 
We could really do with seeing your code idea's, there are ways to do anything in assembler that can be done in high level languages...

My initial thoughts were correct! You will be nesting subroutines.... There are ways round it though..
Ian I would be glad to share the code once I have it setup. I am still in the conceptual stage putting pieces together. That said I have written similar programs before and called on similar subroutines to do exactly what I am describing. I had no issues with it and It all worked well. Once I get the program to a stage that is working, or limping then you guys can help me shrink it down and do it more efficiently.
For now I need to know if I have the syntax of the snippet above correct and if the logic is matching what I stated in BASIC. Cheers.
 
Here is a assembly program I worked on last year. It uses 3 primary colors to generate 12 colors across 12 RGB LEDs by fading transitions and then all colors rotate. If you ask me to describe it in details then I have to write a book regarding its full operation.
 

Attachments

  • A12-Rainbow-3mux12-19.asm
    32.1 KB · Views: 185
I have looked at your program.. It is only using six levels of the stack so I'll hush up about that!!

If you have written this, why do you need my help??? Surely this code is almost the same as you need now!


 
I have looked at your program.. It is only using six levels of the stack so I'll hush up about that!!

If you have written this, why do you need my help??? Surely this code is almost the same as you need now!
Almost not quite. I appreciate it if you can look at the code above and kindly rewrite it to be in the right syntax and functional format. Last time I used a "Set" and "EQU" commands I had major issues and I could not cure them. If I can get this part right I can actually shrink code for "Rainbow" down tremendously and also write the new program in much slicker fashion. All the "Section" calls will reduce to a few lines.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top