title: Stack overflow in Pic16F684 Microcontroller when using Lookup tables
body: <p><br>
  My task was to develop a program which will blink LEDs from D7 to D0.
  <br>I have develop solution which blinks them once and then have a stack overflow.
  <br>I am suspicious on lookup tables becouse previosly i have faced an error on last TRISA configuration(commented now)
  I am pasting the code.</p>
  
  <pre><code>    ;*********************************************************************************
  ; Filename: Pic_demonstration.asm -it should be!
  ; Author:   Alexander Drabek
  ; Date:     01.05.13
  ; Description:  This Assembler program for PIC16F684 turns ON and OFF LEDs from D7 to D0
  ;               with a delay of 0.5 second
  ;Check if trisa reaching the 4th and PORTA eight leds.
  ;To report:
  ;1.separate PCL in Bank1 and Bank0
  ;2.Lookup table and undaestanding of options of the code.
  ;3.we are assuming to work in Bank0
  ;4.overflow.
      list     p=16F684       ; List directive to define processor
      #include &lt;p16f684.inc&gt;  ; Processor specific variable definitions
      __CONFIG  _CP_OFF &amp; _WDT_OFF &amp; _PWRTE_ON &amp; _INTRC_OSC_NOCLKOUT &amp; _MCLRE_OFF &amp; _CPD_OFF
  ;****************************** Assignment Statements ****************************
  ;Delay counters
      COUNT1 EQU 20h  ; Store COUNT1 at address 20h
      COUNT2 EQU 21h  ; Store COUNT2 at address 21h
      normal EQU 22h  ; Store normal at address 22h - responsible for general loop(4 times change trisa)
      COUNT3 EQU 26h ; another counter to make more delay 
  ;Loops counters
      PORTA_Internal EQU 23h       ;Store PORTA_Internal at address 21h
      COUNT_LED_NUMBER EQU 24h    ; Store COUNT_LED_NUMBER at address 21h
      COUNT_TRISA_NUMBER EQU 25h  ; Store COUNT_TRISA_NUMBER at address 21h
  ;****************************** "Start" of Program ******************************
  ; Initial configuration 
  ;errorlevel -302 ; Disable bank switch warning 
          org     0x000       ; Processor reset vector
          bcf     STATUS,RP0  ; Bank 0 selected
          movlw   07h         ; Set RA&lt;2:0&gt; to digital and 
          movwf   CMCON0      ; Comparators turned OFF
          bsf     STATUS,RP0  ; Bank 1 selected
          clrf    ANSEL       ; Digital I/O selected
          movlw   B'00111111' ; Move in W - 0x3F - Set all I/O pins as digital inputs
          movwf   TRISA       ; Configure I/O ports       
          clrf    INTCON      ; Disable all interrupts, clear all flags   
          bcf     STATUS,RP0  ; Bank 0 selected
          clrf    PORTA       ; Clear all outputs
  ;*********************************************************************************
  ; Load values for counters . 
  AGAIN;reset the value 
          movlw   B'11101010'         ; First load a value of say, F0h in the W register
          movwf   COUNT2      ; Now move it to COUNT2 register
          movlw   0x03;       ; First load a value of say, F0h in the W register
          movwf   COUNT3      ; Now move it to COUNT2 register
          movlw   B'00000100' ; Load a value 4, in the W register
          movwf   normal      ; Move it to normal
          movlw   B'00000010' ; First load a value of say, 1 in the W register
          movwf   PORTA_Internal  ; Now move it to PORTA_Internal
          movlw   B'00000000'     ; First load a value of say, 1 in the W register
          movwf   COUNT_LED_NUMBER    ; Now move it to COUNT2 register
          movlw   B'00000000'         ; First load a value of say, 1 in the W register
          movwf   COUNT_TRISA_NUMBER  ; Now move it to COUNT2 register
          goto start_loop 
  ;********************************************************************************
  ;*********************************************************************************
  
  Lookup_PORTA    
               movlw  low TablePORTA
               ADDWF  COUNT_LED_NUMBER,0                   
               movwf  PCL                 ; Jump to specified entry
  TablePORTA   RETLW B'00000010'  ; Sending HIGH to D7 -ok
               RETLW B'00000100'  ; Sending HIGH to D6 -ok
               RETLW B'00000100'  ; Sending HIGH to D5 -ok
               RETLW B'00100000'  ; Sending HIGH to D4 -ok
               RETLW B'00000100'  ; Sending HIGH to D3 -ok
               RETLW B'00010000'  ; Sending HIGH to D2 -ok
               RETLW B'00100000'  ; Sending HIGH to D1 -ok
               RETLW B'00010000'  ; Sending HIGH to D0 -OK--------
  Lookup_TRISA    
               movlw  low TableTRISA 
               ADDWF COUNT_TRISA_NUMBER,0                
               movwf  PCL                             ; Jump to Specified entry   ;     RETLW B'00111001'; 57    - overflow!      
  TableTRISA   RETLW B'00011011'; 27-DECIMAL    ; Element 0 of lookup table
               RETLW B'00101011'; 43-DECIMAL  ; Element 1 of lookup table
               RETLW B'00001111'; 15-DECIMAL          ; Element 2 of lookup table                     
  ;it is always loading first one of eac lookup tables!
  ;*********************************************************************************
  start_loop      
      ;Temporary solution for overflow 
               bsf    STATUS,RP0      ; Bank 1 selected
               movlw   B'00111001'        ; TRISA for D6 and D7
               movwf  TRISA
               bcf    STATUS, RP0 ; Bank 0 selected
               call   DELAY
               CALL   Lookup_PORTA  ; Call the table. -it should obtain the address for next memory cell with PORTA config
               movwf  PORTA       ;light this diod!
               call   DELAY       ; for a half second                 
               clrf   PORTA       ;  Clear PORTA 
               incfsz COUNT_LED_NUMBER,1 ;increase LED NUmber! save into variable!
               call   DELAY
               CALL Lookup_PORTA  ; Call the table. -it should obtain the address for next memory cell with PORTA config
               movwf  PORTA       ;light this diod!
               call   DELAY       ; for a half second                 
               clrf   PORTA       ;  Clear PORTA 
               incfsz COUNT_LED_NUMBER,1
  ;end of temporary solution
  ITERNAL_TRISA_LOOP ;Change the trisa after 2 diods ,do it till end of lookup table
               CALL Lookup_TRISA  ; Call the table. -it should obtain the address for next memory cell with trisa config
               bsf  STATUS,RP0    ;Bank 1
               movwf TRISA        ;Move config to TRISA
               bcf STATUS, RP0    ;Reset bank to 0 
               decfsz normal,1    ;Decrease the number of posible configuration in this iteration value of 5 -Not sure --it will omit las one (option 4)
               goto INTERNAL_LOOP_2DIODS ; Blink 2 diods including delays
               goto AGAIN ; 
  
  INTERNAL_LOOP_2DIODS  ;develop the delay ! +TRISA CHANGE
               bcf    STATUS, RP0 ; 
               call   DELAY
               CALL Lookup_PORTA  ; Call the table. -it should obtain the address for next memory cell with PORTA config
               movwf  PORTA       ;light this diod!
               call   DELAY       ; for a half second                 
               clrf   PORTA       ;  Clear PORTA 
               incfsz COUNT_LED_NUMBER,1 ;increase LED NUmber! save into variable!
               decfsz PORTA_Internal,1 ; it should have value of 2 XD
               goto INTERNAL_LOOP_2DIODS ; only 1 repeat!
               incfsz COUNT_TRISA_NUMBER,1 ;increase the TRISA config number
               movlw  B'00000010'         ; First load a value of say, 1 in the W register
               movwf  PORTA_Internal  ; Now move it to COUNT2 register
               goto  ITERNAL_TRISA_LOOP      ;- Loop forever -
  goto AGAIN
  ;*********************************************************************************
  ; DELAY Subroutine
  ;*********************************************************************************
  ; Generate a delay period
  DELAY
  LOOP1   decfsz   COUNT1,1   ; Decrement COUNT1 and skip next instruction if zero
          goto     LOOP1      ; else loop back to LOOP1
          decfsz   COUNT2,1   ; Decrement COUNT2 and skip next instruction if zero
          goto     LOOP1      ; else loop back to LOOP1
          decfsz   COUNT3,1   ; Decrement COUNT1 and skip next instruction if zero
          goto     LOOP1      ; else loop back to LOOP1
          movlw    0x03       ; Reload the second counter for the next iteration
          movwf    COUNT3     ; Decrement COUNT3 and skip next instruction if zero
          movlw    0xF0       ; Reload the second counter for the next iteration
          movwf    COUNT2
          return              ; else loop back to LOOP1
  
  ;*********************************************************************************
          end
  ;*********************************************************************************
  </code></pre>
  
  <p><br>Anyone know what could be wrong?
  During debuging value for each counter seems ok to me.<br>
  I have tried to look for help but i am  quite new in assembly programming.</p>