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.

Crossing Page Boundary - Code Problem

Status
Not open for further replies.

Suraj143

Active Member
I'm doing table patterns in my LED matrix. I placed delay routines bottom of my code.When my program gets bigger above 2K limit the code gets stuck.
MPLAB also generates a warning message "Crossing Page Boundary". For the entire program I'm calling Delay routine over 200 times. I noticed when my delay routine address goes above 2K limit this happens.

Is there anyway to call delay without problem?
 
You can use a vector table at the beginning of your code.

So for your delay in bank 2 do the following in bank 0.
Code:
delay
         movlw  high(delay1)
         movwf  PCLATH
         movlw  low(delay1)
         movwf  PCL
and rename your delay code to delay1.
If you move a few larger routines into bank 1 then you will free up bank 0 memory.

Long time since I did this so let me know if there are any problems.

Mike.
Edit, you also need to add clrf PCLATH before the return in delay1.
 
You can use a vector table at the beginning of your code.

So for your delay in bank 2 do the following in bank 0.
Code:
delay
         movlw  high(delay1)
         movwf  PCLATH
         movlw  low(delay1)
         movwf  PCL
and rename your delay code to delay1.
If you move a few larger routines into bank 1 then you will free up bank 0 memory.

Long time since I did this so let me know if there are any problems.

Mike.
Edit, you also need to add clrf PCLATH before the return in delay1.

Wonderful suggestion.
I'm adding more patterns to my led matrix. The last pattern address is in 2K range.I'm adding more patterns, so it will go around 4K limit.

I will place the above code in the upper part of the program memory.I will let you know how it goes.

Thanks.
 
Be careful calling subroutines from subroutines. When you are in bank 1 and you call a routine in bank 0 then it will stay in bank 1 and crash.

For simplicity, move routines that don't call other routines.

OR, move groups of routines. For example, LCD routines can all be moved into bank 1 and only the init and write char have to be called from bank 0.

Mike.
 
Program Memory and Ram usage is so much simpler with Assembler if you use the 18F chip range; very easy to port 16F code over.
 
Program Memory and Ram usage is so much simpler with Assembler if you use the 18F chip range; very easy to port 16F code over.
Even simpler with C.. But if ASM is your language, I agree! pic18 is easier... But the asm code is a tad harder..
 
Can we start referring to program memory as "pages" and ram as "banks?"

upload_2018-2-1_5-32-38.png


RAM:

upload_2018-2-1_5-33-53.png


I know Pommie knows that distinction and his suggestions have been right on, despite the slip. But, it can be a confusing issue. For one thing, there is "general purpose" ram and "common" ram (for those chips that have it). The latter functions across all banks. Moreover, indirect accessing is different for accessing program memory (set FSRxH<7>) than for ram.

John
 
It's so long since I used assembly that I forgot the terms that should be used. Pages it is.

Mike.
 
If you are adding more patterns, you could put them all in upper memory and keep your Delay routine on bank 0.
 
Hi all

I just checked my ISR routine, It is too big (exceeding 1st page boundary 0FFh) so I cannot put those vectors in the first page 0h-FFh.My main loop starts from page 2 that is between 0x100 - 0x200 location. I tried all the methods but only below code works. My patterns are not subroutines, just flow code. Subroutines are Delay_1S & Col_Rotate_CW.So many are there.

The problem is for previous & future patterns one by one I have to add [bsf PCLATH,3] & [clear] it. Is there any shorter way of doing that?


Code:
Pat_33        movlw        .2        ;061B address location
        movwf        Count
        movlw        b'01111000'
        movwf        33h
        movlw        b'00011110'
        movwf        37h
Pat_33_Loop    bsf        PCLATH,3
        call        Col_Rotate_CW                  
        call        Delay_1S
        bcf        PCLATH,3
        bcf        Flag_Register,Feed_Rotate
        decfsz        Count,F
        goto        Pat_33_Loop
        goto        Pat_34


        org        0x0900
Col_Rotate_CW    ---
        ---
        return
Delay_1S    ---
        ---
        return
 
Last edited:
Oops sorry I don't have larger tables. I only have soo many patterns that they cannot show by a table . When my program gets bigger the subroutines are going beyond 2K limit. Thats my problem.
I cannot place on top part of program memory because I have a larger ISR as well.

See a sample pattern code.

Code:
clrf        R4
            call        Col_Rotate_CW
            call        Delay_1S
            movlw        b'11110000'
            movwf        R4
            call        Col_Rotate_CW            ;ok
            bcf        Flag_Register,Feed_Rotate        ;
            call        Col_Rotate_CW
            call        Delay_1S          
            bsf        Flag_Register,Feed_Rotate
            movlw        b'00111100'
            movwf        R4
            clrf        R3
            call        Col_Rotate_CW
            call        Delay_1S
 
Last edited:
I think its better to move ISR routine to the last page of PIC16F886 that is closer to the address of 7k-8K...!!!! & place subroutine vectors in the first page block ?
 
Oops sorry I don't have larger tables. I only have soo many patterns that they cannot show by a table . When my program gets bigger the subroutines are going beyond 2K limit. Thats my problem.
I cannot place on top part of program memory because I have a larger ISR as well.

It's really best to keep ISR's as short as possible, and you use long calls (either manually, or use the macro) to access subroutines in higher memory.
 
Seems as your code develops you are going to run into more and more page boundary and ram bank problems.

Without having a full overview of your project i/o needs, would suggest you use a Pic18F2520 , or 4520 / 2620 /4620 and similar chips, all normally easy and lo cost to buy.

That has 32kb of Program memory, without any page boundaries, just one contiguous array.

The Ram banks are similarly very easy to handle as each bank is 256 bytes, and with one bank select at the beginning of your code allows you to have 384 bytes available without changing banks, eg bank 0 access 128 + bank 1 256 = 384 bytes.
So much easier to code, plus it has extra helpful assembler instructions , and normally its very easy to recompile you 16F code.


Have to agree with the Nigel, if you have so much code in the ISR your program flow needs improving, eg , if you are testing interrupt conditions then rather than executing the resultant action set in the ISR, set a Flag for the main code to pick up.
 
I am curious why there are so many patterns. In an earlier thread we worked on a pseudo-random generator. My thought at the time was that the generator would be used to create the patterns as needed, rather than store each of the 250+(up to millions) patterns in program memory.

Is that not the case? How many patterns do you have stored? How many bytes are required for each pattern?
 
Oops sorry I don't have larger tables. I only have soo many patterns that they cannot show by a table . When my program gets bigger the subroutines are going beyond 2K limit. Thats my problem.
I cannot place on top part of program memory because I have a larger ISR as well.

See a sample pattern code.

Code:
clrf        R4
            call        Col_Rotate_CW
            call        Delay_1S
            movlw        b'11110000'
            movwf        R4
            call        Col_Rotate_CW            ;ok
            bcf        Flag_Register,Feed_Rotate        ;
            call        Col_Rotate_CW
            call        Delay_1S         
            bsf        Flag_Register,Feed_Rotate
            movlw        b'00111100'
            movwf        R4
            clrf        R3
            call        Col_Rotate_CW
            call        Delay_1S

Could you verify if some code currently in your ISR, could be executed in the main loop, based maybe, on flags ser/reset inside the ISR.

You could eventually be surprised of how much your code would be simplified.
 
Here how I'm going to do.
GOing to place all of my subroutines above 2K limit & call them by writing to PCLATH. Any comments.

Code:
Main_Loop        org        0x014C        ; 2nd 255 block        
Pat_1            call        Clear_Display
            movlw        .2
            movwf        Repeat_Count
Pat_1_A            movlw        .40
            movwf        Count
            movlw        .1
            movwf        Height
Pat_1_A_Loop        movlw        b'10101010'
            movwf        R1
            bsf        PCLATH,3
            call        Spread_Up
           bcf        PCLATH,3
            movlw        b'01010101'
            movwf        R1
            bsf        PCLATH,3
            call        Spread_Up
            bcf        PCLATH,3
            decfsz        Count,F
            goto        Pat_1_A_Loop
            goto        Pat_2

Pat_2            ---
            ---

Pat_3            ---
            ---

;All my subroutines placed from 0x0900 onwards

            org        0x0900        ; 9th 255 block
Spread_Up        clrf        R2
Spread_Up_Init        movf        R1,W
            movwf        P1
            movwf        P2
            movwf        P3
            movwf        P4
            call        Init_Column_Set1
Spread_Up_Loop        bcf        STATUS,C
            rlf        P4,F
            rlf        P3,F
            rlf        P2,F
            rlf        P1,F
            call        Feed_1_Column_UP
            decfsz        Columns,F
            goto        Spread_Up_Loop
            call        Delay_1S
            incf        R2,F
            movf        R2,W
            xorwf        Height,W            ;2
            btfss        STATUS,Z
            goto        Spread_Up_Init
            return

Init_Column_Set1    movlw        .29
            movwf        Columns
            movlw        30h                ; start at 30h
            movwf        FSR
            return

Feed_1_Column_UP    rlf        INDF,F
            incf        FSR,F
            rlf        INDF,F
            incf        FSR,F
            return
 
Last edited:
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top