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.
I agree it's pretty repetitive... I have taken a look at simplifying by using lookup tables... there are 66 megacolour and 384 seg colour entries... It could easily be made in a super loop and two inner loops... However, it's a task that would take me too long to convert.... I would sooner do this in C... It would be simpler but a smidge slower!!
 
I did not mean for you to redo Rainbow. Just look over the snippet below and tell me what needs to be corrected to be in a working format. Also what variables you would and would not declare in the beginning of the program. Thanks.

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
 
I need you comments about these issues
Code:
count1   equ   0x20
counta   equ   0x21
countx   equ   0x22
countb   equ   0x23

   org   0
   goto   Start   

Start
   nop
   nop       ; Init registers
   nop

   movlw    d'50'
d1
   movwf    count1     ; You need to tell me what
   movwf    counta     ; happens here!!!
d2
   call    sub1
   decfsz    counta
   goto    d2
   movlw   d'51'   
   subwf   count1,w   ; Set countx= 51-count1
   movlw    countx
   movwf    countb
d3
   call    sub2
   decfsz    countb
   goto    d3
   decfsz    count1
   goto    d1     ; Here is an issue!!!
         ; the contents of the w reg
         ; are to be place in count1 and counta
sub1
   nop
   nop
   return

sub2
   nop
   nop
   return
   
   end
 
I need you comments about these issues
[/code]
I made some changes. If you would correct the line indicated with an arrow. It needs something for it to skip over two lines.
Code:
count1   equ   0x20    ; allocating 4 memory spaces to 4 variables, I think we only need 3
counta   equ   0x21
; countx   equ   0x22
countb   equ   0x23

   org   0
   goto   Start

Start
   nop
   nop       ; Init registers
   nop
call Transit
nop
nop
nop
 
Transit
   movlw    d'50'
   movwf    count1     ; Initialize count1 "main loop", set to 50
d1                                ; moved this line down one
   movwf    counta     ; first time initialize  counta to 50 then it follows count1 as it decrements
d2
   call    sub1
   decfsz    counta      ; decrement counta from last value of count1 (initially 50) down to zero
   goto    d2                 ; do sub1 until counta gets to zero
   movlw   d'51'          ; move 51 to w
   subwf   count1,w   ; Set w= 51-count1 ,subtract count1 from 51 and place in w
;   movlw    countx    ; don't believe we need this variable here now
   movwf    countb    ; move content of w (ie: 51-count1) into countb
d3
   call    sub2          
   decfsz    countb     ; decrement countb from (51-count1) down to zero
   goto    d3                ; do sub2 until countb is zero
   decfsz    count1     ; we need to jump over two lines (ie: movlw, goto d1) if count1=zero <-------
   movlw   count1     ;read and move content of count1 to w to be placed in counta on top
   goto    d1                ; keep doing the main loop until count1= zero, each time the highest value for counta is the new count1
   nop
   nop
   return

sub1
   nop
   nop
   return
sub2
   nop
   nop
   return

   end
 
Last edited:
Code:
count1  equ  0x20  ; allocating 4 memory spaces to 4 variables, I think we only need 3
counta  equ  0x21
countb  equ  0x24

  org  0
  goto  Start

Start
  nop
  nop  ; Init registers
  nop

  movlw  d'50'
  movwf  count1  ; Initialize count1 "main loop", set to 50
d1  ; moved this line down one
  movwf  counta  ; first time initialize  counta to 50 then it follows count1 as it decrements
d2
  call  sub1
  decfsz  counta  ; decrement counta from 50 down to zero
  goto     d2   ; do sub1 until counta gets to zero
  movlw  d'51'  ; move 51 to w
  subwf  count1,w  ; Set w= 51-count1 ,subtract count1 from 51 and place in w
  movwf  countb  ; move content of w (ie: 51-count1) into countb
d3
  call  sub2   
  decfsz  countb  ; decrement countb from (51-count1) down to zero
  goto  d3  ; do sub2 until countb is zero
  decfsz  count1  ; we need to jump over two lines (ie: movlw, goto d1) if count1=zero <-------
  movlw  count1  ;read and move content of count1 to w to be placed in counta on top
  goto  d1  ; keep doing the main loop until count1= zero, each time the highest value for counta is the new count1
  nop
  nop
  return   ; This is a no no!! There is no retrun here unless the whole thing was called

sub1
  nop
  nop
  return
sub2
  nop
  nop
  return
  end

The return statement will cause a stack underflow...

You cannot jump two places with the decfsz command so you'll need to re-write
Code:
count1  equ  0x20  ; allocating 4 memory spaces to 4 variables, I think we only need 3
counta  equ  0x21
countb  equ  0x24

  org  0
  goto  Start

Start
  nop
  nop  ; Init registers
  nop

  movlw  d'50'
  movwf  count1  ; Initialize count1 "main loop", set to 50
d1  ; moved this line down one
  movwf  counta  ; first time initialize  counta to 50 then it follows count1 as it decrements
d2
  call  sub1
  decfsz  counta  ; decrement counta from 50 down to zero
  goto     d2   ; do sub1 until counta gets to zero
  movlw  d'51'  ; move 51 to w
  subwf  count1,w  ; Set w= 51-count1 ,subtract count1 from 51 and place in w
  movwf  countb  ; move content of w (ie: 51-count1) into countb
d3
  call  sub2   
  decfsz  countb  ; decrement countb from (51-count1) down to zero
  goto  d3  ; do sub2 until countb is zero
  decfsz  count1  ; we need to jump over two lines (ie: movlw, goto d1) if count1=zero <-------
  goto    loop
  goto    done
loop
  movlw  count1  ;read and move content of count1 to w to be placed in counta on top
  goto  d1  ; keep doing the main loop until count1= zero, each time the highest value for counta is the new count1
done
  nop
  nop
   
  return   ; This is a no no!! There is no retrun here unless the whole thing was called

sub1
  nop
  nop
  return
sub2
  nop
  nop
  return
  end
 
Code:
return   ; This is a no no!! There is no retrun here unless the whole thing was called

I corrected it before you commented the first time. My intention is to call this snippet from the main program. So I did name the start of the code "Transit" and left the "return" to redirect it back to main program. Thank you my friend, the code looks good.
Now there is one more step I need to take to account for counta=50 and countb=0 (do nothing). That is a simple fix.
That way I get counta=50 countb=0, then decrement counta starting with 49 while incrementing countb from 1. That means in the loops you just wrote I need to change 50 to 49, and change 51 to 50. You realize we just rewrote RGB morphing for one pixel only in a few lines without using internal PWM? For one channel RGB the sub1 and sub2 become extremely simplified. We don't even have to rotate as the morphing will take care of it. I will play with this when I have a bit more time and post results. Again thank you (and Nigel) for your valuable time you spent in assisting me. Cheers.
 
Meanwhile if you get tempted to play with the concept this is what I am thinking:
Assuming pin1 of PortB is connected to red, pin2 to green and pin3 to blue (for one pixel RGB common cathode)
Note: your color1 and color2 do not have to be red, green and blue only. It can be yellow=011, Aqua=110, Purple-101, or white=111
The morphing process covers everything in between the two colors you select with a smooth transition if you choose a large number of steps (255).

Main Program
Set color1=red ; create a variable and set it to 001
Set color2=green ; create a variable and set it to 010
call Transit
Set color1=green
Set color2=blue
call Transit
Set color1=blue
Set color2=red
call Transit
goto Main Program
end

Transit
........call sub1, call sub2,....
return

Sub1
place color1 in copyPortB
call Output
return

Sub2
Place color2 in copyPortB
call Output
return

Output
movlw copyPORTB ;a virtual port created to pass the values to PORTB for display
movwf PORTB
call delay ; may not be needed if modulated long enough in "Transit"
return
 
Hi , why don't you use macros?
For example:
Code:
Set color1=green
Set color2=blue
call Transit
Set color1=blue
Set color2=red
call Transit
can be written:
Code:
; create a macro
setcolor macro c1,c1
Set color1=c1
Set color2=c2
call Transit
 endm
; use it 
setcolor green, blue
setcolor blue,red
if you have enough program space you can replace even the sub calls with macro:
Code:
Transit
........call sub1, call sub2,....
return

Sub1
place color1 in copyPortB
call Output
return

Sub2
Place color2 in copyPortB
call Output
return
;define macro
subs macro color
Place color in copyPortB
call Output
endm
; use-it
Transit
   subs color1
   subs color2
   .....
return
In assembler you can even embed macros which I found very useful to create fast simple easy to debug and compact assembler code
For macro loops I found very useful Karl Lunt's PIC macro library:
 
Code:
   list        p=16F628A
   #include <p16F628A.inc>
 
__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _INTOSC_OSC_NOCLKOUT & _LVP_OFF
    errorlevel    -302        ; supress banksel warning messages during assembly
    errorlevel    -311         ; supress HIGH operator warning messages during assembly
   cblock    0x20
    copyPORTA                ;Declare variables used in the program
    copyPORTB
    LoopCount
    OutCount
    Trans1
    Trans2
    Color1
    Color2
    Speed
   endc
#define        bank0    bcf        STATUS,RP0
#define        bank1    bsf        STATUS,RP0
RESET_VECTOR    org        0x000
START
    movlw    b'00000111'         ;Set all ports as outputs
    movwf    CMCON               ;Disable comparators
    bank1
    clrf    TRISA
    clrf    TRISB
    bank0
;-----------------------------------------------------------------------------------------------
;         Main Program and Subroutines                          |   
;-----------------------------------------------------------------------------------------------
        movlw    d'10'                 ;Range Between 1 to 10
        movwf    Speed              ;Transition Speed 1=Fastest
        movlw    b'00001111'    ;Set Initial Start Color Black
        movwf    Color1
        movlw    b'11111111'
        movwf    copyPORTB   
;-----------------------------------------------------------------------------------------------
Sequence
        call        MorphColors
        goto    Sequence
;-----------------------------------------------------------------------------------------------
MorphColors
        call        Red
        call        Yellow
        call        Green
        call        Aqua
        call        Blue
        call        Magenta
        return
;More color transitions can be added here before "return"
;-----------------------------------------------------------------------------------------------
Red
        movlw    b'00011111'   
        call        PutColor
        return
;-----------------------------------------------------------------------------------------------
Yellow   
        movlw    b'01011111'   
        call        PutColor
        return
;-----------------------------------------------------------------------------------------------
Green
        movlw    b'01001111'   
        call        PutColor
        return
;-----------------------------------------------------------------------------------------------
Aqua
        movlw    b'11001111'   
        call        PutColor
        return
;-----------------------------------------------------------------------------------------------
Blue
        movlw    b'10001111'   
        call        PutColor
        return
;-----------------------------------------------------------------------------------------------
Magenta
        movlw    b'10011111'   
        call        PutColor   
        return
;-----------------------------------------------------------------------------------------------
White
        movlw    b'11011111'   
        call        PutColor   
        return
;-----------------------------------------------------------------------------------------------
Black
        movlw    b'00001111'   
        call        PutColor   
        return
;-----------------------------------------------------------------------------------------------
PutColor
        movwf    Color2
        call         Morph
        movfw    Color2
        movwf    Color1   
        return
;-----------------------------------------------------------------------------------------------
Morph                           
        movlw    d'254'
        movwf    LoopCount
M1
        movfw    LoopCount
        movwf    Trans1
        sublw    d'255'
        movwf    Trans2
M2
        movfw    Color2
        movwf    copyPORTA
        call        Output
        decfsz    Trans2,F
        goto    M2
M3
        movfw    Color1
        movwf    copyPORTA
        call        Output
        decfsz    Trans1,F                                   
        goto    M3
        decfsz    LoopCount
        goto    M1
        Return
;-----------------------------------------------------------------------------------------------
Output
        movfw    Speed               ;Transition Speed
        movwf    OutCount        ;Placing Delay Will Cause Flicker
Out1
        movfw    copyPORTA
        movwf    PORTA           
        movfw    copyPORTB
        movwf    PORTB
        decfsz    OutCount
        goto    Out1
        return
;-----------------------------------------------------------------------------------------------
  end
Here is a simplified yet user friendly version of color morphing. This code will morph between selected colors in a smooth transition. Color transitions can be added for added effects. When color black is used in between colors, the colors will fade in and fade out. When color white is used in between colors, the colors get washed out and then back to vivid colors. Choose a number between 1 and 10 for "Speed" to change the speed of the transitions (1=Fastest). Microcontroller used is a PIC16F628A and RGB LED's used are Common Anode. With RA4 and RA5 having a Pull-up Resistors. RA4=Red, RA6=Green, RA7=Blue. Optional RB0-RB7 and RA0-RA3 are used as Source Pins (provide 5v, 15mA per Channel). These pins can be ignored and all Anodes of LED's can be tied to +5v via current limiting resistors. This code could easily be adapted for smaller 8-pin PIC (such as PIC12F683) with only one set of RGB outputs.
 
Hi EV, If I look at post #7 you can use the following method:
Say count1 = C, counta = A, countb = B
loop:
dec C
A = C
B = 49 - C ; remember 49 = 50 - 1
goto loop
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top