Searching \ for 'Problems with PCLATH,' in subject line. ()
Make payments with PayPal - it's fast, free and secure! Help us get a faster server
FAQ page: www.piclist.com/techref/index.htm?key=problems+with+pclath
Search entire site for: 'Problems with PCLATH,'.

Truncated match.
PICList Thread
'Problems with PCLATH,'
1996\10\27@082645 by Chaipi Wijnbergen

flavicon
picon face
On Sat, 26 Oct 1996, NEIL GANDLER wrote:

>  I am having a problem with a 16c74 program. The program
> length has now exceeded 2K in program length, so now I must
> manipulate the PCLATH register when performing long calls.
> The problem occurs after I place a long call and then try to
> return back to page0 using the RETURN command.

Neil,

When you are running on page 0 and calling a routine on page 1, you set
PCLATH to point to page 1, after returning from page 1, PCLATH is still
pointing into page 1, but, you are running in Page 0, so, for each next
call or goto command, the PIC will try to jump to a location in Page 1.

So, when you use PCLATH, you need to update it before any call that either
jump to another page or jump to a location within the same page but after
returning from the other page.

chaipi

1996\10\27@134936 by Neil Gandler

flavicon
face
On Sun, 27 Oct 1996, Chaipi Wijnbergen wrote:

{Quote hidden}

Thanks for the advice, Do I need to store and restore PCLATH before and
after interrupts?

Neil

1996\10\27@192608 by Steve Hardy

flavicon
face
> From: NEIL GANDLER <spam_OUTV064MB9KTakeThisOuTspamUBVMS.CC.BUFFALO.EDU>
>
>  I am having a problem with a 16c74 program. The program
> length has now exceeded 2K in program length, so now I must
> manipulate the PCLATH register when performing long calls.
> The problem occurs after I place a long call and then try to
> return back to page0 using the RETURN command. My program
> locks up and goes nuts. Subroutines that are executed within
> page1 work fine. The PIC manual does not explain the Long
> Call procedure very well. They mention one sentence about
> saving the PCLATH register during interrupts, but I have no
> clue how this would help or how to do it. I do know that
> interrupts are the cause of my problem. Can anyone offer and
> advice? Thanks.

I encountered this problem recently.  One possible solution is to
code up a macro to perform calls from <2K to >=2K boundary.  I
call this 'hicall'.  Mercifully, only one bit of PCLATH needs to
be manipulated.  hicall:

       . disables interrupts
       . sets bit 3 of PCLATH
       . calls the nominated routine in the upper block
       . clears bit 3 of PCLATH
       . enables interrupts.

Why do I disable interrupts?  Well, if you don't, then your interrupt
service routine must save and restore PCLATH.  Since this requires
about 5 cycles and an extra register I chose not to do it since every
cycle counts in an interrupt handler.  (However, if your int handler
does not perform any calls or gotos then you can skip the save).

The down side of this simple scheme is that all routines in the upper
block must run disabled for interrupts.  If the high routines need to
call low routines, another macro (lowcall) should be coded.  Such nested
(low) routines may re-enable interrupts, but must disable interrupts
before returning to the high caller.

I found this division of code into a low (interruptable) and high
(disabled) sections was quite satisfactory.  As a bonus, the high
routines can use as scratch registers the registers normally used by
the interrupt handler for saving W and status.

One trick that will allow the fastest possible int handler without
the necessity of disabling the high routines or saving PCLATH is:

       . Code the entire int handler as a macro.  It must not make
         any calls or jumps outside of itself.  All labels should
         be LOCAL.
       . Expand the macro at ORG 4h and also at ORG 804h

Although wasteful of code space, the interrupt routine will now be
insensitive to the state of PCLATH.

I have noticed that most of my code only modifies PCLATH to ensure that
it is correct for computed gotos/table lookups, and also for calling over
2K boundaries.  For a memory map which looks like the following:

       0000 - Jump to hard reset routine
       0004 - Interrupt service
       00xx thru 06FF - Main code low block
       0700 thru 07FF - Table lookups/computed gotos
       0804 - Duplicate of interrupt service (optional)
       08xx thru 0EFF - Main code high routines
       0F00 thru 0FFF - High table lookups/computed gotos

then PCLATH is manipulated in the following way:

       . On reset, it is initialised to 07h.  This primes it for
         table lookups since all these are at 700-7FF (or F00-FFF).
       . BSF/BCF PCLATH,3 is used to switch pages prior to a cross-
         block call or goto.

This minimises mucking around with this problematic register.  Your
table lookups/computed gotos can now assume that PCLATH is correct,
thus opening up the possibility of using W directly as a parameter
rather than the old-fashioned way of saving the lookup parameter in
a register.

As an aside, what does one do with the three 'wasted' instructions
at locations 1, 2 and 3?  Well, I use these to contain code identifier,
version and release codes (stored as RETLWs).  This has the advantage
that any old PIC (programmed by me) can be read by the programmer to
determine what was last programmed.  Can be useful, since one '84 looks
awfully similar to another from the outside.

Regards,
SJH
Canberra, Australia

1996\10\27@212749 by Shel Michaels

picon face
In a message dated 96-10-27 07:29:37 EST, Neil writes:

<<  They mention one sentence about
saving the PCLATH register during interrupts, but I have no
clue how this would help or how to do it. I do know that
interrupts are the cause of my problem. >>

  If, for instance, your interrupt service routine modifies PCLATH - perhaps
because it uses a page 1 subroutine - then PCLATH remains modified even after
you interrupt return, which may be to page 0.
  So...in the same way that you store W and STATUS in temporary locations
when you start your interrupt service routine, store PCLATH also.  At the end
of your service routine, just before restoring W and STATUS and doing your
RETFIE, also restore PCLATH.

Regards,
...Shel Michaels
.....sbmichaelsKILLspamspam@spam@aol.com

1996\10\28@004858 by tjaart

flavicon
face
NEIL GANDLER wrote:
>
>  I am having a problem with a 16c74 program. The program
> length has now exceeded 2K in program length, so now I must
> manipulate the PCLATH register when performing long calls.
> The problem occurs after I place a long call and then try to
> return back to page0 using the RETURN command. My program
> locks up and goes nuts. Subroutines that are executed within
> page1 work fine. The PIC manual does not explain the Long
> Call procedure very well. They mention one sentence about
> saving the PCLATH register during interrupts, but I have no
> clue how this would help or how to do it. I do know that
> interrupts are the cause of my problem. Can anyone offer and
> advice? Thanks.
>
>      Neil Gandler

If you're not sure where the heck you are in the pages, you can do this
after a "return"

My_label
       movlw   ((Mylabel>>8)&&0xFF)
       movwf   PCLATH

Not very efficient in ROM terms, but effective in where-the-heck-am-i
terms.
--
Friendly Regards

Tjaart van der Walt
______________________________________________________________
|  Another sun-deprived R&D Engineer slaving away in a dungeon |
|WASP International GSM vehicle tracking and datacomm solutions|
|           +27-(0)11-622-8686 | http://wasp.co.za             |
|______________________________________________________________|

1996\10\28@051255 by Andy David

flavicon
face
Neil,

sounds like you understand how addresses are derived by combining
PCLATH and PCL... but don't forget that PCLATH isn't automatically
maintained by the PIC: when you manipulate PCLATH for the long
call into page1, the return will work fine as the full return
address is pushed onto the stack (and hence the correct address
can be returned to) - PCLATH, however, was *written to* by the long
call procedure but *not restored* by the return -  further call (or goto)
instructions will still use the long-call-modified PCLATH and
hence still work like a long call - you need to restore PCLATH
yourself after the return.

In your ISR, it's a pretty safe bet that you'll need to perform
some local gotos, so you need to ensure that PCLATH is
configured for this.
When saving the context in your ISR, save PCLATH as well and make
sure that PCLATH is then loaded with a value that will jump into
the correct page during your ISR. Restore PCLATH when you restore
context and RETFIE, and it should be ok.

There's a good explanation of this (answer #36) on Andy Warren's
answers page, plus some example code. Good onya, Andy!


- Andy.

*************************************************************
Andrew David               Senior Project Engineer - Software

Ultronics Division         AndyspamKILLspamUltronics.co.uk
Ultra Hydraulics Ltd.
Anson Business Park
Cheltenham Road East
Staverton
Glos. GL2 9QN

Tel.: (01452) 858376 (Direct)  Ultronics Fax.: (01452) 858377
*************************************************************

1996\10\28@103459 by Wireless Scientific

flavicon
face
At 3:28 PM 10/26/96, NEIL GANDLER wrote:
> I am having a problem with a 16c74 program. The program
>length has now exceeded 2K in program length, so now I must
>manipulate the PCLATH register when performing long calls.
>The problem occurs after I place a long call and then try to
>return back to page0 using the RETURN command. My program
>locks up and goes nuts. Subroutines that are executed within
>page1 work fine. The PIC manual does not explain the Long
>Call procedure very well. They mention one sentence about
>saving the PCLATH register during interrupts, but I have no
>clue how this would help or how to do it. I do know that
>interrupts are the cause of my problem. Can anyone offer and
>advice? Thanks.
>
>     Neil Gandler


I had the exact same problem! make sure you have the correct probe selected.

craig

1996\10\28@105248 by tjaart

flavicon
face
Steve Hardy wrote:
{Quote hidden}

A simple solution is to use a MPASM address for a label. Right shift it
8 times, and load it into PCLATH. You can even make a macro out of it :

Fix_up_PCLATH MACRO
       local   Local_Label
Local_Label
       movlw   ((Local_Label>>8)&&0xFF)
       movwf   PCLATH
       ENDM

Now all you have to do after returning from a unknown address location,
is "Fix_up_PCLATH"

It uses two words of ROM, but saves your sanity.


--
Friendly Regards

Tjaart van der Walt
______________________________________________________________
|  Another sun-deprived R&D Engineer slaving away in a dungeon |
|WASP International GSM vehicle tracking and datacomm solutions|
|           +27-(0)11-622-8686 | http://wasp.co.za             |
|______________________________________________________________|

1996\10\28@120733 by Ian Stirling

flavicon
face
--
Ian Stirling.                        |  http://www.mauve.demon.co.uk/
AKA Caeser, Bolonewbie.              |  With information on the PDA I'm making.

1996\10\28@175102 by myke predko

flavicon
face
Tjaart Wrote...
>
>Fix_up_PCLATH MACRO
>        local   Local_Label
>Local_Label
>        movlw   ((Local_Label>>8)&&0xFF)
>        movwf   PCLATH
>        ENDM

Actually, this can be simplified to:

       movlw    $ >> 8
       movwf    PCLATH

myke

Avoiding precedents does not mean nothing should ever be done.  It only
means that nothing should ever be done for the first time - Sir Humphrey
Appleby K.C.B.

More... (looser matching)
- Last day of these posts
- In 1996 , 1997 only
- Today
- New search...