Page 1 of 1 [ 9 posts ] 

kc8ufv
Veteran
Veteran

User avatar

Joined: 27 Jul 2008
Age: 43
Gender: Female
Posts: 762
Location: Toledo, OH

15 Nov 2009, 7:52 pm

I am working on a project to control some lights, and seem to be having an issue with my nested subroutines. It seems like when I'm in one of the emergency light patterns, I call the appropriate delay subroutine, and the return opcode throws everything back to the main loop, bypassing the rest of the loop that the routine was called for. I know I haven't put in the code for pattern 1 yet, but that will be going in after I figure out this problem. (that one is going to be a lot more complex pattern). For my testing, I just have LEDs wired on port A pins 0-5, and buttons (and pulldown resistors) attached to port B pins 0-3. Is anyone here familiar with a solution to this problem? I only need to nest 2 layers deep, though 3 would be nice when I code the other light pattern (I plan on flashing the left set twice, then the right set twice, then all lights twice, like pattern 3 does once.)

Code:
init   bsf 03h,5         ; enter config register
       movlw b'11111111'   ; set port B to be inputs
       movwf 86h
       movlw 00h   ; set port A to be outputs
       movwf 85h   
       bcf 03h,5         ; leave config register

      movlw 00h
      movwf 05h
MAIN    btfsc 06h,2   ; Start main loop, and check for light pattern 1/3 bit
      call PTRN1   ; Jump to patern 1/3 loop
      btfsc 06h,3   ; Check for light pattern 2
      call PTRN2   ; Jump to pattern 2 loop
      movlw 00h   ; Turn off all lights
      movwf 05h
      btfsc 06h,0 ; check if left signal should be on
       bsf 05h,0   ; turn on left signal if it should be on
      btfsc 06h,1   ; check if right signal should be on 
      bsf 05h,1   ; turn on right signal if it should be on
      goto MAIN   ; restart main loop

PTRN3   movlw 05h
      movwf 0Bh
      movlw b'11111111'   ; LIGHT PATTERN 3
      movwf 05h
      call SHRTDLY
start3   decfsz 0Dh
      goto fin3
      xorwf 05h
      call SHRTDLY
      goto start3
fin3   call LNGDLY
      return   ; Return to main loop

PTRN1

lgt1   btfsc 06h,3      ;   LIGHT PATERN 1, determine if should be PATERN 3
      goto PTRN3      ;   Goto Patern 3 if patern bit 2 is set
      
      return      ;   return to main loop.

PTRN2   

lgt2   btfsc 06h,2      ;    Check if should be Pattern 3
      goto PTRN3
      movlw b'10101010'   ; Start LIGHT PATTERN 2
      movwf 05h
      call LNGDLY
      movlw b'11111111'
      movwf 05h
      call LNGDLY
      return    ; Return to main loop

SHRTDLY   movlw 7Fh
      movwf 0Ah
SD2      decfsz 08h,1   ; Short delay for strobe effect
      goto SD2
      decfsz 09h,1
      goto SD2
      decfsz 0Ah,1
      goto SD2
   return            ; return to calling loop

LNGDLY    decfsz 08h,1   ; Long delay for break in flash pattern
      goto LNGDLY
      decfsz 09h,1
      goto LNGDLY
      decfsz 0Ah,1
      goto LNGDLY
      decfsz 0Bh,1
      goto LNGDLY
   return            ; Return to calling loop
end



CTBill
Veteran
Veteran

User avatar

Joined: 17 Oct 2008
Age: 60
Gender: Male
Posts: 514
Location: Connecticut, USA

15 Nov 2009, 9:26 pm

Been a while since I last worked with the PIC16, but I seem to recall that the ICE debugger environment consumes one or two stack levels (and that you are issuing CALL instructions in your routine), as well as several fixed RAM locations.

Does your code work okay if not built with debug option?

Are you managing banked RAM correctly?



kc8ufv
Veteran
Veteran

User avatar

Joined: 27 Jul 2008
Age: 43
Gender: Female
Posts: 762
Location: Toledo, OH

15 Nov 2009, 9:41 pm

I'm not using a debugger, I am making these determinations based on the behavior of it in the real pic.

I am not that familiar with banked ram, so I'm not sure if I am using it correctly. As far as I can tell, without calling the delay loops, it is functioning as expected. Since writing my original post, I attempted changing the calls from the main loops to the flash patterns to goto statements, and returning to the main loop with another goto, and it still is acting like the program is just returning to the main loop after completing the delay loops.



lau
Veteran
Veteran

User avatar

Joined: 17 Jun 2006
Age: 76
Gender: Male
Posts: 9,798
Location: Somerset UK

15 Nov 2009, 9:42 pm

Erm. You should be using general purpose registers for your counters.

Using PCLATH (0Ah) as a counter is about as unwise as you can get! (The three ms bits of PCLATH are undefined)

What happens when you try to use 08h and 09h as counters is entirely undefined.

What happen when you use INTCON (0Bh) is also a bit wild.

In the end, you may find it MUCH more useful to use the built-in timer. Program loop counting is a huge waste of the chip's capabilities.


_________________
"Striking up conversations with strangers is an autistic person's version of extreme sports." Kamran Nazeer


CTBill
Veteran
Veteran

User avatar

Joined: 17 Oct 2008
Age: 60
Gender: Male
Posts: 514
Location: Connecticut, USA

15 Nov 2009, 9:54 pm

Whatever Lau said, maybe--I don't have time to trace every register's address to its destination in your code.

Use symbolic variables if you want to be understood and not conflict with critical registers (such as INTCON or PCLATH).



Last edited by CTBill on 15 Nov 2009, 9:55 pm, edited 1 time in total.

kc8ufv
Veteran
Veteran

User avatar

Joined: 27 Jul 2008
Age: 43
Gender: Female
Posts: 762
Location: Toledo, OH

15 Nov 2009, 9:55 pm

Thank you both, I have corrected the problem. Either it was caused because I was using example code for a 16f87, or, the example code I used was a bad example. I moved my counters up to starting at 20h, and they are working much much better.

http://www.mstracey.btinternet.co.uk/pi ... ogtut5.htm



lau
Veteran
Veteran

User avatar

Joined: 17 Jun 2006
Age: 76
Gender: Male
Posts: 9,798
Location: Somerset UK

15 Nov 2009, 10:08 pm

Indeed, Microchip's products started off using just a few low address registers, and gradually crept up to using lots.

The example code you linked to was probably fine for the 16f87.

Note that the example code DID give the locations symbolic names, as CTBill suggested. My preference is to see no numeric values in any code, other than maybe the odd 0, 1 or 2, say. All numeric stuff should be in include files, or at the top of the source code, as equates of one sort or another. Dredging through code to see where a particular number appears, and what it is all about, is a nightmare.


_________________
"Striking up conversations with strangers is an autistic person's version of extreme sports." Kamran Nazeer


CTBill
Veteran
Veteran

User avatar

Joined: 17 Oct 2008
Age: 60
Gender: Male
Posts: 514
Location: Connecticut, USA

15 Nov 2009, 10:27 pm

I'm glad that your code is now working. :)

The PIC processors are very capable little devices, but require an extreme amount of care during development for a successful outcome because of their quirky architecture.



kc8ufv
Veteran
Veteran

User avatar

Joined: 27 Jul 2008
Age: 43
Gender: Female
Posts: 762
Location: Toledo, OH

15 Nov 2009, 11:03 pm

I will probably adjust my code tomorrow after I get home from work to using names for the structures. I can see how it would be easier to follow. I have a deadline of the week before christmas on this project, as it will be a gift for my dad. After I finish the microcontroller stuff, I am gonna get the transistor switches built and tested on the breadboard. Gotta get this ready to put on a real soldered board and then pot it with epoxy. Gonna leave a programming header exposed to modify it later, if need be.