# 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?

#### Pommie

##### Well-Known Member
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.

#### Suraj143

##### Active Member
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.

#### Pommie

##### Well-Known Member
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.

#### Wp100

##### Well-Known Member
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.

#### Ian Rogers

##### User Extraordinaire
Forum Supporter
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..

#### jpanhalt

##### Well-Known Member
Can we start referring to program memory as "pages" and ram as "banks?"

RAM:

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

#### Pommie

##### Well-Known Member
It's so long since I used assembly that I forgot the terms that should be used. Pages it is.

Mike.

#### ClydeCrashKop

##### Well-Known Member
If you are adding more patterns, you could put them all in upper memory and keep your Delay routine on bank 0.

#### Suraj143

##### Active Member
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:

#### Suraj143

##### Active Member
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:

#### Suraj143

##### Active Member
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 ?

#### Nigel Goodwin

##### Super Moderator
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.

#### Wp100

##### Well-Known Member
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.

#### jpanhalt

##### Well-Known Member
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?

#### atferrari

##### Well-Known Member
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.

#### Suraj143

##### Active Member
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
bcf        PCLATH,3
movlw        b'01010101'
movwf        R1
bsf        PCLATH,3
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
movwf        P1
movwf        P2
movwf        P3
movwf        P4
call        Init_Column_Set1
rlf        P4,F
rlf        P3,F
rlf        P2,F
rlf        P1,F
call        Feed_1_Column_UP
decfsz        Columns,F
call        Delay_1S
incf        R2,F
movf        R2,W
xorwf        Height,W            ;2
btfss        STATUS,Z
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.