Searching \ for 'Interrupt' 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/microchip/ints.htm?key=interrupt
Search entire site for: 'Interrupt'.

No exact or substring matches. trying for part
PICList Thread
'PIC16C84 interrupts'
1994\10\17@072424 by crocontroller discussion list

flavicon
face
Is there an application note for the 16c84 (and similar) interrupt usage ?

The interrupt handling on these seems to be rather more quirky than for
many microcontrollers, but I can only find isolated notes about what to
watch out for - notably some comments in AN555 about preserving the
status bits while restoring W, and a warning about interrupt-protecting
manipulations of PCL in another note (possibly one about table lookups -
I can't remember the number. It's in the embedded applications book).

In the absence of an application note, do any other readers know of good
references (Nigel Gardner's introductory book doesn't cover this area at
all) or have warnings / workarounds to share ?


On an unrelated subject, is there a way to get the picstart programmer
to initialise the data EEPROM on the 16C84 ? I can only find methods
for the program and config EEPROM, though the device does permit ISP
access to the data area.
Can I setup data EEPROM in MPSIM, other than interactively with the EE
command - I'd like to set up a number of values, e.g. with the .ini file.

-adrian

1994\10\17@075156 by crocontroller discussion list

flavicon
face
> On an unrelated subject, is there a way to get the picstart programmer
> to initialise the data EEPROM on the 16C84 ? I can only find methods
> for the program and config EEPROM, though the device does permit ISP
> access to the data area.

Adrian,

I think David Tait's code will do the trick, but you'll have to build the
interface between you parallel port and the 16c84 to use it. :)

Yours,

Derrick Early

1994\10\17@081059 by crocontroller discussion list

flavicon
face
> I think David Tait's code will do the trick, but you'll have to build the
> interface between you parallel port and the 16c84 to use it. :)
>
> Yours,
>
> Derrick Early

Yes, it will - so I'd assumed that the picstart could too, and wrote
some code that expected that some factory-initialised data could be
put in there. Now I find that the person making the device will have
to build some programming hardware even though he's already got the
picstart programmer !

This would also have been useful while developing the code - If the
data area is accessible from the programmer, it allows testing to
be carried out without both reading and writing functions working.

This may not be too dreadful, because there's some advantage in adding
an ISP port and programming the part in situ rather than in a programmer
(especially if a surface mount device is used) but it's something of
a nuisance, and needn't add any extra cost to the picstart programmer
board.

-adrian

1994\10\17@094454 by crocontroller discussion list

flavicon
face
Adrian,

Too bad the picstart source isn't available.  That is why I decided to
build my own.  Also, I wanted to be able to do a Vhi and Vlo verify.

Good luck,

Derrick Early

'Protecting PCL changes against interrupts'
1994\10\27@121958 by crocontroller discussion list

flavicon
face
AN556 indicates that 'movwf PCL' on a PIC with interrupts enabled is
dangerous, as the interrupt processing will increment the computed
value of PCL before stacking it (normally it would increment the
_present_ value of PCL, causing a return to the next instruction).

This is a fairly significant feature, and if it also applies to the
more common  'addwf PCL',  users of the newer PICs need to be rather
careful around PCL-modifying code such as table lookups.

Can anyone confirm if this is really a problem ? Is it something that
applied only to some early mask revisions ?  Is there a clock-by-clock
description of the interrupt operation somewhere ?

-adrian

1994\10\28@084954 by crocontroller discussion list

flavicon
face
>
> AN556 indicates that 'movwf PCL' on a PIC with interrupts enabled is
> dangerous, as the interrupt processing will increment the computed
> value of PCL before stacking it (normally it would increment the
> _present_ value of PCL, causing a return to the next instruction).
>
> Can anyone confirm if this is really a problem ?
>
I have done a quite extensive project using a PIC 16C71 including a
some "addwf PC" (PC=PCL) in the non-interrupt drive part and I
haven't had any problems at all with that part. My problems has been
to make the chip not to miss any interrupts. Beside the known bug
with the INT pin (sometimes it misses an interrupt) I had to clean
out all instuctions concerning Port B (even readings) in order to get
the change-of-state interrupt to work...

/Tomas

Tomas Westlund
OPQ Systems AB
SWEDEN
spam_OUTtomasTakeThisOuTspamopq.se

1994\10\28@091718 by crocontroller discussion list

flavicon
face
Hi Adrian,

I think that you probably already do this, but I just make sure that I
disable the interrupts before touching PCL.  I used the code in the data
book to nail the interrupts off.  After I finish with the table lookup,
I turn the interrupts back on.

Sorry, if I'm telling you something that you already know.

Yours,

Derrick Early

1994\10\28@110326 by crocontroller discussion list

flavicon
face
Derrick Early wrote :
> I think that you probably already do this, but I just make sure that I
> disable the interrupts before touching PCL.  I used the code in the data
> book to nail the interrupts off.  After I finish with the table lookup,
> I turn the interrupts back on.

I could do that, but it would expand the code (I use a lot of lookups)
and increase the interrupt latency (probably OK in this application).

Since the warning in AN556 only refers to movwf PCL and I'm only using
addwf PCL, I don't want to add the extra instructions unless it's
absolutely necessary. The addwf instruction is often shown in table
lookup examples, without any warning about interrupts, but I can't see
why the addwf instruction would be safe if the movwf instruction isn't.

I (and others) haven't seen any problems through not protecting from
interrupts, though that doesn't really prove it one way or another.

-adrian

1994\10\28@125212 by crocontroller discussion list

flavicon
face
Hi again Adrian,

The problem occurs if you get an interrupt between the time that you set the
PCL and when you set the PC for the program jump.  Oops, maybe I didn't
understand.  I thought that you were jumping outside of a segment.  I believe
that everything is fine as long as your table lookups stay within a segment
of the program.  ie. the high bits stay the same.  You could organize your
tables in this fashion to keep from having to dissable the interrupts.

Yours,

Derrick


'Nested Interrupts'
1994\11\14@142951 by bruce
flavicon
face
Is it possible to nest interrupts on a PIC 16C71?

What I want to do is to allow two different interrupts to occur at
different times. It will be possible that I would have to service an
interrupt whilst I am still servicing the first one.

Any comments?

1994\11\14@232729 by crocontroller discussion list

flavicon
face
<<Is it possible to nest interrupts on a PIC 16C71?

What I want to do is to allow two different interrupts to occur at
different times. It will be possible that I would have to service an
interrupt whilst I am still servicing the first one.>>

You just need to disable the interrupt being serviced, then set GIE. The
following is an excerpt from INT.ASM, the entirety of which may be found in
DEMO.ZIP, wherever ASPIC.ZIP is found:

PROCINT:
       .if (PICDEVICE == 1671)
;--- A/D interrupt ---
       btfss   ADIE            ;skip if interrupt enabled
       goto    _not_iad        ;not enabled
       btfsc   ADIF            ;not A/D interrupt
       goto    I_ADC           ;A/D Interrupt!
_not_iad:
       .endif

;--- RTCC interrupt ---
       btfss   RTIE            ;skip if interrupt enabled
       goto    _not_irt        ;not enabled
       btfsc   RTIF            ;not RTCC interrupt
       goto    I_RTCC          ;A/D Interrupt!
_not_irt:
;--- RB Change interrupt ---
       btfss   RBIE            ;skip if interrupt enabled
       goto    _not_irb                ;not enabled
       btfsc   RBIF            ;not RB change interrupt
       goto    I_RB            ;PORT B change Interrupt!
_not_irb:
;--- RB0 INT interrupt ---
       btfss   INTE            ;skip if interrupt enabled
       goto    _not_int        ;not enabled
       btfsc   INTF            ;not INT interrupt
       goto I_INT              ;RB0 edge interrupt
_not_int:
       .if (PICDEVICE == 1684)
;--- EEPROM interrupt ---
       btfss   EEIE            ;skip if interrupt enabled
       goto    _not_iee        ;not enabled
       btfsc   EEIF            ;not EEPROM interrupt
       goto    I_EE            ;EEPROM Interrupt!
_not_iee:
       .endif

       retfie


;**********************************************************************
;* RB0 edge interrupt (unused)
;**********************************************************************

I_INT:
       CLB     INTE            ;clear unwanted enable!
       retfie                  ;exit

;**********************************************************************
;* RB CHANGE interrupt (unused)
;**********************************************************************

I_RB:
       CLB     RBIE            ;clear unwanted enable!
       retfie                  ;exit

;**********************************************************************
;* RTCC overflow interrupt handler
;**********************************************************************
       .seg    REGS    ;file space used by this function
_RT_WSAVE:      .ds 1   ;w register save
_RT_STAT:       .ds 1   ;STATUS save
       .seg    CODE

I_RTCC:
       CLB     RTIE            ;disable interrupt to prevent
recursion
       SEB     GIE             ;enable other interrupts
       CLB     RTIF            ;clear flag
       movwf   _RT_WSAVE       ;save W
       movfw   STATUS          ;get STATUS
       movwf   _RT_STAT        ;save STATUS

       movfw   _RT_STAT        ;get STATUS
       movwf   STATUS          ;restore saved status
       swapf   _RT_WSAVE       ;restore W without affecting status
       swapf   _RT_WSAVE,W     ;w is restored
       CLB     GIE             ;disable interrupts
       SEB     RTIE            ;re-enable this one
       retfie                  ;exit (re-enabling interrupts)


'Interrupts'
1995\02\08@033839 by Ran Talbott
flavicon
face
You wrote:

>Say I have two interrupt routines.

It's probably better to say that you don't:  one of the tricks I use to save a f
ew
cycles is to do all the interrupt handling "inline",  and check all the possible
interrupt sources on each interrupt.  E.g.:

   Test INTF,  and branch if off
        Handle external interrupt
   Test T0IF,  and branch if off
        Handle TMMR0 overflow
   etc...
   RETFIE

I'd only do CALLs if I had a service routine complicated enough to take up
more page 0 space than I could spare,  or I had lots of spare CPU time,  and
wanted to trade some for a small improvement in readability.  But the
generous use of whitespace in the inline code does almost as well.

>On the RETURN at the end of the RTCC routine, control passes to the service
>routine.  But what if the RB0 flag was checked before the RTCC routine was
>called?  On RETFIE, would the interrupt service routine be called again
>by the uC because a flag was still high??

Yup:  some chips reset their "interrupt pending" status if you peek at it,  but
the PIC requires that you reset it explicitly.  "Just checking" really means
"just checking" in this case:  you have to BCF INTCON,INTF to make it
shut up.  If you don't clear it,  you'll get an unpleasant surprise...

Ran


'Interrupt Save/Restore for 16Cxx (was: "external r'
1995\06\27@215118 by Andrew Warren
face
flavicon
face
Fernando Soares <.....Fernando.Manuel.Ramos.SoaresKILLspamspam@spam@UNINOVA.PT> wrote:

{Quote hidden}

This works on the 16C71/61 (if you don't care about saving/restoring
PCLATH), but it will not work on any 16Cxx parts whose general-purpose
registers aren't accessible from all pages (e.g., all the other 16Cxx
devices).  For those, save registers with:

   INTW    EQU [any register on page 0]
   INTW1   EQU SAVEW + 080H

   INTS    EQU [any register on page 0]
   INTP    EQU [any register on page 0]
   INTF    EQU [any register on page 0]

   INT_SERVICE:

       MOVWF   INTW            ;STORE W-REG IN CURRENT DATA-SEGMENT.

       MOVF    STATUS,W        ;GRAB THE STATUS REGISTER.

       BCF    STATUS,RP0       ;SWITCH TO PAGE 0.

       MOVWF   INTS            ;STORE THE STATUS REGISTER.

       MOVF    PCLATH,W        ;STORE THE PCLATH REGISTER.
       MOVWF   INTP            ;

       MOVF    FSR,W           ;STORE THE FSR.
       MOVWF   INTF            ;

At the end of your interrupt-handler, do this to restore the registers:

   INT_EXIT:

       MOVF    INTF,W         ;RESTORE THE FSR.
       MOVWF   FSR             ;

       MOVF    INTP,W         ;RESTORE THE PCLATH REGISTER.
       MOVWF   PCLATH          ;

       MOVF    INTS,W         ;RESTORE THE STATUS REGISTER,
       MOVWF   STATUS          ;

       SWAPF   INTW            ;RESTORE THE W-REGISTER.
       SWAPF   INTW,W       ;

       RETFIE                  ;RETURN AND RE-ENABLE INTERRUPTS.

-Andy

P.S.  As far as I know, Klaus Borchers was the first to publicize this
pair of routines.

--
Andrew Warren - fastfwdspamKILLspamix.netcom.com
Fast Forward Engineering, Vista, California


'Using Interrupts on 16C61'
1995\08\25@184433 by Walter Anderson
flavicon
face
I am working on my first PIC project; a device to keep time and
automatically water some plants.  My question centers around the
steps nescessary to set up the '61 (or '84) to use interrupts.

Using MPSIM on the following code, the ISR is never reached.

; variable declarations
tempW           EQU     0x20
tempStatus      EQU     0x21

; program space
org 0x0000
RESET_V         goto    START
               nop
               nop
               nop
INT_V           movwf   tempW
               swapf   STATUS,W
               bcf     STATUS,RP0
               movwf   tempStatus
               ;               ; interrupt service routine
               bcf     STATUS,RP0
               swapf   tempStatus,W
               movwf   STATUS
               swapf   tempW
               swapf   tempW, W
               retfie

START           bsf     STATUS, RP0
               clrwdt
               movlw   B'10100000'             ; enable timer 0 interrupt &
               movwf   INTCON                  ; enable interrupts
loop            goto    loop

1995\08\25@200314 by Brian Read

flavicon
face
Where do you set the option reg. to use the internal clock
or are you using a stimulus file to clock TMR0 from the RA4
pin? TMR0 will never tick unless you do one of 'em :-)

Happy bit fiddling,
Brian


'16C64 Interrupt Problem'
1995\09\15@061253 by Alexander Colquhoun
flavicon
picon face
I am relatively new to using Pics and would be grateful if anyone can
shed some light on a interrupt problem I have encountered using a PIC
16C64.

I have written code for a 16C64 which basically decodes eight serial
bytes of data,stores them in sequential registers,and once they are
all stored outputs them on the i2c bus,via a slave transmitter.

The code is written in two sections:

Section 1:

The main program 1 loops round waiting for a flag being set which
indicates all the bytes are stored in sequential storage registers.
This decoding uses three sources of Interrupt RB0/INT,Interrupt on
change,and Timer0 overflow,each Interrupt being enabled sequentially
and only one being enabled one at a time.
This section of code works fine.

Once the flag is set the program jumps to section 2.

Section 2:

Section two enables only i2c interrupts by setting the SSPIE bit in PIE1
register,and GIE and PEIE in INTCON register.
PIE1 is set in the initialisation section of the program not in section
2,INTCON is setup in section 2.

Main loop 2 loops round waiting for a flag being set which indicates the
end of the transmission of the 8 data bytes,at which point it returns to
the data decode and storage section in section 1.

The i2c interrupt is generated by an address match,via a key being
pressed on a PC.
This section also works fine and provided I do not initiate an i2c
interrupt until all the bytes are in I receive all eight bytes
correctly at the end of the decode and storage section.

What puzzles me however is that if I initiate an i2c interrupt in the
data decode and storage section,I would expect the bus to 'hang' as
the interrupt should not be serviced since it is NOT enabled.
What happens however is the bus appears to 'hang',but once all the bytes
are stored they are output correctly,it appears that the i2c interrupt is
'stored' and once I enable it in section 2 it is then serviced.

I do appreciate that flags get set even though interrupts are not
enabled.

I would be most grateful for any assistance on this,since although the
code works as I want,i.e. the i2c interrupt is serviced immediately
after the first section although I have not initiated one here to my
knowledge.

The code is sequential,and the two sets of interrupts are also only enabled
seperately,so why should trying to initiate an interrupt in a section of
code where it is NOT enabled,be serviced as soon as I enable the
interrupt,but do not try to initiate it.

I hope that someone can help me regards the above,also is there a way to
write the code such that there is only one main loop and interrupt
prioritising.
Ideally enable both i2c and decode interrupts service the first one
and ignore the other till after the first has been serviced.

Thanks in advance for a PIC beginner.

1995\09\16@160613 by Andrew Warren

face
flavicon
face
Alexander Colquhoun <.....alexcKILLspamspam.....AIFH.ED.AC.UK> wrote:

>What puzzles me however is that if I initiate an i2c interrupt in the
>data decode and storage section,I would expect the bus to 'hang' as
>the interrupt should not be serviced since it is NOT enabled.
>What happens however is the bus appears to 'hang',but once all the bytes
>are stored they are output correctly,it appears that the i2c interrupt is
>'stored' and once I enable it in section 2 it is then serviced.
>
>I do appreciate that flags get set even though interrupts are not
>enabled.

Alexander:

Right... The flags get set even though interrupts are not enabled.  When an
interrupt DOES eventually get enabled, however, the PIC will immediately
service it if its corresponding flag is set.  If you don't like this behavior,
you should clear the flags just before enabling the interrupts to which they
correspond.

-Andy

--
Andrew Warren - EraseMEfastfwdspam_OUTspamTakeThisOuTix.netcom.com
Fast Forward Engineering, Vista, California


'Saving W & STATUS from Interrupt using SWAP, AN585'
1995\10\02@100438 by Scott Stephens
flavicon
face
>To: PICLISTspamspam_OUTMITVMA.BITNET
>From: @spam@stephnssKILLspamspammail.pyrotechnics.com
>Subject: Saving W & STATUS from Interrupt using SWAP, AN585 and RTOS's
>
>I was checking out AN585 Real time operating system and noticed that the
author uses:
>MOVWF Temp_W
>SWAPF STATUS,W
>MOVWF TEMP_Stat
>before the Interrupt service routine to save the W and Status registers.
Why use SWAPF STATUS,W ? I can see that if STATUS happens to be 0, the Z
flag would be set but that would happen AFTER the current status was saved
in TEMP_Stat, wouldn't it? Is there another reason?
>
>And does anyone have any other suggestion and/or ideas for multitasking and
reenterant code? I like the examples given, but have trouble getting my
routines to cooperate adapting it to the interrupt and single timer on a 16C84.
>

'Interrupts during table read and AN556'
1995\10\11@040818 by Scott Stephens

flavicon
face
I just read the note on Eric Smith's PIC Page http://www.spies.com/~eric/pic/
mentioning a problem with Interrupts occuring during a table read operation.
AN556, page 5-3, bottom, under bold heading Iterrupts states that "...if the
interrupt occurs just before the "movwf pcl" instruction...On return from
interrupt ,the program will go to the intended offset of the table +1...a
very undesirable result, so interrupts must be disabled during a table read.."

Eric states on his page that at a seminar the Microchip rep's said this
wasn't a problem.

Anyone aware of this, will MPSIM handle is the way a 16C84 will?

1995\10\12@011655 by Andrew Warren

face
flavicon
face
Scott Stephens <KILLspamstephnssKILLspamspamKIWI.PYROTECHNICS.COM> wrote:

>AN556, page 5-3, bottom, under bold heading Iterrupts states that
>"...if the interrupt occurs just before the "movwf pcl"
>instruction...On return from interrupt ,the program will go to the
>intended offset of the table +1...a very undesirable result, so
>interrupts must be disabled during a table read.."
> ....
>Anyone aware of this, will MPSIM handle is the way a 16C84 will?

   Scott:

   This is NOT true.  Interrupts do NOT need to be disabled around
   table reads.  As discussed at some length on the Microchip BBS, if
   this WERE true, interrupts would also have to be disabled around
   GOTOs and CALLs.

   MPSIM handles interrupts and PCL writes exactly as a 16C84 would.

   -Andy

--
Andrew Warren - RemoveMEfastfwdTakeThisOuTspamix.netcom.com
Fast Forward Engineering, Vista, California

1995\10\12@104926 by Jeff D. Pipkins

flavicon
face
From:    Scott Stephens <spamBeGonestephnssspamBeGonespamKIWI.PYROTECHNICS.COM>
|
|I just read the note on Eric Smith's PIC Page
|http://www.spies.com/~eric/pic/
|mentioning a problem with Interrupts occuring during a table read
|operation.  AN556, page 5-3, bottom, under bold heading Iterrupts
|states that "...if the interrupt occurs just before the "movwf pcl"
|instruction...On return from interrupt ,the program will go to the
|intended offset of the table +1...a very undesirable result, so
|interrupts must be disabled during a table read.."
|
|Eric states on his page that at a seminar the Microchip rep's said
|this wasn't a problem.
|
|Anyone aware of this, will MPSIM handle is the way a 16C84 will?

Scott,

I was one of several who found conflicting results and suspected
that the problem didn't actually exist.  A couple of people at
Microchip, including the author of AN556, have since told me
that this is indeed the case -- the problem does not exist, nor
has it ever existed.

My WWW connection is not working right now, but if someone were
to send me Eric Smith's email address, I would be happy to
forward to him my email archive on this problem, including the
note from D'Souza.  For that, matter, if anyone else wants a
copy, you're welcome to it, just send me an email address.

Cheers!
--Jeff

Jeff Pipkins <TakeThisOuTPipkinsEraseMEspamspam_OUTbangate.compaq.com>  -------------------
Opinions above are mine personally; use only at your own risk.

'16C84 interrupts'
1995\10\13@050630 by att%atlas.king.ac.uk%UKACRL.bitnet

flavicon
face
Dear Piclist,
Can anyone give me some pointers to using the RTCC interrupt on the
16C84?
This is how I've got it set up so far.




start       bcf GLOBAL_INTERRUPT    ; disable interrupts

; for a 2.4576MHz crystal, 2457600/256=9600
; load rtcc with 96 giving 100 interrupts/sec

       movlw   b'000111'   ; assign prescaler 1:256
       option
       movlw   .96
       movwf   TMR0        ; set up timer

other stuff . . . .

       bsf TIMER0_INTERRUPT
       bcf TIMER0_FLAG
       bsf GLOBAL_INTERRUPT

loop    goto loop


service movwf   save_w
       movf    status,w
       movwf   save_s
       bcf GLOBAL_INTERRUPT
       btfss   TIMER0_INTERRUPT
       goto    out
       bcf TIMER0_FLAG
       movlw   .96
       movwf   TMR0

       incf    msec
       movlw   .100
       subwf   msec,w
       btfsc   status,c
       goto    out
       clrf    msec

---
interrupt routine . . . .
---

out
       bsf GLOBAL_INTERRUPT
       movf    save_s,w
       movwf   status
       movf    save_w,w
       retfie


Have I missed something? I seem to get interrupts much faster than I
should.

Many thanks.

/\/\att.

1995\10\13@055108 by .Bellis%psy.ox.ac.uk%UKACRL.bitnet

flavicon
face
> Dear Piclist,
> Can anyone give me some pointers to using the RTCC interrupt on the
> 16C84?
> This is how I've got it set up so far.
>
> ; for a 2.4576MHz crystal, 2457600/256=9600
> ; load rtcc with 96 giving 100 interrupts/sec

The embedded control handbook is wrong.  The RTCC counts at
the instruction cycle frequency rather than the oscillator
frequency.

> Have I missed something? I seem to get interrupts much faster than I
> should.

Four times too fast, I think you'll find.

> Many thanks.
>
> /\/\att.

Ray.

--
 Computing Officer, MRC Research Centre in Brain and Behaviour,
    Department of Experimental Psychology, Oxford University
 <http://www.mrc-bbc.ox.ac.uk/~rpb>  <RemoveMERay.BellisspamTakeThisOuTpsy.ox.ac.uk>

1995\10\13@140031 by Scott Stephens

flavicon
face
>Dear Piclist,
>Can anyone give me some pointers to using the RTCC interrupt on the
>16C84?
>This is how I've got it set up so far.
>
>
>
>
>start       bcf GLOBAL_INTERRUPT    ; disable interrupts
>
>; for a 2.4576MHz crystal, 2457600/256=9600
>; load rtcc with 96 giving 100 interrupts/sec

The crystal frequency is divided by four to generate the clock for TMR0, at
that frequency I would load TMR0 with 32 to get 100 interrupts/second.
2.4576/4=614.4
614.4/256=2.4
2.4K/100=24
256-24=232=E8H

>service movwf   save_w
>        movf    status,w
>        movwf   save_s


Use SWAPF intsruction. It won't affect the ZERO flag as does MOVF

ISR     movwf   W_BACKUP        ;
       swapf   STATUS,W
       movwf   STATUS_BACKUP   ;


>        bcf GLOBAL_INTERRUPT

When an interrupt occurs, GIE is cleared. You don't need to clear it. But
when you do, clear it in the following loop:

Lable   bcf     INTCON,GIE
       btfsc   INTCON,GIE
       goto    lable

0therwise, executing an interrupt and RETFIE could re-inable the interrupt
you've just tried to clear.

>---
>interrupt routine . . . .
>---

>        bsf GLOBAL_INTERRUPT

Don't do that. RETFIE will enable GIE on exit. Enabling it early can cause
recursive interrupts, and crash your stack.

>        movf    save_s,w
>        movwf   status
>        movf    save_w,w
>        retfie

       swapf   STATUS_BACKUP,W ;Restore working reg's now that ISR's done
       movwf   STATUS          ;
       swapf   W_BACKUP
       swapf   W_BACKUP,W
       retfie                  ;End of ISR


Disable RBIE and INTE if not in use, otherwise input on RB0, RB4-7 can
result in interrupts.
Good luck.

1995\10\13@164412 by Eric Smith

flavicon
face
>   service movwf   save_w
>          movf    status,w
>          movwf   save_s
...
>          movf    save_s,w
>          movwf   status
>          movf    save_w,w
>          retfie

You will find that this will cause you problems if you start doing
anything in your non-interrupt code that uses the status register.
The problem is that using a movf to restore registers affects the status
register.  You need to change things around to use a swapf instruction:

int:    movwf   save_w
       swapf   status,w
       movwf   save_s
...
       swapf   save_s,w
       movwf   status
       swapf   save_w,f
       swapf   save_w,w
       retfie

This will work on the 61, 71, and 84, but not on parts with bank-switched
registers.

1995\10\14@001844 by John Payson

flavicon
face
> When an interrupt occurs, GIE is cleared. You don't need to clear it. But
> when you do, clear it in the following loop:
>
> Lable   bcf     INTCON,GIE
>         btfsc   INTCON,GIE
>         goto    lable
>
> 0therwise, executing an interrupt and RETFIE could re-inable the interrupt
> you've just tried to clear.

This problem gives me great appreciation both for Microchip's decision to
mimize interrupt latency time by allowing delayed interrupts, and apprecia-
tion as well for other processor designers' decision not to allow interrupts
to be pipelined.  Too bad the PIC doesn't have delayed jumps [using delayed
jumps, a table lookup would be: [line numbers indicate order of execution]

TableLoc:
       movlw   data
4       movlw   data

       ...

TableLookup:
1       addlw   TableLoc
2       movwf   PC
3       goto    NextInstruction
NextInstruction:
5       [code continues here]

Note that while instruction #2 is executing, #3 is being fetched.  Then
while #3 is executing, 4 is being fetched, etc.  Note that if instruction
#4 were a jump, instruction 5 would still be executed, but the next inst-
ruction would be at the target of the #4 jump.

Note that not only would delayed jumps save execution time, but they'd also
remove the need for "retlw" to return a value (freeing up an 8-bit operand
opcode).  They might also simplify the sequencing logic EXCEPT that the
stack would have to be twice as wide [to accommodate two return addresses]
or else tricky bouncing around calls and interrupts would have to be forbid-
den.

> >        bsf GLOBAL_INTERRUPT
>
> Don't do that. RETFIE will enable GIE on exit. Enabling it early can cause
> recursive interrupts, and crash your stack.

BTW, if a normal subroutine wants to enable interrupts upon completion, is
there any objection to using RETFIE?  8051's and 6805's don't like that, but
would the PIC mind?

1995\10\14@134530 by Andrew Warren

face
flavicon
face
Ray Bellis <Ray.Bellis%psy.ox.ac.ukEraseMEspam.....UKACRL.BITNET> wrote:

>The RTCC counts at the instruction cycle frequency rather than the
>oscillator frequency.
>
> > Have I missed something? I seem to get interrupts much faster than
> >I should.
>
>Four times too fast, I think you'll find.

Ray:

Uhh... If this were his only problem, the interrupts would be happening
four times too SLOW.

-Andy

--
Andrew Warren - EraseMEfastfwdspamix.netcom.com
Fast Forward Engineering, Vista, California

1995\10\16@041938 by .Bellis%psy.ox.ac.uk%UKACRL.bitnet

flavicon
face
> Ray Bellis <Ray.Bellis%RemoveMEpsy.ox.ac.ukEraseMEspamEraseMEUKACRL.BITNET> wrote:
>
> >The RTCC counts at the instruction cycle frequency rather than the
> >oscillator frequency.
> >
> > > Have I missed something? I seem to get interrupts much faster than
> > >I should.
> >
> >Four times too fast, I think you'll find.
>
> Ray:
>
> Uhh... If this were his only problem, the interrupts would be happening
> four times too SLOW.

Whoops...  get my brain into gear...  You are, of course, correct.

Ray.

--
 Computing Officer, MRC Research Centre in Brain and Behaviour,
    Department of Experimental Psychology, Oxford University
 <http://www.mrc-bbc.ox.ac.uk/~rpb>  <RemoveMERay.Bellisspam_OUTspamKILLspampsy.ox.ac.uk>

1995\10\16@042806 by s.addison%abdn.ac.uk%UKACRL.bitnet

flavicon
face
Ray Bellis <Ray.Bellis%RemoveMEpsy.ox.ac.ukTakeThisOuTspamspamUKACRL.BITNET> wrote:

>The RTCC counts at the instruction cycle frequency rather than the
>oscillator frequency.
>
> > Have I missed something? I seem to get interrupts much faster than
> >I should.
>
>Four times too fast, I think you'll find.

Ray:

Uhh... If this were his only problem, the interrupts would be happening
four times too SLOW.

-Andy

--
Andrew Warren - EraseMEfastfwdspamspamspamBeGoneix.netcom.com
Fast Forward Engineering, Vista, California

Steve Addison
University of Aberdeen
Tillydrone Avenue
Aberdeen
Scotland
UK
AB9 2TN
Tel: UK 01224 272889
Fax: UK 01224 272396

1995\10\17@073242 by att%atlas.king.ac.uk%UKACRL.bitnet

flavicon
face
Thanks for your responses on 16C84 interrupts, everyone.
This has made things much clearer.
I am still having some slight timing problems though. Getting to
grips with the fact that TMR0 counts up not down as calculated below,
was part of the solution.

I have made an LCD clock and it lost 17 secs in 2 hours.
Surely this is not the accuracy of the crystal?

> >; for a 2.4576MHz crystal, 2457600/256=9600
> >; load rtcc with 96 giving 100 interrupts/sec


> The crystal frequency is divided by four to generate the clock for TMR0, at
> that frequency I would load TMR0 with 32 to get 100 interrupts/second.
                                       ^^
                                       24 surely?

> 2.4576/4=614.4
> 614.4/256=2.4
> 2.4K/100=24      <-----
> 256-24=232=E8H


My next experiment will be to try 99 in my counter rather than 100 in
an attempt to see if the counting is inclusive i.e. 100 -> 0 = 101
counts rather than 100.

/\/\att.

1995\10\17@110103 by Jerry Ethridge

flavicon
face
{Quote hidden}

For anyone who is trying to create accurate interrupt times
on the pic, you must be aware that when you load the rtcc
with a value, the prescaler is cleared to zero. What this
means is that when the rtcc reaches 0, and your interrupt
service routine starts, the prescaler has continued to accumulate
instruction counts. Lets say that it takes a dozen or so counts
to finally get around to clearing the interrupt flag, incrementing
or decrementing your time counter, and then loading the rtcc with
your preload value. The prescaler has been accumulating instruction
ticks and will be incrementing the rtcc when it rolls over. However
when you preload the rtcc, those ticks get wiped out and reset to zero.
Every interrupt cycle loses time!

The solution is to pick your crystal frequency and your prescaler value
such that you never write to the rtcc. It should be allowed to overflow.
This way, the prescaler is never cleared to zero and no clock ticks are
lost.

Good Luck
Jerry

1995\10\17@124257 by Falstaff

picon face
> > I have made an LCD clock and it lost 17 secs in 2 hours.
> > Surely this is not the accuracy of the crystal?
> >
> > My next experiment will be to try 99 in my counter rather than 100 in
> > an attempt to see if the counting is inclusive i.e. 100 -> 0 = 101
> > counts rather than 100.

> The solution is to pick your crystal frequency and your prescaler value
> such that you never write to the rtcc. It should be allowed to overflow.
> This way, the prescaler is never cleared to zero and no clock ticks are
> lost.

You can also disable the prescaler (by assigning it to thw WDT) and
then it is possible to update the counter.  Note that you need to add
two to the value you write to the counter in this case, because the
counter is stopped for two instruction cycles after writing to it.

Frank

"Mutual respect, even if we disagree."
------------------------------------------------------------------------
Frank A. Vorstenbosch        +31-(70)-355 5241        RemoveMEfalstaffKILLspamspamxs4all.nl

'RTCC Finer Points [was Re: 16C84 Interrupts]'
1995\10\17@131247 by Mike Keitz

flavicon
face
Jerry Ethridge wrote:
>
>For anyone who is trying to create accurate interrupt times
>on the pic, you must be aware that when you load the rtcc
>with a value, the prescaler is cleared to zero. What this
>means is that when the rtcc reaches 0, and your interrupt
>service routine starts, the prescaler has continued to accumulate
>instruction counts. Lets say that it takes a dozen or so counts
>to finally get around to clearing the interrupt flag, incrementing
>or decrementing your time counter, and then loading the rtcc with
>your preload value. The prescaler has been accumulating instruction
>ticks and will be incrementing the rtcc when it rolls over. However
>when you preload the rtcc, those ticks get wiped out and reset to zero.
>Every interrupt cycle loses time!

Absolutely correct.

>
>The solution is to pick your crystal frequency and your prescaler value
>such that you never write to the rtcc. It should be allowed to overflow.
>This way, the prescaler is never cleared to zero and no clock ticks are
>lost.
>
This is a solution.  Here are some others:

* Don't use the prescaler at all.  Problem with this is that the interrupt
rate will be rather fast.

* If using the internal clock to drive the prescaler, then the prescaler
value is *known* at all times in the interrupt routine, as it continues to
run.  Jerry alludes to this in his description above.  If the prescaler is
set to 16 for instance, about 16 instructions into the interrupt routine it
will count around to 0 again.  (probably 15 or less since launching the
interrupt uses some cycles).  Writing the RTCC at that point would still
reset the prescaler, but this wouldn't cause a timing error as it is already
0.  (There is also the issue of the poorly-documented "2-cycle
synchronization delay".  Is this also reset?)  In any case, my point is that
when using internal clocks, the timing error resulting from writing to the
RTCC during an interrupt routine will be constant, although possibly hard to
figure out exactly.  This is also a way to get "fractional" resolution of
the interrupt rate without having to "jitter" the reload count.  But there
may be a long wait if a large prescale value is used.

* The 12-bit PICs (16C5X) have a similar RTCC, but no interrupt capability.
Timing on them is done by polling the RTCC.  In this case, writing to RTCC
is the last resort, since it is hard (not impossible) to determine the
contents of the prescaler.  One of the digital clock app notes from
Microchip made the mistake of writing, they probably didn't test it over a
long enough time to see that it didn't work.  One way to trigger an action
every "n" (n < 256) RTCC counts is to read and compare with an expected value:

wt4rtcc
       movfw   RTCC            ;Get RTCC value
       xorwf   exprtcc,0       ;Compare to expected value
       skpz                    ;Skip if expected value reached
       goto    wt4rtcc         ;Keep looping until value reached.
       movlw   n               ;Number of RTCC counts required till next time.
       addwf   exprtcc,1       ;Update the expected value for next time.

The code below this routine will then execute 7 to 12 cycles after RTCC
reaches the expected value.  The prescaler must be set to 8 or more if using
the internal clock option, if externally clocked the RTCC must not increment
faster than once every 5 instruction cycles.  Great simplification is
possible if n=256, if n is a power of 2, the general routine above could
also be simplified.

-Mike

1995\10\17@200113 by Jerry Ethridge

flavicon
face
I wrote:

> >
> >The solution is to pick your crystal frequency and your prescaler value
> >such that you never write to the rtcc. It should be allowed to overflow.
> >This way, the prescaler is never cleared to zero and no clock ticks are
> >lost.
> >

Mike Keitz wrote:

{Quote hidden}

Thank you Mike,

I like these solutions and in fact have added them to my PIC notes file.

It can be difficult however to analyze the system to come up with accurate
timing when messing with the RTCC. For example, If you have anything but a
very simple interrupt routine that may make several decisions and make any
number of jumps that may or may not involve two cycle instructions then you
will have to analyze every possible path and compensate for time lost in the
prescaler.

I just chose a simple solution to minimize my own effort. My own lazyness
has resulted in many elegant yet simple soulutions :).

For example, for a clock, I would go with a 4194304 crystal (common freq),
and set the prescaler to 16. Then I would let the RTCC overflow and never
write to it. This will result in 256 interrupts a second. Use a software
variable as a counter and everytime this counter reaches zero voila, 1
second.

4194304/4/16/256/256=1

With the prescaler set to 16 along with the RTCC counter, this will give you
4096 instructions to play with between each interrupt. For a clock, this
should be plenty.

If you need ms resolution go with a 8192000 (also common) crystal and a
prescaler value of 8.

8192000/4/8/256=1000

This will result in a 1ms interrupt.

If however you are turning your real time clock on and off, and need lots of
processing between interrupts, a more thorough analysis of timing should be
done and a method similar to the ones Mike suggested above should be used.

Very interesting discussion. Thanks!

Jerry

'16C84 interrupts'
1995\10\18@051518 by Matthew Rowe

flavicon
face
{Quote hidden}

Not loading the rtcc at all has resulted in the accuracy I need. It
is now at +5 secs in 15 hours. Much better. Thanks.

/\/\att.

'RTCC Finer Points [was Re: 16C84 Interrupts]'
1995\10\18@111844 by Jeff D. Pipkins

flavicon
face
There should be an app note about this.  Here's the straight scoop.

If you want the timer to interrupt you at a constant rate,
here's how it can be done.  I put this code in my timer ISR:


            movlw        timerpd-3
            subwf        TMR0

Where "timerpd" is a constant, and TMR0 is another word for rtcc.
Note that I'm using the OSC clock for the timer, and NOT the
external timer clock option.  I don't know exactly how that
would affect the timing.  Using the above strategy will cause
your code, in the isr, to execute once every "timerpd" instruction
cycles, as long as you don't disable interrupts in the main code.
Note that interrupt latency is not an issue!  The counter keeps
counting after it overflows, and the more interrupt latency,
the further it counts, but the constant is SUBTRACTED from the
current count, instead of just resetting the current count,
and then trying to fudge-factor the interrupt latency.

I've measured it on a logic analyzer (using a 16C84) and it's
right on the money every time.

It's important to note that I'm not using the prescaler.
As a couple of others pointed out, the prescaler gets cleared
during the subtraction above because the timer is written to.
The bottom line is, if you want to have a regular heartbeat
timer interrupt, you must not use the prescaler, or you must
not ever write to the timer.

Hope this helps,
--Jeff

Jeff Pipkins <spamBeGonePipkinsSTOPspamspamEraseMEbangate.compaq.com>  -------------------
Lead, Communications VP, Quartet Activities Chairman,
Lone Star Statesmen Barbershop Chorus
Opinions above are mine personally; use only at your own risk.

'16C84 interrupts'
1995\10\18@134706 by Andrew Warren

face
flavicon
face
Matthew Rowe <KILLspammattspamBeGonespamATLAS.KINGSTON.AC.UK> wrote:

>Not loading the rtcc at all has resulted in the accuracy I need. It
>is now at +5 secs in 15 hours. Much better. Thanks.

Matt:

I'm glad your problem is solved, but 5 seconds/15 hours is really WAY
short of the accuracy you SHOULD be getting.

5/(15*3600) is...  What?  10,000 parts per million?  Even the cheapest
crystals should be about 100 times more accurate than THAT.  Perhaps
your timing calculations are off...

-Andy

--
Andrew Warren - EraseMEfastfwdspamEraseMEix.netcom.com
Fast Forward Engineering, Vista, California

'RTCC Finer Points [was Re: 16C84 Interrupts]'
1995\10\18@174734 by Jerry Ethridge

flavicon
face
{Quote hidden}

This is OK but without using the prescaler, and the RTCC only having
8 bits, you are limited to something less than 256 cycles
between each interrupt. Of course if the only thing you are doing
is a very simple clock circuit, it would probably be fine. This method
would also be very tricky to use if you were using alot of different
interrupts. Although this thread has mainly been about the 16C84, have
you seen all the interrupt options in the 74's? My typical ISR would
take up a good chunk of my processing time if I were limited to less
than 256 cycles between heartbeats.

At least by using the prescaler, it gives you some breathing room to
do a few things before you are interrupted by your heartbeat. As Jeff
points out above, never write to RTCC when using the prescaler.

My own personal preference is to always use the prescaler and to never
modify the RTCC. I don't know why it was designed to clear the prescaler
when the RTCC has been modified. Real time clocks would be a breeze to
design with just about any crystal value and RTCC preload value if the
the prescaler were not cleared in this manner. Oh well, I'm not the
designer, just the guy that has to work around someone elses design :>)

Never satisfied-
Jerry

'16C84 interrupts'
1995\10\19@162948 by Shel Michaels

picon face
In a message dated 95-10-19 06:53:48 EDT, you write:

>Matthew Rowe <@spam@matt@spam@spamspam_OUTATLAS.KINGSTON.AC.UK> wrote:
>
>>Not loading the rtcc at all has resulted in the accuracy I need. It
>>is now at +5 secs in 15 hours. Much better. Thanks.
>
>Matt:
>
>I'm glad your problem is solved, but 5 seconds/15 hours is really WAY
>short of the accuracy you SHOULD be getting.
>
>5/(15*3600) is...  What?  10,000 parts per million?  Even the cheapest
>crystals should be about 100 times more accurate than THAT.  Perhaps
>your timing calculations are off...
>
>-Andy
>
>

Well, actually, 5 parts in 54000 is a little better than 1 part in 10^4,
which is about 100 parts-per-million, as you say!!   BTW, this has been an
interesting thread, thanx all!  8^)

Shel Michaels

'Nested Interrupts on PIC16C74?'
1995\10\19@182658 by John Loch

flavicon
face
Hello,

I am writing a I2C master transmit routine where I need to disable
interrupts for approximately 1 ms every 10 ms.  I am also incrementing a
counter for every state change on a port B pin with an interrupt service
routine.  If the port B pin changes state twice (3, 4, 5 times?) while the
interrupts are disabled during the 1 ms transmit, will the interrupts
become nested??  I can't afford to miss one of these port B interrupts.

Also if anyone has a better scheme to implement I2C master transmit, please
let me know.  Here is my pseudo-code algorithm:

on periodic-interrupt (once every 10 ms)
if I2C bus not busy
  disable-all-interrupts         /* so as not to screw up the timing of my
software delay loops */
  send start
  for each byte in queue
     send-byte-with-arbitration-check
  end for loop
  send stop
  enable-interrupts
end if

to send-byte-with-arbitration-check
  for each bit in byte (MSB first)
     clear-bit TRISC<3>                  /* pull the SCLK line low */
     if bit=1
        set-bit TRISC<4>                  /* set SDA line high */
        set arbitration-flag = 1        /* flag indicating arbitration
must be checked */
     else
        clear-bit TRISC<4>              /* set SDA line low */
        set arbitration-flag = 0        /* no need to check for
arbitration on this bit */
     end if
     delay-instructions                 /* do nothing instructions to
implement 5 us delay */

     set-bit TRISC<3>                   /* set SCLK line high (data valid) */
     if arbitration-flag = 1            /* check for bus contention */
        if PORTB<4> = 0                 /* another device has priority,
abort send */
           abort-send                      /* abort transmission and try
again later */
        end if
     end if
     delay-instructions               /* do nothing instructions to
implement 5 us delay */
  end for loop
  /* make sure slave acknowledges byte */
  set-bit TRISC<4>                     /* set SDA line high (tri-state) */
  clear-bit TRISC<3>                 /* pull the SCLK line low */
  delay-instructions                  /* do nothing instructions to
implement 5 us delay */
  set-bit TRISC<3>                   /* set SCLK line high */
  if PORTB<4> = 1                      /* slave didn't acknowledge */
     abort-send                            /* abort transmission and try
again later */
  end if
  delay-instructions                  /* do nothing instructions to
implement 5 us delay */
end send-byte-with-arbitration-check

Note: 5 us delay to implement 100 kbits/second I2C data rate

- John Loch
spamBeGonejohnlochspamKILLspammtt.com
The Source for Renewable Energy -
http://www.mtt.com/theSource/renewableEnergy

'16c84 interrupts'
1995\10\20@010643 by Andrew Warren

face
flavicon
face
Shel Michaels <.....Sbmichaelsspam_OUTspamAOL.COM> wrote:

>Well, actually, 5 parts in 54000 is a little better than 1 part in 10^4,
>which is about 100 parts-per-million [not 10,000 parts per million]

Thanks, Shel... Guess I need to take some remedial arithmetic classes.

-Andy


--
Andrew Warren - TakeThisOuTfastfwd.....spamTakeThisOuTix.netcom.com
Fast Forward Engineering, Vista, California

'Nested Interrupts on PIC16C74?'
1995\10\20@011507 by Andrew Warren

face
flavicon
face
John Loch <TakeThisOuTjohnlochKILLspamspamspamMTT.COM> wrote:

>I am writing a I2C master transmit routine where I need to disable
>interrupts for approximately 1 ms every 10 ms.  I am also incrementing a
>counter for every state change on a port B pin with an interrupt service
>routine.  If the port B pin changes state twice (3, 4, 5 times?) while the
>interrupts are disabled during the 1 ms transmit, will the interrupts
>become nested??  I can't afford to miss one of these port B interrupts.
>
>Also if anyone has a better scheme to implement I2C master transmit, please
>let me know.

John:

The PIC will set the interrupt flag on the FIRST change-on-portB interrupt
that happens while interrupts are disabled, but it won't tell you if any
more occurred.  With the change-on-portb interrupts, you could store the
state of the portb pins at each interrupt, then compare the value stored at
the last interrupt to the value of the pins during the current interrupt,
thereby making it possible to tell whether TWO interrupts had occurred, but
there's no way you'll ever be able to tell when three or more happened.

Unless you really need the fastest possible I2C transmit rate, why not leave
interrupts enabled?  The 5-microsecond delays are the MINIMUM allowable; if
you stretch them out (to hours, even), nothing bad will happen.

-Andy

--
Andrew Warren - .....fastfwdspamRemoveMEix.netcom.com
Fast Forward Engineering, Vista, California

'More fun with 16CXX interrupts'
1995\10\20@045756 by att%atlas.king.ac.uk%UKACRL.bitnet

flavicon
face
> Was Subject:        Re: Nested Interrupts on PIC16C74?

> >I am also incrementing a counter for every state change on a port B
> >pin with an interrupt service routine.
> >If the port B pin changes state twice (3, 4, 5 times?) while the
> >interrupts are disabled during the 1 ms transmit, will the interrupts
> >become nested??  I can't afford to miss one of these port B interrupts.

I'm trying to do something along these lines. I have the timer
generating interrupts continually with rtcc rollover for a real time
clock. As well as this, I'm trying to use the portB int-on-change
interrupts which work on their own but when both are enabled, the
thing hangs. Is interrupt nesting crashing the stack or destroying my
push-pop register stores or what?

The end result I'd like to achieve is two slow serial ports on which
the int-on-portB event starts some counters (updated by timer0 for
accuracy) for each input and decodes the serial data after that.
Am I going to have to resort to polling portB?

This stuff is getting far too exciting!

/\/\att.

1995\10\20@051455 by Andrew Warren

face
flavicon
face
Matthew Rowe <matt%RemoveMEatlas.king.ac.ukspamspamBeGoneUKACRL.BITNET> wrote:

>I'm trying to do something along these lines. I have the timer
>generating interrupts continually with rtcc rollover for a real time
>clock. As well as this, I'm trying to use the portB int-on-change
>interrupts which work on their own but when both are enabled, the
>thing hangs. Is interrupt nesting crashing the stack or destroying my
>push-pop register stores or what?

Matt:

Interrupts don't "nest", they "stack".  That is, unless you explicitly
enable interrupts in your interrupt-service routine, the ISR WILL NOT
be interrupted.  If an interrupt condition occurs while the PIC is
executing the interrupt-service routine, all that'll happen is that the
corresponding Interrupt Flag will be set.  Then, when your ISR finishes
executing and RETFIEs, that pending interrupt flag will immediately
cause a jump to the start of the ISR again.

Make sure that your ISR doesn't enable interrupts; remember that RETFIE
re-enables them automatically.  Also, make sure that your ISR clears
the appropriate interrupt flags; if it doesn't, and that flag is still
set when you reach the RETFIE, it will cause an immediate jump back to
the start of the ISR.

-Andy

--
Andrew Warren - spamBeGonefastfwd@spam@spamspam_OUTix.netcom.com
Fast Forward Engineering, Vista, California

'RTCC INTERRUPT AND SLEEP'
1995\10\25@213841 by doug r. boulware

flavicon
face
The Parallax simulator shows that a PIC16C84 will awaken from sleep by
an RTCC overflow interrupt that is triggered from the RA4/RTCC input
pin.

I have not found any documentation that confirms this, and cannot seem
to get it to occur on the actual chip.  I am attempting to awaken the
chip when a start bit from an RS232 serial input is detected.  The
serial input routine is interrupt driven from the RTCC and works fine
without the sleep instruction.

Can this be done ?

Regards,

Doug Boulware <TakeThisOuTdougrbspamspamfree.org>

* RM 1.3  *

1995\10\26@021450 by divanov

flavicon
face
... snip snip ...

> The serial input routine is interrupt driven from the RTCC and works fine
> without the sleep instruction.

The sleep instruction effectively stops the oscillator. You can
wake up the PIC by means of external interrupt, but your timing will
obviously be incorrect.

> Can this be done ?

I don't see any reasonable way to implement RS232 using the sleep
instruction. Please, correct me someone if I'm wrong.

Cheers,

RI

1995\10\26@043037 by Andrew Warren

face
flavicon
face
Doug R. Boulware <dougrbEraseMEspamSQUEAKY.FREE.ORG> wrote:
>
>The Parallax simulator shows that a PIC16C84 will awaken from sleep by
>an RTCC overflow interrupt that is triggered from the RA4/RTCC input
>pin.
>
>I have not found any documentation that confirms this, and cannot seem
>to get it to occur on the actual chip.  I am attempting to awaken the
>chip when a start bit from an RS232 serial input is detected.  The
>serial input routine is interrupt driven from the RTCC and works fine
>without the sleep instruction.
>
>Can this be done ?

Doug:

Sure, but contrary to what that substandard simulator shows, it can't
be done with only the RTCC pin.  Check out section 8.8.1, "Wake-Up from
Sleep", in the 16C84 Data Sheet; the only events which can wake up the
PIC are:

   External reset input on MCLR
   WDT timeout reset
   Interrupt from RB0/INT, PortB-change, or data EEPROM write-complete

Yuo might also want to take a look at Section 6.1, "TIMER0 (TMR0)
INTERRUPT", which says, in so many words, "The TMR0 module interrupt
cannot wake the processor from SLEEP...."

If your RB0 pin is available, I'd tie it to the RA4/RTCC pin and
configure the RB0 interrupt to occur when it sees the start bit.

That'll wake up the PIC; once awake, you can disable the RB0 interrupt
during the reception (so you don't get repeated RB0 interrupts), then
re-enable it just before you go to sleep.

-Andy

--
Andrew Warren - RemoveMEfastfwdEraseMEspamspam_OUTix.netcom.com
Fast Forward Engineering, Vista, California

'PSIM 'bug list' ? (was:Re: RTCC INTERRUPT AND SLEE'
1995\10\26@051307 by Markus Imhof

flavicon
face
...
>Sure, but contrary to what that substandard simulator shows, it can't
....
BTW, is there somewhere a list of differences between the simulator and the
real part (w/ respect to the '84, mainly) ? I just noticed one other 'bug':
The sim won't preload the EEPROM memory - definitely a drawback if you want
to use this memory to initialize a few random numbers.

Bye
 Markus

'16C84 interrupts'
1995\10\26@112544 by Martin McCormick

flavicon
face
In message <@spam@m0t5fOu-0000nZCRemoveMEspamEraseMEdc.cis.okstate.edu>, Andrew Warren writes:
>I'm glad your problem is solved, but 5 seconds/15 hours is really WAY
>short of the accuracy you SHOULD be getting.
>
>5/(15*3600) is...  What?  10,000 parts per million?  Even the cheapest
>crystals should be about 100 times more accurate than THAT.  Perhaps
>your timing calculations are off...

       You might also want to be absolutely certain that the crystal is
on frequency.  I have seen clock crystals supposedly cut for 8Mhz that were
several kilohertz off.  The mode of the crystal is also very important.
Some crystals are cut for series mode operation and others for parallel.
An NTSC color burst crystal is cut for 3.57945Mhz but will run at 3.68Mhz
or so when put in a TTL clock circuit.

       One nice thing about microcontrollers is that you could just slightly
recalculate the divisors for time-dependent operations providing the crystal
doesn't drift a lot with temperature.  I guess you could even put leap ticks
in the timing routine to tweak it a little.  I think that this is what
UNIX systems do to speed up or slow down their real-time clocks.

Martin McCormick WB5AGZ  Stillwater, OK 36.7N97.4W
OSU Center for Computing and Information Services Data Communications Group

'RTCC INTERRUPT AND SLEEP'
1995\10\26@123540 by Mike Keitz

flavicon
face
>Yuo might also want to take a look at Section 6.1, "TIMER0 (TMR0)
>INTERRUPT", which says, in so many words, "The TMR0 module interrupt
>cannot wake the processor from SLEEP...."

To expand on that, the RTCC doesn't work at all during sleep, as the
synchronizer is driven by the internal PIC clock.  The prescaler (if
enabled) probably does continue to count, but the main register won't.

>If your RB0 pin is available, I'd tie it to the RA4/RTCC pin and
>configure the RB0 interrupt to occur when it sees the start bit.
>
There's really no need to use two pins, you could take all input through a
port B pin, and use the RTCC with internal clock to time the bits and cause
interrupts at the correct sample times.  Or, if the PIC has nothing to do
until it gets some more serial data, an ordinary software-timed receiver may
be all that's required.  At high baud rates, the (uncertain) time required
to re-start the oscillator may make it difficult to know where the center of
the start bit (that woke up the PIC) was and sample at the right time.
Sending a 'don't care' byte to wake up the PIC, then immediately following
it with real data may be a way around that.

-Mike

1995\10\27@234843 by doug r. boulware

flavicon
face
I wrote:

DB>The Parallax simulator shows that a PIC16C84 will awaken from sleep by
DB>an RTCC overflow interrupt that is triggered from the RA4/RTCC input
DB>pin.
DB>
DB>I have not found any documentation that confirms this, and cannot seem
DB>to get it to occur on the actual chip.  I am attempting to awaken the
DB>chip when a start bit from an RS232 serial input is detected.  The
DB>serial input routine is interrupt driven from the RTCC and works fine
DB>without the sleep instruction.

Andrew Warren replied:

AW>Sure, but contrary to what that substandard simulator shows, it can't
AW>be done with only the RTCC pin.  Check out section 8.8.1, "Wake-Up from
AW>Sleep", in the 16C84 Data Sheet; the only events which can wake up the
AW>PIC are:

AW>    External reset input on MCLR
AW>    WDT timeout reset
AW>    Interrupt from RB0/INT, PortB-change, or data EEPROM write-complete

AW>Yuo might also want to take a look at Section 6.1, "TIMER0 (TMR0)
AW>INTERRUPT", which says, in so many words, "The TMR0 module interrupt
AW>cannot wake the processor from SLEEP...."

AW>If your RB0 pin is available, I'd tie it to the RA4/RTCC pin and
AW>configure the RB0 interrupt to occur when it sees the start bit.

Thanks.  You confirmed my suspicion that the simulator is wrong.  Not
that its the first bug I've come across.  In case it's not general
knowledge, the Parallax simulator also does not handle the port B change
interrupt correctly.  The v2.42 I have will continually interrupt as long
as any of the respective port B pins are high.

I was trying to keep port B open for general I/O and use port A for
serial comm and interface to a National Semi 0831 serial A/D converter.
I'm playing around with a "Remote I/O" system that I communicate with
serially, similar to the "Stamp Expander" that Parallax sells, only
using the '84.

I have yet to get the Microchip simulator. Is it better than
Parallax's ?

Regards,

Doug Boulware <EraseMEdougrbspam@spam@free.org>

* RM 1.3  *

1995\10\28@014740 by Andrew Warren

face
flavicon
face
Doug R. Boulware <@spam@dougrbspam_OUTspam.....SQUEAKY.FREE.ORG> wrote:

>You confirmed my suspicion that the simulator is wrong.  Not that its the
>first bug I've come across.  In case it's not general knowledge, the
>Parallax simulator also does not handle the port B change interrupt
>correctly.  The v2.42 I have will continually interrupt as long as any of
>the respective port B pins are high.
> ....
>I have yet to get the Microchip simulator. Is it better than Parallax's ?

   Doug:

   Depends on what you mean by "better".  If you mean "does it properly
   emulate the PICs' operation", "does it support EVERY SINGLE PIC that
   Microchip makes", "does Microchip promptly fix whatever minor bugs DO
   creep in", or "does it allow source-level debugging of code written for
   Microchip's MPASM assembler", or even "was it written by a chick", the
   answer is YES.

   If you mean, "does it have a user-friendly interface", the answer is NO,
   NOT YET.  By April, 1996, though, Microchip's simulator will be fully
   integrated into MPLAB, the new interface for Microchip's Windows-based
   PIC-MASTER emulator.

   -Andy

--
Andrew Warren - spamBeGonefastfwdEraseMEspamix.netcom.com
Fast Forward Engineering, Vista, California


'PIC16C84 & PortB interrupt'
1995\11\10@043916 by SONY-OD
flavicon
face
I try to use a PIC16C84 and I get MICROCHIP documentation. There is something
strange:

 PortB can generate INTERRUPT when there is change on RB.4..7, the
documentation said: these pins are sampled on the Q1 cycle of read.
The new input is compared with old latched value in every instruction cycle.

HOW IT IS possible an interrupt occurs if portB is latched only on a READ
instruction ?
Does this means that it's neccessary to read PORTB every time to generate
an interrupt ?
MICROCHIP Doc. said: PortB can generate instruction in SLEEP mode, HOW it
is possible if portB is latched only on a read ?

Is it a mistake of the MICROCHIP doc. ?

Someone can help me please,

       Philippe <sonyedespamBeGonespamiway.fr>

1995\11\10@112247 by Mike Keitz

flavicon
face
>I try to use a PIC16C84 and I get MICROCHIP documentation. There is something
>strange:
>
>  PortB can generate INTERRUPT when there is change on RB.4..7, the
>documentation said: these pins are sampled on the Q1 cycle of read.
>The new input is compared with old latched value in every instruction cycle.
>
>HOW IT IS possible an interrupt occurs if portB is latched only on a READ
>instruction ?

When the port is read by the program, the interrupt-compare latch is reset
to agree with the present state of the port inputs.  Thus the interrupt
condition goes away then until a pin changes (actually, I think the RBIF
flag needs to be manually reset as well).  In other words, the read resets
the compare function so a further change is required.  The sampling is done
on every instruction cycle.  If the sample doesn't agree with the latched
value (last value read), the RBIF flag is set, which causes an interrupt if
RBIE and GIE are also set.

>Does this means that it's neccessary to read PORTB every time to generate
>an interrupt ?

No.  It is only necessary to read port B once while the external hardware is
in the 'non-interrupt' state (this defines what the state is), then clear
RBIF, and set RBIE and GIE.  The next change of one of the B4-B7 pins will
generate an interrupt.  Before leaving the interrupt routine, be sure that
the port and the latch agree with each other (by doing a read) and the RBIF
is clear so another interrupt won't occur immediately.

>MICROCHIP Doc. said: PortB can generate instruction in SLEEP mode, HOW it
>is possible if portB is latched only on a read ?

The latch is one input of the compare, the pin state is the other.  The
value in the latch is held during sleep from the last value read while the
CPU was running.  The path from the pins through to the comparators is
apparently held open during sleep.

>Is it a mistake of the MICROCHIP doc. ?

The system as it is described in the doc seems to make sense to me, though
their description isn't real clear.  I'm not sure why the convoluted
implementation of latching twice, it seems that a one-cycle pipeline
(generating a pulse each time a pin were different from the last cycle)
would have worked just as well if the RBIF indeed has its own latch.

-Mike

1995\11\10@130911 by Conny Andersson

flavicon
face
At 10.36 1995-11-10 +0100, Philippe wrote:

>  PortB can generate INTERRUPT when there is change on RB.4..7, the
>documentation said: these pins are sampled on the Q1 cycle of read.
>The new input is compared with old latched value in every instruction cycle.
>
>HOW IT IS possible an interrupt occurs if portB is latched only on a READ
>instruction ?

Easy! The pins are sampled AND put in the portB register by the
MOVF/SWAPF/... instructions BUT they are also "sampled" by the interrupt
logic - two separate sample-circuits. The actual data on the pins are not
nescessarily the same as the actual data in the register.


-- Conny

1995\11\11@061235 by adrian

flavicon
picon face
On the topic of the port B int on a 16C84...

Would I be right in thinking that setting or clearing B0-3 using bit
operations would mean a port read and write and hence clear any pending
interrupt for B4-7 change ?

The way I read it, I cannot use B0-3 for any I/O without risking loss of a
pending B4-7 change interrupt, which meant is was useful for getting out of
sleep but not much else.

Did I miss read the spec, or is this how it works ?

--
_
(_) _| _ . _  _   Tel +44 973 222257
( )(_|(  |(_|| )  Fax UK 0500 222258                    E&OE

1995\11\11@182557 by Andrew Warren

face
flavicon
face
Adrian Kennard <RemoveMEadrian@spam@spamspamBeGoneRHANNA.DEMON.CO.UK> wrote:

>On the topic of the port B int on a 16C84...
>
>Would I be right in thinking that setting or clearing B0-3 using bit
>operations would mean a port read and write and hence clear any pending
>interrupt for B4-7 change ?

   Adrian:

   No.  Interrupts set the RBIF flag; once set, that flag will trigger a
   jump to the interrupt vector as soon as its enable flag (RBIE) and GIE
   are both set.

   However...

   There's a major flaw in the Change-on-Port-B Interrupt logic.  If you
   read from Port B at the same instant that a change on RB4-7 occurs, the
   RBIF flag will NOT be set.  BSF/BCF instructions perform a read, of
   course, so if you ever do BCFs, BSFs, or any other Port-B read operation,
   you can pretty much forget about using the Change-on-Port-B interrupt.

   -Andy

--
Andrew Warren - .....fastfwd@spam@spamEraseMEix.netcom.com
Fast Forward Engineering, Vista, California

1995\11\13@115230 by John Payson

flavicon
face
>     There's a major flaw in the Change-on-Port-B Interrupt logic.  If you
>     read from Port B at the same instant that a change on RB4-7 occurs, the
>     RBIF flag will NOT be set.  BSF/BCF instructions perform a read, of
>     course, so if you ever do BCFs, BSFs, or any other Port-B read operation,
>     you can pretty much forget about using the Change-on-Port-B interrupt.

Does MOVWF perform a read-before-write? [I realize, of course, that if it
did so it would ignore the value read, but it's probably easier to have the
hardware do the read for all of the ALU-freg ops].  What about CLRW?  Does
that read [IND] if the 7 lsb's of opcode are zero?  Would changing the 7
LSB's to something else cause that something else to be read [hopefully
harmlessly] instead?

1995\11\13@123306 by Mike Keitz

flavicon
face
>What about CLRW?  Does
>that read [IND] if the 7 lsb's of opcode are zero?  Would changing the 7
>LSB's to something else cause that something else to be read [hopefully
>harmlessly] instead?

An interesting question, if it exists this side effect could be useful for
something (not sure what yet).  If the possible extra read could be a
problem, you could replace CLRW with ANDLW 0 (exactly the same effect as
CLRW; W=0 and Z flag =1) or of course MOVLW 0 (W=0, but Z unchanged) instead
and forget about the CLRW "instruction" (as you've noticed, it's actually
coded as CLRF x,w) altogether.

-Mike

1995\11\13@150424 by Andrew Warren

face
flavicon
face
John Payson <.....supercatRemoveMEspamMCS.COM> wrote:

>Does MOVWF perform a read-before-write?

   No.

>What about CLRW?  Does that read [IND] if the 7 lsb's of opcode are zero?

   No, but why not just use MOVLW 0 (if you don't want the Z flag to be
   affected) or ANDLW 0 (if you do)?

   -Andy

--
Andrew Warren - .....fastfwdSTOPspamspam@spam@ix.netcom.com
Fast Forward Engineering, Vista, California

1995\11\13@190107 by John Payson

flavicon
face
> >What about CLRW?  Does
> >that read [IND] if the 7 lsb's of opcode are zero?  Would changing the 7
> >LSB's to something else cause that something else to be read [hopefully
> >harmlessly] instead?
>
> An interesting question, if it exists this side effect could be useful for
> something (not sure what yet).  If the possible extra read could be a
> problem, you could replace CLRW with ANDLW 0 (exactly the same effect as
> CLRW; W=0 and Z flag =1) or of course MOVLW 0 (W=0, but Z unchanged) instead
> and forget about the CLRW "instruction" (as you've noticed, it's actually
> coded as CLRF x,w) altogether.

I was just realizing that, because of the existence of writable registers
in the 16Cxx (though not 16C5x) which are altered by reading, MOVWF has to
be an oddball instruction; on the 16Cxx, almost all of the instructions whose
first two bits are "00" fit the following formula:
 read F-register selected by OP0-6
 take that and W; compute a value and flags [incl. "skip" flag] using the
   operation specified by OP8-12
 store the result in W if OP7 is 0, or back in the F resister if OP7 is 1

The only exceptions are:
 movwf
 nop
 clrwdt
 retfie
 return
 sleep
 tris
 option

Note that were it not for the existence of read-modified registers, even
these instructions could be executed with the above formula provided that
something else was "also" done [except for MOVWF, all of them would decode
as "take W and some F-register, then store W into W].  I wonder if that's
how they are in fact decoded on the 16C5x?

PS--Does anyone know how the TRIS and OPTION instructions are decoded?  I'd
like to be able to access EECTL and EEDATA without having to muss around
with bank-switching on the 16C84.

1995\11\23@023010 by Dan Matthews

picon face
Sorry Andy,

I hate to correct you when you are 99.9% right, but...

In the PIC16CXX architecture EVERY instruction that accesses a register
performs a read first, for the exact reason mentioned, simplification of design.

In this case, a MOVWF to PORTB during what would be a change on PORTB
interrupt will in fact clear the interrupt condition.

       best regards,

               Dan Matthews

At 12:03 PM 11/13/95 -0800, you wrote:
{Quote hidden}

1995\11\23@133253 by Andrew Warren

flavicon
face
Dan Matthews <spamBeGonedmatthewKILLspamspam@spam@primenet.com> wrote:

> I hate to correct you when you are 99.9% right, but...
>
> In the PIC16CXX architecture EVERY instruction that accesses a
> register performs a read first, for the exact reason mentioned,
> simplification of design.
>
> In this case, a MOVWF to PORTB during what would be a change on
> PORTB interrupt will in fact clear the interrupt condition.

Thanks, Dan...  My message to John Payson was just the singlw word,
"no", so I guess the portion that was "99.9% right" was the
list's mail address, his quoted question, and my signature.

It was bad enough when only instructions that performed an EXPLICIT
read or read-modify-write kept the interrupt from happening... This
new information makes the change-on-portB interrupt almost
COMPLETELY worthless.  Does Microchip see this as a bug and plan to
correct it in future revs of the chip?

-Andy


Andrew Warren - fastfwdspam_OUTspam@spam@ix.netcom.com
Fast Forward Engineering, Vista, California

1995\11\23@232947 by Dan Matthews

picon face
Actually, the "99.9% correct" was in reference to your many other extensive
replies found here and on the BBS.

       Best regards,

               Dan Matthews

At 10:30 AM 11/23/95 -0800, you wrote:
{Quote hidden}

1995\11\24@013644 by Martin J. Maney

flavicon
face
On Thu, 23 Nov 1995, Andrew Warren wrote:

> It was bad enough when only instructions that performed an EXPLICIT
> read or read-modify-write kept the interrupt from happening... This
> new information makes the change-on-portB interrupt almost
> COMPLETELY worthless.  Does Microchip see this as a bug and plan to
> correct it in future revs of the chip?

I have no connection with Microchip other than that I'm designing a 16C73
into a product currently being prototyped, but I believe I can predict
the answer.  They will say "no".  The data sheet has always [always = in
the 1994 and 1995/1996 books] implied that this feature was intended for
use in applications where the input change is used to wake the chip from
a sleep state, and of course when the chip is sleeping it won't be
reading or writing the port B pins and disturbing the change sensing...

There's even an application note that demonstrates exactly this use,
isn't there?

So I believe that this is _exactly_ the operation that Microchip designed
into those pins on port B, and the bug is only that you wish they worked
otherwise than they do.  The 1995/1996 databook is pretty explicit about
this:  "the interrupt on change feature is reccomended for wake-up on key
depression operation and operations where port B is used only for the
interrupt on change feature."  I think they could allow as well
applications where bit 0 is used as an external interrupt input (for
non-sleeping applications).

1995\11\28@121907 by BBoles

flavicon
face
    Actually, we understand this as a bug and it is being fixed in all new
    devices including upcoming 'A' versions of '74, '73, '65, '64 , etc.

    Rgds, Brian.


______________________________ Reply Separator _________________________________
Subject: Re: PIC16C84 & PortB interrupt
Author:  "Martin J. Maney" <spamBeGonemaneyspam_OUTspamRemoveMEMCS.COM> at Internet_Exchange
Date:    11/24/95 12:34 AM


On Thu, 23 Nov 1995, Andrew Warren wrote:

> It was bad enough when only instructions that performed an EXPLICIT
> read or read-modify-write kept the interrupt from happening... This
> new information makes the change-on-portB interrupt almost
> COMPLETELY worthless.  Does Microchip see this as a bug and plan to
> correct it in future revs of the chip?

I have no connection with Microchip other than that I'm designing a 16C73
into a product currently being prototyped, but I believe I can predict
the answer.  They will say "no".  The data sheet has always [always = in
the 1994 and 1995/1996 books] implied that this feature was intended for
use in applications where the input change is used to wake the chip from
a sleep state, and of course when the chip is sleeping it won't be
reading or writing the port B pins and disturbing the change sensing...

There's even an application note that demonstrates exactly this use,
isn't there?

So I believe that this is _exactly_ the operation that Microchip designed
into those pins on port B, and the bug is only that you wish they worked
otherwise than they do.  The 1995/1996 databook is pretty explicit about
this:  "the interrupt on change feature is reccomended for wake-up on key
depression operation and operations where port B is used only for the
interrupt on change feature."  I think they could allow as well
applications where bit 0 is used as an external interrupt input (for
non-sleeping applications).


'Re[2]: PIC16C84 & PortB interrupt'
1995\12\01@112214 by John Payson
flavicon
face
> On Thu, 23 Nov 1995, Andrew Warren wrote:
>
> > It was bad enough when only instructions that performed an EXPLICIT
> > read or read-modify-write kept the interrupt from happening... This
> > new information makes the change-on-portB interrupt almost
> > COMPLETELY worthless.  Does Microchip see this as a bug and plan to
> > correct it in future revs of the chip?

[bboles replied]
>
>      Actually, we understand this as a bug and it is being fixed in all new
>      devices including upcoming 'A' versions of '74, '73, '65, '64 , etc.
>
>      Rgds, Brian.

What precisely is Microchip fixing in the 'A' versions?  Most of the quirks
I can see with the PortB behavior (and read-modify-write in general) are
things that a "clever programmer" might exploit in some way.

Also, what is the specific behavior of the register read logic?  Does it
do the read for any opcode whose top six bits are not "00 0000", or does
it read regardless?  If the latter, does this cause any potential problems
with serial I/O on the '74 [since reading the input latch clears it, and
the output latch shares the input latch's address]?

PS--Personally, my preferred implementation for an "interrupt-on-change"
pin feature would be to have the interrupt triggered if/when the signal on
the port pin does not match the output latch.  This could then be easily
cleared either by "movf port,f" or by most read-modify-write operations on
the port.

1995\12\01@173239 by BBoles

flavicon
face
    Without getting into a lot of detail on what is different on 'A'
    parts, the PortB is fixed such that it will work as described in the
    datasheet.  We did think about a interrupt on change that would work
    relative to the output port, but that would be a spec change.

    The device does a read for any instruction cycle except literals.
    This wasn't a problem except on the 74/64 with IBF flag in TRISE.
    Here a RETURN (000Dh) instruction would read PORTD and clear the IBF
    flag. Oops!  There isn't an instruction that can accidentally hit
    SSPBUF.

    P.S. also fixed on Rev. A.

    Rgds, Brian.


______________________________ Reply Separator _________________________________
Subject: Re: Re[2]: PIC16C84 & PortB interrupt
Author:  John Payson <.....supercatspamRemoveMEMCS.COM> at Internet_Exchange
Date:    12/1/95 10:20 AM


> On Thu, 23 Nov 1995, Andrew Warren wrote:
>
> > It was bad enough when only instructions that performed an EXPLICIT
> > read or read-modify-write kept the interrupt from happening... This
> > new information makes the change-on-portB interrupt almost
> > COMPLETELY worthless.  Does Microchip see this as a bug and plan to
> > correct it in future revs of the chip?

[bboles replied]
>
>      Actually, we understand this as a bug and it is being fixed in all new
>      devices including upcoming 'A' versions of '74, '73, '65, '64 , etc.
>
>      Rgds, Brian.

What precisely is Microchip fixing in the 'A' versions?  Most of the quirks
I can see with the PortB behavior (and read-modify-write in general) are
things that a "clever programmer" might exploit in some way.

Also, what is the specific behavior of the register read logic?  Does it
do the read for any opcode whose top six bits are not "00 0000", or does
it read regardless?  If the latter, does this cause any potential problems
with serial I/O on the '74 [since reading the input latch clears it, and
the output latch shares the input latch's address]?

PS--Personally, my preferred implementation for an "interrupt-on-change"
pin feature would be to have the interrupt triggered if/when the signal on
the port pin does not match the output latch.  This could then be easily
cleared either by "movf port,f" or by most read-modify-write operations on
the port.


'!!portB interrupts still a problem'
1996\03\13@071346 by Moshe Fish
flavicon
face
On Tue, 12 Mar 1996 12:22:46 -0800  Scott Dattalo wrote:
>
>The code looks O.K.  Perhaps there is another, simpler problem. For example, do
you know if your
>'65 is running? Are you using an in-circuit emulator? If not, are you sure the
part is getting
>programmed correctly? When you use the scope to look at the signal, do you have
a storage
>oscilloscope? If not, you'll never see anything unless you use the Port A
output as the trigger
>source; in which case you'll at best see a faint trace across the screen.
>
>Suggestions
>1) Verify your test set up is functional. The easiest way I can think is to
create two versions of
>your code: the first outputs a logic 1 to port A<0> and the second a logic 0.
If they both perform
>the same then hmmm....
>
>2) Instead of pulsing port A, why not toggle it? This way, you can at least see
the current
>state with a DMM if you want.
>
>
>Without more info, this is the best I can do.
>
>Hope this helps
>
>Scott
>
Hi Scott
Thanks for replying
I have tried to take the same code (to which I added a GIE) and delete all parts
of the code which relate to port B and the other ports leaving only Port A
setup and the test. The code works perfectly and I can see it on the scope
(which by the way is a Tektronix digital scope). This leads me to believe at
this stage that somewhere in the portB setup there is something that is
affecting port A. By the way the simulator (I do not have an emulator) shows it
working fine on the code with the portB interrupts.
I still remain mystified although I am sure that when I discover what it is I
will fell like an idiot.
Moshe
PS anyone else out there got any suggestions?
-------------------------------------
Name   :Moshe Fish
E-mail :mfishspam@spam@netvision.net.il
Date   :03/13/96
Time   :14:15:28

'!!Need help on portB interrupts'
1996\03\13@092116 by Derrick Early

flavicon
picon face
Try running your code through picsim first with a stimulus file.  Once
you get your code working there, you'll have a better chance on the chip.

One word of caution, the simulator doesn't always act like the chip, but
it is the next best thing.

Yours,
--
Derrick Early
EraseMEearlyRemoveMEspamSTOPspamfinite.nrl.navy.mil

'!!Port B interrupt-latest'
1996\03\13@110112 by Moshe Fish

flavicon
face
The saga continues....
I seem to have narrowed down the problem to the point where I load the TRISB
register with a value. When I took out all the port B setup commands I got
pulses out port A the moment I put in  MOVLW  B'11111111'
                               MOVWF  TRISB
I stopped getting out pulses.First I was getting pulses out of portB itself even
though it was just defined as an i/p port and then when I tried the chip a few
minutes later I actually got pulses out of RA3 but none of the other port A
pins and port b is sitting at Vcc with a small 'digital ripple' of pulses on
top. I decided to try load 11110000 into TRISB but that killed everything-both
ports are now 0.I checked the board and there are no connecting tracks.I have
MCLR connected directly to Vcc and even tried resetting through a resistor to
ground but to no avail. Would it help to tie all the other port pins to Vcc or
Vdd. They are set as o/p?
Thanks to anyone who has still got patience for me

-------------------------------------
Name   :Moshe Fish
E-mail :RemoveMEmfishKILLspamspamTakeThisOuTnetvision.net.il
Date   :03/13/96
Time   :18:03:41

'!!Need help on portB interrupts'
1996\03\13@132230 by Kevin Rhoades (X4869)

flavicon
face
At 03:08 PM 3/12/96 PST, you wrote:
>Is there anyone out there who can help me?
>I have just started working with PIC's and am currently testing the '65 to get
> to know it. I am trying to run a very simple program that puts out a pulse on
> portA everytime a change on interrupt occurs on portB<4:7>....
-----snip--8<---
{Quote hidden}

---Snip---8<----------

>-------------------------------------
>Name   :Moshe Fish
>E-mail :spamBeGonemfishspam@spam@netvision.net.il
>Date   :03/12/96
>Time   :14:14:15
>
>

It looks to me as though you are entering an endless loop here.
I believe the GOTO LOOP needs to be on a line ABOVE where the LOOP code begins.
Maybe?

Best of luck...K.R...

'!!portB interrupts still a problem'
1996\03\13@170445 by Scott Dattalo

face
flavicon
face
Moshe Fish wrote:
>
> I have tried to take the same code (to which I added a GIE) and delete all
parts
>  of the code which relate to port B and the other ports leaving only Port A
>  setup and the test. The code works perfectly and I can see it on the scope
>  (which by the way is a Tektronix digital scope).

Hard to go wrong there...

>                                          This leads me to believe at
>  this stage that somewhere in the portB setup there is something that is
>  affecting port A. By the way the simulator (I do not have an emulator) shows
it
>  working fine on the code with the portB interrupts.

Here are a few more ideas. 1) Are you certain that your pic include
file P16C65.INC is O.K.? Specifically, it's possible that your PORT B
definitions
may be fubarred. 2) Have you tried another target PIC16C65? Maybe you have a bad
chip. 3) Where in your code did you enable GIE? Since the interrupt routine does
not save the STATUS register and reinitialize it for its on use, there's a
chance
that RP0 is in the wrong state when the interrupt occurs. Consequently, your
write
to PORTB would instead be going to TRISB; ditto for the PORTA write. This could
change the PORTB inputs to outputs!


> I still remain mystified although I am sure that when I discover what
> it is I will fell like an idiot..............->feel? or fail?

That's O.K. all idiots eventually fell (fail). However, I'm sure your no idiot!

Scott

'!!Port B interrupt-most latest'
1996\03\14@074602 by Moshe Fish

flavicon
face
>Moshe,
>I had a fairly large backlog of e-mail messages before I got to this one.
However,
>I bet you a buck (US) that suggestion 3 in my latest e-mail to the LIST will
fix
>your problem. Well, hang on a second. Maybe I should see your latest code
before
>making any wagers! Where in your code are you enabling the GIE bit?
>
>Scott
>
Scott
Here is my latest code version A-this works, i.e gives me the test pulses on
portA, NOTICE the parts that I have cut out (;)

               list P=16c65, f=inhx8m

               INCLUDE <P16C65.INC>

               ORG     0
               GOTO    START

;               ORG     4
;               GOTO    PULSE_CHECK     ;interrupt service vector

               ORG     0x10

START           CALL    INITPORTS



TEST            NOP
               NOP
               NOP
               MOVLW   B'00001111'     ;set pin hi-led on if to Vdd
               MOVWF   PORTA
               NOP
               NOP
               NOP
               NOP
               NOP
               NOP
               NOP
               NOP
               MOVLW   B'00000000'     ;set pin lo-led off if to Vdd
               MOVWF   PORTA
               NOP
               NOP
               MOVLW   B'00001111'     ;set pin hi-led on if to Vdd
               MOVWF   PORTA
               NOP
               NOP
               NOP
               NOP
               NOP
               NOP
               NOP
               NOP
               MOVLW   B'00000000'     ;set pin lo-led off if to Vdd
               MOVWF   PORTA


LOOP            GOTO TEST

PULSE_CHECK     BTFSS   INTCON,RBIF     ;PortB interrupt?
               GOTO    MAIN            ;If no int goto main
               MOVLW   B'00001111'     ;if interrupt
               MOVWF   PORTA           ;set pins hi-led on if to Vdd

CLR_RBINTF
               MOVF    PORTB,1         ;end mismatch-read portb to itself
               BCF     INTCON,RBIF     ;clear RB interrupt flag
               MOVLW   B'00000000'     ;set pins lo again-led off if to Vdd
               MOVWF   PORTA
               RETFIE

MAIN            RETFIE

INITPORTS       BSF     STATUS,RP0      ;select bank 1
               CLRF    TRISA           ;set all to o/p-lower power consump
;               MOVLW   B'1111111'      ;set portB<4:7> as i/p <0:3>o/p
;               MOVWF   TRISB
               CLRF    TRISC           ;set all to o/p-lower power consump
               CLRF    TRISD           ;set all to o/p-lower power consump
               CLRF    TRISE           ;set all to o/p-lower power consump
;               BCF     OPTION_REG,NOT_RBPU     ;enable pullup

               BCF     STATUS,RP0      ;select bank 0
               CLRF    PORTA           ;portA all low
               CLRF    PORTB           ;init portB
               CLRF    PORTC           ;portC all low
               CLRF    PORTD           ;portD all low
               CLRF    PORTE           ;portE all low
;               BCF     INTCON,RBIE     ;disable mask
;               MOVF    PORTB,W         ;read port
;               BCF     INTCON,RBIF     ;clear RB port interrupt change flag
;               BSF     INTCON,RBIE     ;enable RBIF interrupt
               RETFIE                  ;enable global and return

               END

My code version B includes the lines;           MOVLW   B'11111111'
                                               MOVWF   TRISB
and this seems to be where the problems start. I either get pulses on all portB
pins (flat tops with narrow long V drops to Vdd) and nothing on portA or only
RA3 will give me any pulses out and RB is zero. At the moment it seems only to
want to generate the former (I'm telling you sometimes I believe these things
are really alive and someone is playing a big joke on us ).

For version C I changed the value above from 11111111 to 11110000 and I now get
nothing from portB or portA.

I do get this message from the assembler
Message[302] C:\MOSHE\SOFTWARE\WMCS_PIC\WMPIC1C.ASM 87 : Argument out of range.
Least significant bits used.
for the lines that I write to TRIS but I get it for portA as well and that works
fine in version A. The assembler has a FAQ on this
WHEN I ASSEMBLE MY CODE, I GET DOZENS OF MESSAGES
ABOUT TRUNCATIONS FOR REGISTER VARIABLES IN BANK
1.

The full address is not contained in the generated machine
code.  Since it is necessary to define the variables with the full
address, you may want to mask this message using the directive
"ERRORLEVEL -302".

Thanks once again

Moshe

PS has nobody else had this problem? I'm sure it's a standard thing to read
pulses in on portB and send out on another port.
PPS It was "feel"

-------------------------------------
Name   :Moshe Fish
E-mail :RemoveMEmfishspam_OUTspamnetvision.net.il
Date   :03/14/96
Time   :14:25:33

1996\03\14@141002 by Kalle Pihlajasaari

flavicon
face
> and this seems to be where the problems start. I either get pulses on all
portB
>  pins (flat tops with narrow long V drops to Vdd) and nothing on portA or only
>  RA3 will give me any pulses out and RB is zero. At the moment it seems only
to


Have you checked what your watchdog timer is doing?

Cheers
--
Kalle Pihlajasaari     kallespamspamdata.co.za
Interface Products     Box 15775, Doornfontein, 2028, South Africa
+27 (11) 402-7750      Fax: +27 (11) 402-7751

1996\03\15@201037 by Dan Matthews

picon face
------ =_NextPart_000_01BB129A.7FEE2E40
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: 7bit

Moshe,

Here is your problem: Your interrupt ends in a RETFIE but there was never a call
to return from.

Change your

GOTO    PULSE_CHECK
to
CALL    PULSE_CHECK

and that should fix it.

Dan Matthews
spam_OUTdan.matthewsspam_OUTspamspam_OUTmicrochip.com
----------
From:   Moshe Fish[SMTP:mfishspam_OUTspamNETVISION.NET.IL]
Sent:   Thursday, March 14, 1996 4:05 PM
To:     Multiple recipients of list PICLIST
Subject:        !!Port B interrupt-most latest

>Moshe,
>I had a fairly large backlog of e-mail messages before I got to this one.
However,
>I bet you a buck (US) that suggestion 3 in my latest e-mail to the LIST will
fix
>your problem. Well, hang on a second. Maybe I should see your latest code
before
>making any wagers! Where in your code are you enabling the GIE bit?
>
>Scott
>
Scott
Here is my latest code version A-this works, i.e gives me the test pulses on
portA, NOTICE the parts that I have cut out (;)

               list P=16c65, f=inhx8m

               INCLUDE <P16C65.INC>

               ORG     0
               GOTO    START

;               ORG     4
;               GOTO    PULSE_CHECK     ;interrupt service vector

               ORG     0x10

START           CALL    INITPORTS



TEST            NOP
               NOP
               NOP
               MOVLW   B'00001111'     ;set pin hi-led on if to Vdd
               MOVWF   PORTA
               NOP
               NOP
               NOP
               NOP
               NOP
               NOP
               NOP
               NOP
               MOVLW   B'00000000'     ;set pin lo-led off if to Vdd
               MOVWF   PORTA
               NOP
               NOP
               MOVLW   B'00001111'     ;set pin hi-led on if to Vdd
               MOVWF   PORTA
               NOP
               NOP
               NOP
               NOP
               NOP
               NOP
               NOP
               NOP
               MOVLW   B'00000000'     ;set pin lo-led off if to Vdd
               MOVWF   PORTA


LOOP            GOTO TEST

PULSE_CHECK     BTFSS   INTCON,RBIF     ;PortB interrupt?
               GOTO    MAIN            ;If no int goto main
               MOVLW   B'00001111'     ;if interrupt
               MOVWF   PORTA           ;set pins hi-led on if to Vdd

CLR_RBINTF
               MOVF    PORTB,1         ;end mismatch-read portb to itself
               BCF     INTCON,RBIF     ;clear RB interrupt flag
               MOVLW   B'00000000'     ;set pins lo again-led off if to Vdd
               MOVWF   PORTA
               RETFIE

MAIN            RETFIE

INITPORTS       BSF     STATUS,RP0      ;select bank 1
               CLRF    TRISA           ;set all to o/p-lower power consump
;               MOVLW   B'1111111'      ;set portB<4:7> as i/p <0:3>o/p
;               MOVWF   TRISB
               CLRF    TRISC           ;set all to o/p-lower power consump
               CLRF    TRISD           ;set all to o/p-lower power consump
               CLRF    TRISE           ;set all to o/p-lower power consump
;               BCF     OPTION_REG,NOT_RBPU     ;enable pullup

               BCF     STATUS,RP0      ;select bank 0
               CLRF    PORTA           ;portA all low
               CLRF    PORTB           ;init portB
               CLRF    PORTC           ;portC all low
               CLRF    PORTD           ;portD all low
               CLRF    PORTE           ;portE all low
;               BCF     INTCON,RBIE     ;disable mask
;               MOVF    PORTB,W         ;read port
;               BCF     INTCON,RBIF     ;clear RB port interrupt change flag
;               BSF     INTCON,RBIE     ;enable RBIF interrupt
               RETFIE                  ;enable global and return

               END

My code version B includes the lines;           MOVLW   B'11111111'
                                               MOVWF   TRISB
and this seems to be where the problems start. I either get pulses on all portB
pins (flat tops with narrow long V drops to Vdd) and nothing on portA or only
RA3 will give me any pulses out and RB is zero. At the moment it seems only to
want to generate the former (I'm telling you sometimes I believe these things
are really alive and someone is playing a big joke on us ).

For version C I changed the value above from 11111111 to 11110000 and I now get
nothing from portB or portA.

I do get this message from the assembler
Message[302] C:\MOSHE\SOFTWARE\WMCS_PIC\WMPIC1C.ASM 87 : Argument out of range.
Least significant bits used.
for the lines that I write to TRIS but I get it for portA as well and that works
fine in version A. The assembler has a FAQ on this
WHEN I ASSEMBLE MY CODE, I GET DOZENS OF MESSAGES
ABOUT TRUNCATIONS FOR REGISTER VARIABLES IN BANK
1.

The full address is not contained in the generated machine
code.  Since it is necessary to define the variables with the full
address, you may want to mask this message using the directive
"ERRORLEVEL -302".

Thanks once again

Moshe

PS has nobody else had this problem? I'm sure it's a standard thing to read
pulses in on portB and send out on another port.
PPS It was "feel"

-------------------------------------
Name   :Moshe Fish
E-mail :RemoveMEmfishKILLspamspam@spam@netvision.net.il
Date   :03/14/96
Time   :14:25:33



------ =_NextPart_000_01BB129A.7FEE2E40
Content-Type: application/ms-tnef
Content-Transfer-Encoding: base64

eJ8+IgYBAQaQCAAEAAAAAAABAAEAAQeQBgAIAAAA5AQAAAAAAADoAAENgAQAAgAAAAIAAgABBJAG
AEABAAABAAAADAAAAAMAADADAAAACwAPDgAAAAACAf8PAQAAAFgAAAAAAAAAgSsfpL6jEBmdbgDd
AQ9UAgAAAABwaWMgbWljcm9jb250cm9sbGVyIGRpc2N1c3Npb24gbGlzdABTTVRQAFBJQ0xJU1RA
TUlUVk1BLk1JVC5FRFUAHgACMAEAAAAFAAAAU01UUAAAAAAeAAMwAQAAABcAAABQSUNMSVNUQE1J
VFZNQS5NSVQuRURVAAADABUMAQAAAAMA/g8GAAAAHgABMAEAAAAmAAAAJ3BpYyBtaWNyb2NvbnRy
b2xsZXIgZGlzY3Vzc2lvbiBsaXN0JwAAAAIBCzABAAAAHAAAAFNNVFA6UElDTElTVEBNSVRWTUEu
TUlULkVEVQADAAA5AAAAAAsAQDoBAAAAAgH2DwEAAAAEAAAAAAAAA98+AQiABwAYAAAASVBNLk1p
Y3Jvc29mdCBNYWlsLk5vdGUAMQgBBIABACMAAABSRTogISFQb3J0IEIgaW50ZXJydXB0LW1vc3Qg
bGF0ZXN0AOQLAQWAAwAOAAAAzAcDAA8AEgAIABQABQAYAQEggAMADgAAAMwHAwAPABIABgARAAUA
EwEBCYABACEAAABCMDRGMUYwOTg5N0VDRjExOEMwODQ0NDU1MzU0MDAwMADpBgEDkAYAyAwAABAA
AAALACMAAAAAAAMAJgAAAAAACwApAAAAAAADADYAAAAAAEAAOQCgHEIR1RK7AR4AcAABAAAAIwAA
AFJFOiAhIVBvcnQgQiBpbnRlcnJ1cHQtbW9zdCBsYXRlc3QAAAIBcQABAAAAFgAAAAG7EtUROAkf
T7F+iRHPjAhERVNUAAAAAAMABhDjt6LhAwAHEPALAAAeAAgQAQAAAGUAAABNT1NIRSxIRVJFSVNZ
T1VSUFJPQkxFTTpZT1VSSU5URVJSVVBURU5EU0lOQVJFVEZJRUJVVFRIRVJFV0FTTkVWRVJBQ0FM
TFRPUkVUVVJORlJPTUNIQU5HRVlPVVJHT1RPUFVMAAAAAAIBCRABAAAAeAsAAHQLAAAYGwAATFpG
dfRpskv/AAoBDwIVAqgF6wKDAFAC8gkCAGNoCsBzZXQyNwYABsMCgzIDxQIAcHJCcRHic3RlbQKD
M3cC5AcTAoB9CoAIzwnZO/EWDzI1NQKACoENsQtg4G5nMTAzFFALChRRDQvyYwBABdBvc2hlliwK
hQqFSASQZSAEANQgeQhhIBNQbwJgE+A4OiBZHMILgBPQcnI2dQUxCfBkBCALgCBhAQfwRVRGSUUg
Ypp1BUB0GyAcUXdhBCDYbmV2BJAe8WMHQAMg6HRvIBYQdAhwA6ADUvouG1xDEYAZEBxgHLMZzfsd
ARPQYwVAG7YZzxrQJV9hJHtHT1RPJTAlMFAAVUxTRV9DSEV8Q0slMCXPJtchQCKmQfxMTCdvJOUp
Li4BKi8m1+sKhQBwZB/BYQVAGxAIYKJsMXBmaXgccHQiLZpEA5FNMbAf0XdzCoUaZABwLgDANARA
bWmtBQBvEXAFIC4FoG0KiyBsaTE4MALRaS14MTQ0DfAM0DfjC1kx+jYkty06Byb9ORUMMCTG/kYD
YR1wOJ8k5AyCGuQ8kAEEAGhbU01UUDombTJQGxBATh8wVkkgU0lPTi5AIS5J/ExdOq87vQZgAjA8
7z37lFRoCHBzNNB5LDPRGnIRcCA34EXQMTk5QDYgNDowNSlATXNBPzu9VG9Dfz38MhB09wUgHUAh
YWMFIAiQAjAEIDhvZiA3QBPAKUBJQxpMQGBUR19CTnViakclAUl/PfshIVAVsSD6Qh3YLQRgTOEL
YBPQE8CzG1w25jM2OIckXT4a+7g+SSARgDFwHwBmC3Cocmx5U0FyI1FiANDqaxWgZ0yCZVLwC3AD
INkHgXNhI1AEIGINwAWw+xxgV6BnJOAhMh/QHIECIOZlIiYcIG93IIJXGVqgHwVAHLEe8R+QWRAg
KFXkUykxhXVnWmFLgAIg9CAzHsJtWHJTclmWW3PvHGBNQiAgAxBsXDYyUVcm4Ry6LiBXZSEQRdAj
In9b4R7xEbAFoB6QZGAz4Hn/WqBbATHlEbAjZWCVBaANsO9cNlqkVyYAwGsLgFlQAHDvWHAgMCNQ
EaAhZHAf4x7R/xyzZ/Ie8BxRXhIJ8AGgN0DbZQFhokcfYjKQP1cmVyb+UwWgAkBtzW7KHDZgaGuj
pyCRAJBf4UEtW6N3BbAka3NF0GkuHGBnad8gkHEhHGBhomCzcDIQEbCrW9JcNnAVsUFF0E4o4P9N
IB9wYaIKsUxhMZNXoiCQjyDgH6EIYAVAKDspG1yLec5MxD05UGM2NUXQxGY9C4BoeDg2ZnlvSX0E
SU5NMFVEH3A8+lA5UEN7cEDwfiBuNnyv8YAkT1JHLfMKdoIuKNbZTWBBUk12CoU7gE+BVG40hH+C
3C5OOx3oEbBy/nY1sHISJRAFsH9fhR+Bc384QAp2b5aDwovJLFJ91EkzP5CBMFRTG1wbXFRF92IB
i8l2cFCLb5Lvk/+VD0GXFU1PVkxXiCFC1ic3gDeAMZkBJ4kUEbH3HPAe0TYALR1AMXBf4QaQMSEy
VmRklr+Xx1dG+ykikEFBm2+WL54vnz+gT/+hX6Jvo3+kj6Wfpq+nv6jP/5ePmJWYwplNFaCaVA3Q
ms//qx+c76+/qm+yf7OPmA+ZH/+aL68/sE+xX7QPvA+9H74v/78/wE/BX8Jvw3/Ej8Wfxq//uh+s
P61Prl/I37qvu7cbXHxMT8iwhy+SQhtcLk5CTR9AUwXwffJUQ0CQLPhSQkm7QolBUfJSSW22M4I/
h/VNQX4Q14o7Sf1MoG4hUB3hWyIhUFnBdXf/zh+2f4kVzOEd9ttfzq+DwD/ZarflBCC4b813IqZM
UvZf1YHVIEbfH9xn1bOQMvxCLBrQ2ZcegVoABAA1Ef0RcC0WEFfRdgI+oCFBMpCZEbBsZuVf6sRC
Q9W0fdUfYx1ACsHVgB3ZGOFnv+pv3G/K/+JEFaAe8GcLcf/Mf82P4B+7r/anHyQbXNkeb/e/CsGP
9+tmU9W0g7FU817Q1XBQMOGnHUAlEVjwem5eoDH2T48V5MDVs1SOUkBg4U8hBW8vcOLAn1zBHOEC
k2WhX2BtcIZ/X+/utzK3R7fF1jI8RuA3Hj4e8B6xAlB+gDA6M94+AkEDv/UcAIJC/p//r3xTQwDf
Ae8C/wsv//tE/w0fDi8PPxBP//sfcBJPE19/FG8I/+vWyLB2kECQ5OBF/EcsdnHk4SlQ5/ZskXcB
/TIQbO5Qiv8a3/x//Y6Bv/8WHeEPdgMYQxkBIs8j3+dw/9lq2zAykAbkJp8nr9UwJQ7/DQAmLyrf
5wYSK3YCEiAtn/8ur+cGF0t2AnbAMWwar+vvORdEO2R64B3TWcBza/81r+Zv53HdAtm16Sc5bza/
/+yP7ZR2Au3pRiBk8XcA7pn/PW/8RTefHbXVg96P9s/6EvtG3x2XZxkAWPBZ8GoA6HA9aPB0Z1B1
dkZ/S8RFTr5E+B1YcHHr7dLtYHVoEP93YncAbLFacEKaBS8GIEtvf1MfVC8Jz8/VSlJbo2bxbfd3
YWGAZjF3atN242QEVzHudHcxZGB30GVtkGrRc8Dft/J1BhhDKeviUyjukRgwfWFwcHMBWeHaQGvw
ZAB34/JRZQFWIGRkAF0B43T+KUpD2lBXAWUEJcSK0GUhxGx5UhZSQTNdITFx/3PSdCJqAnT2eJFK
Uu3C4oBqekYQb1mQQVzBbRFt/m90MNqRKbFXVGDCXNFSFt9qQNqR43FqYE/wcnGBbPMOZorQdDDT
cChJJ20vdJEeQF/CbDJzZQF0ad90MOKAWbBX4GywZXgRT5H3ZZBW8l/Qc1IW0BBFcDxh/x5AcVAY
UGIiSlJpsnVgcPOqcO6geV/CYSJQaV/gWGpva0VwWvF14oAp+i7P3EZgkXI2DQBZsEF0l1biTkEY
UHVicWJveBH+ZljAaNBRhvOStzK28kpD/1mw2lBd0FpBUhZfhnNDKePvYIIlw2/dWbBkZ0Jkkm4B
f2oROMBBsnNSZ/IHoGWQbQtY4YrmTXnEWzMwMqJdJCA6XFzcwFOI0MF8sFNPRlRXg9B9EQBXTUNT
X1BJQwN9wn4xMUMuQVNNICA4NyA6ZHByZ/8U4GUiY0LzMEqAQZJv1tEQ3+kwWUBlgG7gKaBmilBm
8v9u0OoQb4Hi4G/WaDFPiFbx81yxWbB3cimwZ9HzsACC/yJQY1FZsFpCKbGDoiXFXRHXaQFWtVyx
d4rQa2ungiD/bdJbAE5md9DSYHqa4pAHoXFusEZBUVriVwLP1Vcf1ADZQFmwfwDTwE1CTAk1EE1Z
JCBPREUshVmhR/oAIERPWkzQv9TQfVBN0JJQALCOYFPP1TBBQk9VknAAgFVObkMhABxR+7BGz5D5
4UfXAKDScJFwVn2QSZAwjYBD+7DZMUJBTkvP1TH7b92KUmYeMfKA47BsQHnQ/23yX4EZsllQT+Ho
cLgxZ/L7Z2bocWHo8E/hz9VOElmQfyDQTwFt4UCxlcEiIHnCcvtmIl5QZYkjckSFAEVCXRX/Z/Me
MVZWlUSOIGly2xBisP9m5jkieVxvkF/CZ/I4oGxA1yIwYiHP1SKR8FLPkI2AoFZFTCAtfEEik7+f
/kFa0plR8pP4HW9zaADf0r37sIsy2lBy8GRisP3Q72shQYBW5Vi1P1mgaMEU0PtsQSmwJ4tSWUHo
YNAQVuP/oCLzsDxiW7dalLgxYAXt0P9tQ+hSgCNbAV+CGTNZcdMmTaaxSYgxB6EiZmWgbHoiz9wt
sU+yX7KAz9VOdmFiYVRwOqWDcLBuAGiZz9VFLdsRGHA6bYIgZaWgQE/wdHZuAE6hLm22cS5h0M/V
RGeytFEwgDMvMTQvOTaUNkdqAbRCuJA6MjUIMDMnz9/6grpyZFxpIDM2jjC6cO6g2zBcZjO8sHxz
MrxBWMBGACIxulV9BbpQAL5wAwAQEAAAAAADABEQAAAAAEAABzDgtrHH1BK7AUAACDDgtrHH1BK7
AR4APQABAAAABQAAAFJFOiAAAAAAnBo=

------ =_NextPart_000_01BB129A.7FEE2E40--

1996\03\17@092010 by Moshe Fish

flavicon
face
On Fri, 15 Mar 1996 18:08:20 -0700  Dan Matthews wrote:
>------ =_NextPart_000_01BB129A.7FEE2E40
>Content-Type: text/plain; charset="us-ascii"
>Content-Transfer-Encoding: 7bit
>
>Moshe,
>
>Here is your problem: Your interrupt ends in a RETFIE but there was never a
call
{Quote hidden}

Dan
All Microchip application examples use GOTO at the ORG 4 interrupt address. When
the interrupt is finished the program should continue from where it left off in
 the main code before the interrupt and it is this address the PC should lode
off the stack on the return, not the address 4.Unless I misunderstand something
here.
Moshe
-------------------------------------
Name   :Moshe Fish
E-mail :KILLspammfishspam.....netvision.net.il
Date   :03/17/96
Time   :14:14:11

1996\03\17@143028 by Dan Matthews

picon face
------ =_NextPart_000_01BB13FD.572644C0
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: quoted-printable

I hate when that happens.  Maybe I should stick to looking at code =
during daylight hours.  You are of course correct. The next address is =
put on the stack automatically when the interrupt occurs, and therefore =
your code can have a GOTO (as does my own code), not a CALL, at 04h.=20

       humbly,

               Dan Matthews

----------
From:   Moshe Fish[SMTP:spam_OUTmfishspamKILLspamNETVISION.NET.IL]
Sent:   Sunday, March 17, 1996 5:41 PM
To:     Multiple recipients of list PICLIST
Subject:        Re: !!Port B interrupt-most latest

On Fri, 15 Mar 1996 18:08:20 -0700  Dan Matthews wrote:
>------ =3D_NextPart_000_01BB129A.7FEE2E40
>Content-Type: text/plain; charset=3D"us-ascii"
>Content-Transfer-Encoding: 7bit
>
>Moshe,
>
>Here is your problem: Your interrupt ends in a RETFIE but there was =
never a
call
{Quote hidden}

Dan
All Microchip application examples use GOTO at the ORG 4 interrupt =
address. When
the interrupt is finished the program should continue from where it =
left off in
 the main code before the interrupt and it is this address the PC =
should lode
off the stack on the return, not the address 4.Unless I misunderstand =
something
here.
Moshe
-------------------------------------
Name   :Moshe Fish
E-mail :KILLspammfishspamspamBeGonenetvision.net.il
Date   :03/17/96
Time   :14:14:11



------ =_NextPart_000_01BB13FD.572644C0
Content-Type: application/ms-tnef
Content-Transfer-Encoding: base64

eJ8+IgkTAQaQCAAEAAAAAAABAAEAAQeQBgAIAAAA5AQAAAAAAADoAAENgAQAAgAAAAIAAgABBJAG
AEABAAABAAAADAAAAAMAADADAAAACwAPDgAAAAACAf8PAQAAAFgAAAAAAAAAgSsfpL6jEBmdbgDd
AQ9UAgAAAABwaWMgbWljcm9jb250cm9sbGVyIGRpc2N1c3Npb24gbGlzdABTTVRQAFBJQ0xJU1RA
TUlUVk1BLk1JVC5FRFUAHgACMAEAAAAFAAAAU01UUAAAAAAeAAMwAQAAABcAAABQSUNMSVNUQE1J
VFZNQS5NSVQuRURVAAADABUMAQAAAAMA/g8GAAAAHgABMAEAAAAmAAAAJ3BpYyBtaWNyb2NvbnRy
b2xsZXIgZGlzY3Vzc2lvbiBsaXN0JwAAAAIBCzABAAAAHAAAAFNNVFA6UElDTElTVEBNSVRWTUEu
TUlULkVEVQADAAA5AAAAAAsAQDoBAAAAAgH2DwEAAAAEAAAAAAAAA98+AQiABwAYAAAASVBNLk1p
Y3Jvc29mdCBNYWlsLk5vdGUAMQgBBIABACMAAABSRTogISFQb3J0IEIgaW50ZXJydXB0LW1vc3Qg
bGF0ZXN0AOQLAQWAAwAOAAAAzAcDABEADAAcAAAAAAAPAQEggAMADgAAAMwHAwARAAwAFwAMAAAA
FgEBCYABACEAAABFREJBODEyQkVFN0ZDRjExOEMwODQ0NDU1MzU0MDAwMAAgBwEDkAYAUAYAABAA
AAALACMAAAAAAAMAJgAAAAAACwApAAAAAAADADYAAAAAAEAAOQDAcV7aNxS7AR4AcAABAAAAIwAA
AFJFOiAhIVBvcnQgQiBpbnRlcnJ1cHQtbW9zdCBsYXRlc3QAAAIBcQABAAAAFgAAAAG7FDfaXiuB
uu5/7hHPjAhERVNUAAAAAAMABhBoF9EIAwAHEE4EAAAeAAgQAQAAAGUAAABJSEFURVdIRU5USEFU
SEFQUEVOU01BWUJFSVNIT1VMRFNUSUNLVE9MT09LSU5HQVRDT0RFRFVSSU5HREFZTElHSFRIT1VS
U1lPVUFSRU9GQ09VUlNFQ09SUkVDVFRIRU5FWFRBAAAAAAIBCRABAAAAAAUAAPwEAADQCAAATFpG
dRnJRPn/AAoBDwIVAqgF6wKDAFAC8gkCAGNoCsBzZXQyNwYABsMCgzIDxQIAcHJCcRHic3RlbQKD
M3cC5AcTAoB9CoAIzwnZO/EWDzI1NQKACoENsQtg4G5nMTAzFFALChRRxQvyYwBAIEkgEYAT0Mgg
d2gJ8CB0GxEbAURwcAnwcy4gBdBhTHliG0Aa8HNoCGBsQmQdEHRpY2sboG+SIBWgb2sLgGcgG9Gz
BaANsCBkCHEecWQcsHBsaWdoG+EIYRxiWccIYB6QFhAgb2YewSBBpxtABaEWEGN0HHBUG3AQIG5l
eAVAYWRkxxYQBBEEACBwdQVAAiDfG6EbQBPAANAd0GEjoANx8x2hB0BseRtWG0ALgBPQRSHgdQUx
b2NjIEEsfR6Qbh1wJAEWEAIQIPF5XwhhHsQlIAOgEYB2G0BhACBHT1RPIChhKQQgZG8HkW0lYG93
SwOgHtIpJxBubyLBIDBDQUxMJxEFQDA0vmgccAqFCoYBkRsAdQbQ3SVQLCxvLXAtQ0QDkRygcwJA
G3B3cy4NCwMfwDEEODAC0WktMTQ0zw3wDNAyIwtZMTYKoANg8xPQIhAgLTRHCocy+wwwdTPGRgNh
OjVOM8YtQ00Wbx0gG0BGBABoW1NgTVRQOm0x8B0gQABORVRWSVNJT4ROLjphLklMXTTvnzX9BmAC
MDcvODtTdSdAFxywJxAcoHIRcCAxNwEnEDE5OTYgNToyNBrQUE07fzX9VG//Pb84PB1QHaALUBtA
IfEFIH8IkAIwBCAhIR/AE8BBQEk0Q0w6oFRBfzyOdWJOaiIBQ584O1JlShAhpCFQFbEgQiYILQRg
P0cBC2AT0BPAME8xUzM2tzLHGkUzxk8DoDbgaUCRzjVAAkCkMaA6MFJgAdD5NDAwNzHAHIAvihtQ
M9KKOgqFPjREID1fB8ClIrBQCsB0XzHAMFYQADFCQjEyOUEuwDdGRUUyRTJAVIbHCFAmIQIwLVR5
HDBKEGsT0CKwLwtTOx7AEYQ9MCJ1cy0pwEYgaSIVV39yAHFmBJAtRW5HHtEeYUoQN2JpTgY+71SG
OQMt9l2XSCeRI1IoE/8zwQJgE+BKECChBcAmGAnwLmQjQQOgKUBSOnBGSfhFIGIjoSdzG1ApwSKQ
+ykQBcBhCoUooSVAVIYd4l0WEHQIcAOgA1IuXS5DPxGAGRAn9F0uKWNpYVBVAExTRV9DSEVD/ktU
hh3wWrcrkWlvXUwnNPcb0R0lMfB4I1AiIF0uL48zVNEfkG4uJOEv80Btrx2wA2ARcAUgLgWgbVSM
7zSpCoVwEQqFQSVABdByNn8ekBwgH8AlIB2gI9EioGH+bUXBBCBaIBtAKWMb0SQC4E9SRyA0Jgki
5Rxw/lcbcWQ2JdwjYTHwAwA5If8nU2BCCcB3UB0WBaACMAuA/wpQZhMbUl+iTZEOISERITD/C4Bk
NiPzAMBiIR7THNAnw/8l3CcyfyEjYRuwI2Ei5iQC/FBDHRYVoA2wZDZ/oiQIHyPVZbQrBCQCIuY0
LlXebneBBCAa8HIgcz+hBJD7JEEnQXMDcBHAcoAZEGQ2fyeCbwY5AwqFc3iNX3N/Trd3UBtAHIA6
OQgKhUVNUM8LcAMgOfUikHR2BAB28foukfEuAxB0hxsxj9EZQPovQHAvQNAKhQdij8IyIP2VQzEu
DE6PT58z1QqFFTECAJnwAwAQEAAAAAADABEQAAAAAEAABzBgsfMuNxS7AUAACDBgsfMuNxS7AR4A
PQABAAAABQAAAFJFOiAAAAAAJNs=

------ =_NextPart_000_01BB13FD.572644C0--

1996\03\18@210113 by Dan Matthews

picon face
Moshe,

I felt so dumb after my CALL vs GOTO suggestion that I had to write your
program to satisfy myself I had done good in the world. (even though you
have probably found it by now)

The following program works with essentially the same circuit you had, with
the lower four bits on PORTA toggling to flash the LED. Instead of an
external source I used RB7 as an output to cause the change on PORTB.
Actually I only drive it low. I tristate RB7 and let the pull-ups take it
high. This way I can short the pin to ground to prevent the change on
PORTB.

After looking over your code again, it was obvious you had been over it
many times trying to fix it because comments and code no longer coincided.
I was not sure I knew exactly what you were doing. To use this code to
detect an input, simply remove the part where I toggle the TRISB,7.

I added several items that may have been the problem, like saving Status
and W on interrupt and configuration word setup using __config (double
underscore in fron of "config"). I thought perhaps the WDT was getting you.

anyway, good luck

  Dan Matthews
  dan.matthewsspamspammicrochip.com

; connect an LED to Vdd (or Vss) from any PORTA pin  0 to 3 (through a
;  resistor, I used 330 ohms)
; optional, connect a 1K/5K pull down through a switch to RB7
; running program will blink LED, signifying change on PORTB interrupt
; pulling RB7 down will prevent pin from changing, LED will not blink
; RB7 does not drive high, but is tristated - it does drive low
; on power up the LED should blink four times slow,
;   signifying LED test
; after LED test, the LED should blink rapidly signifying
;   change on PORTB

  list P=16c65, f=inhx8m

  INCLUDE <P16C65.INC>

  __config (_WDT_OFF & _XT_OSC & _CP_OFF) ; determines config word value

W_TEMP          EQU     0x20    ;variables for STATUS and W in interrupt
W_TEMP_BANK1    EQU     0xA0    ;W_TEMP must be reserved in BANK0 and BANK1
STATUS_TEMP     EQU     0x21
INNERCOUNT      EQU     0x22    ;some bank0 variables for looping
OUTERCOUNT      EQU     0x23
TIMES           EQU     0x24
TESTCOUNT       EQU     0x25

       ORG     0
       CLRF    PCLATH          ; cleared on POR, but good idea
       CLRF    STATUS          ; since it allows a s/w reset
       GOTO    START

       ORG     4
       GOTO    PULSE_CHECK     ;interrupt service vector

       ORG     0x10

START
       CALL    INITPORTS

TEST    MOVLW   9               ; this loop flashes LEDs on start up
       MOVWF   TESTCOUNT
NEXT    CALL    BLINK
       MOVLW   0x5
       CALL    DELAY
       DECFSZ  TESTCOUNT,F
       GOTO    NEXT
       MOVLW   0XFF

       BSF     STATUS,RP0      ; all funtions in "hell" can be in
BANK1
MAIN
       MOVLW   0x1
       CALL    DELAY           ; call a delay of 10X
       MOVLW   0x80
       XORWF   TRISB,F         ; Toggle trisb and cause interrupt
       GOTO    MAIN      ; send to processor hell (infinite loop)
              ; from now on, only an interrupt can redirect program
; note that portb pull-ups are enabled
; note that that portb,7 is initialized to zero
; if TRISB,7 is toggled to input, pull-up pulls pin high
; if TRISB,7 is toggled to output, pin drives latch value,
;    which is zero
; if pin RB7 is pulled down externally, PORTB,7 will not
;    change thus no interrupt
; a blinking LED means change on PORTB interrupt IS occuring

PULSE_CHECK
PUSH
       MOVWF   W_TEMP
       SWAPF   STATUS,W
       BCF     STATUS,RP0
       MOVWF   STATUS_TEMP
;
       BTFSS   INTCON,RBIF     ;PortB interrupt?
       GOTO    POP       ;If not right int, exit interrupt routine

                         ;could have something here to reinitialize
                               ; since you should never get here
       CALL    BLINK           ; Change LED state

CLR_RBINTF
       MOVF    PORTB,W         ;end mismatch-read portb
       BCF     INTCON,RBIF     ;clear RB interrupt flag
POP
       SWAPF   STATUS_TEMP,W
       MOVWF   STATUS
       SWAPF   W_TEMP,F
       SWAPF   W_TEMP,W
       RETFIE

INITPORTS                       ;using some original code
       BSF     STATUS,RP0      ;select bank 1
       CLRF    TRISA           ;set all to o/p-lower power consump
       MOVLW   B'01111111'     ;set portB<0:6> as i/p <7> o/p
       MOVWF   TRISB           ;the portb output will be
                               ;used to cause change on portB
       CLRF    TRISC           ;set all to o/p-lower power consump
       CLRF    TRISD           ;set all to o/p-lower power consump
       CLRF    TRISE           ;set all to o/p-lower power consump
       BCF     OPTION_REG,NOT_RBPU     ;enable pullup
       BCF     STATUS,RP0      ;select bank 0
       CLRF    PORTA           ;portA all low
       CLRF    PORTB           ;init portB
       CLRF    PORTC           ;portC all low
       CLRF    PORTD           ;portD all low
       CLRF    PORTE           ;portE all low
       BCF     INTCON,RBIE     ;disable mask / shouldn't be needed
       MOVF    PORTB,W         ;read port for clearing interrupt
       BCF     INTCON,RBIF     ;clear RB port interrupt change flag
       BSF     INTCON,RBIE     ;enable RBIF interrupt
       RETFIE                  ;enable global and return

DELAY                           ; a long delay that executes W times
       MOVWF   TIMES
OUTERINIT
       MOVLW   0xAF
       MOVWF   OUTERCOUNT
       CLRWDT    ; needed during this long delay if WDT is enabled
INNERINIT
       MOVLW   0xFF
       MOVWF   INNERCOUNT
INNER
       DECFSZ  INNERCOUNT,F
       GOTO    INNER
       DECFSZ  OUTERCOUNT,F
       GOTO    INNERINIT
       DECFSZ  TIMES,F
       GOTO    OUTERINIT
       RETURN

BLINK
       MOVLW   B'00001111'
       XORWF   PORTA,F         ; toggle lower four bits of PORTA
       RETURN


       END

'How to make a processor do nothing until interrupt'
1996\03\19@184821 by Hans-Christian Prytz

flavicon
face
I have a question which probably seems rather simple to those of you
who have used the PIC's for a while.

I need a way to have the processor wait (doing nothing) until an
interrupt from TMR0 occurs. I can't use sleep mode becuse TMR0 stops
when the processor enters sleep mode (right?), so I've tried using a
goto loop calling several NOP's, but this (according to MPSIM)
triggers the watchdog timer.

Does anybody have a suggestion?

--
____________________________________________
|Hans-Christian Prytz                        |
|e-mail: RemoveMEhans.christian.prytzspamBeGonespamRemoveMElogin.eunet.no |
|homepage: http://login.eunet.no/~hanscpr/   |
|____________________________________________|
"If anything can go wrong, it will!"
"If anything goes wrong, it will do so at
 the worst possible time!"
-- Murphy's 1st and 2nd law.
"Murphy was a damn optimist!!"
-- Any friend of Frank Drebin

1996\03\19@192202 by Eric T. Brewer

flavicon
face
The following should do what you desire:

Loop:
               ClrWDT
               Goto            Loop

Cheers,
eric

At 4:41 PM 3/19/96, Hans-Christian Prytz wrote:
{Quote hidden}

1996\03\20@065209 by Kaurstad, yenyvind

flavicon
face
> I have a question which probably seems rather simple to those of you
> who have used the PIC's for a while.
>
> I need a way to have the processor wait (doing nothing) until an
> interrupt from TMR0 occurs. I can't use sleep mode becuse TMR0 stops
> when the processor enters sleep mode (right?), so I've tried using a
> goto loop calling several NOP's, but this (according to MPSIM)
> triggers the watchdog timer.
>
> Does anybody have a suggestion?

Do you need the watchdog-timer ?
If not I suppose you could disable it using thc control bits.
(I'm not sure whether this is possible on all PIC's, though)


---------------------------------------------------------------
  Oyvind Kaurstad    Phone: Norway+90062116   @spam@oyvindSTOPspamspam@spam@hsr.no
   4140 Erfjord     http://www.stud.his.no/~oyvind
              The truth is out there - NOT


'Erratic PC increment through interrupt'
1996\04\26@074704 by Wolfram Liebchen
flavicon
face
Does anyone know, if there is danger of erratic PC increment
caused by an interrupt during a MOVWF PCL ?
The application note AN556, concerning table reads / computed GOTO
on a PIC 16Cxx device, says, that one has to disable interrupts to
prevent the computed GOTO from jumping one instruction too far.

The data book (at least for PIC 17C42) says, that increment of PC
is inhibited after GOTO, CALL, RETURN... and MOVWF PCL. So then, there
should be no danger?
Or even worse, an interreupt during a normal GOTO could also cause a
false jump ?!?

I would like to hear, if anyone has tested for this problem.

TIA

Wolfram


+-----------------------------------------------+
! Wolfram Liebchen, liebchenspamBeGonespamspamBeGoneipserv.ffo.fgan.de !
!      Forschungsinstitut fuer Optik            !
!      Schloss Kressbach                        !
!      D-72072 Tuebingen                        !
!      Tel: +49 (0)7071 / 709-158               !
!      Fax: +49 (0)7071 / 709-270   (G3 / G4)   !
+-----------------------------------------------+

1996\04\26@090603 by myke predko

flavicon
face
>Does anyone know, if there is danger of erratic PC increment
>caused by an interrupt during a MOVWF PCL ?
>The application note AN556, concerning table reads / computed GOTO
>on a PIC 16Cxx device, says, that one has to disable interrupts to
>prevent the computed GOTO from jumping one instruction too far.
>
>
>Wolfram

Wolfram, my ownly comment would be that interrupts may be disabled during a
"movwf PCL", but I believe the command that is normally used in
tables/computed jumps is "addwf PCL,f" (which is not in your list of
interrupt disabling commands).

I think I have lucked out in my applications by doing table reads _before_
interrupts are enabled and inside interrupt handlers (in which interrupts
are disabled).

I will definitely add this to my list of "things to avoid".

Myke
Myke

"We're Starfleet officers, weird is part of the job."

Capt. Catherine Janeway

1996\04\26@114316 by Scott Dattalo

face
flavicon
face
Wolfram Liebchen wrote:
>
> Does anyone know, if there is danger of erratic PC increment
> caused by an interrupt during a MOVWF PCL ?
> The application note AN556, concerning table reads / computed GOTO
> on a PIC 16Cxx device, says, that one has to disable interrupts to
> prevent the computed GOTO from jumping one instruction too far.
>
> The data book (at least for PIC 17C42) says, that increment of PC
> is inhibited after GOTO, CALL, RETURN... and MOVWF PCL. So then, there
> should be no danger?
> Or even worse, an interreupt during a normal GOTO could also cause a
> false jump ?!?
>
> I would like to hear, if anyone has tested for this problem.
>

The information in AN556 is incorrect. You do not need to disable interrupts
in computed GOTOs.

Scott


P.S.
Andy W., I just checked your PIC question 5. It still references AN576.

'16C74 computed goto's / interrupt problem'
1996\04\30@143019 by Jim Main

flavicon
face
What am I doing wrong?

I'm using a KR9600 keyboard encoder writing a 6 bit key code into portB,
with the Data Ready line connected to PB0 INT on the 16C74.  When a button
is pressed on the front panel, the key address is output and the data ready
line pulses high, causing an interrupt - this works so far.

The interrupt service routine - after saving W, STATUS, and PCLATH to temp
registers - writes PortB to a register KEY_IN, sets a flag to signal a key
is ready, clears INTCON, restores the temp registers to their respective
locations, and returns from the interrupt.

The main part of the code just loops till the flag is set, then jumps to a
label set at ORG 0200 (new sub page), rotates KEY_IN to the right (as INT is
PB0)
and adds the result to pcl.  Theres then a large table with key positions
and nops in between (key values aren't consecutive).  The table doesn't
cross the next boundary.

At the locations corresponding to the keys, there's a further goto to get to
a dedicated routine to service that key - at the moment just trying to set a
port bit to test it.  After the routine's finished, the INTE bit is set -
followed by a GOTO the start of the main loop

The problem is it doesn't work.. it seems to be resetting and running from
the beginning again...

I'd appreciate any help - this is driving me crazy!

code follows:


;==========================================================================
;       INTERRUPT SERVICE ROUTINE
;==========================================================================

       ORG     04
       bsf     portA,2                 ;an indicator to tell if the interrupt w
as entered

       movwf   temp_w                  ;store the contents of the w register
       swapf   STATUS,w                ;and the status register, so that they
       bcf     STATUS, RP0             ;(set RAM page 0)
       movwf   temp_stat               ;can be restored before leaving the inte
rrupt
       movf    pclath,w
       movwf   temp_lath


       clrf    intcon                  ;disable the keypad interrupt

keypad
       movf    PortB,w
       movwf   key_in                  ;load key data into key_in register
       bsf     mode,d_rdy              ;set the data ready bit of the mode regi
ster


       movf    temp_lath,w
       movwf   pclath

       swapf   temp_stat,w             ;restore the status & w registers
       movwf   STATUS                  ;before leaving the interrupts

       swapf   temp_w,f                ;using swapf's so that the status
       swapf   temp_w,w                ;bits aren't altered


       RETFIE                          ;get out of the interrupt

;------------------------------------------------------------------------------
;main program loop
;---------------------------


start
       btfss   mode,d_rdy              ;is the data ready flag set?
       goto    start                   ;no, so LOOP
       bcf     mode,d_rdy              ;yes, so clear the flag and continue
       bsf     portA,1
       goto    process


       org     0201                    ;start the computed goto table in a new
sub page

process bsf     portA,3                 ;an indicator to see if the code made it
this far..

       rrf     key_in,f                ;rotate key_in to the right to get it in
to position
       movlw   0x3F                    ;mask top 2 msb's of key_in
       andwf   key_in,w                ;so that top 2 bits are cleared and data
is in bottom 6 bits
       movwf   portC                   ;to check that the correct amount's abou
t to be added to pcl


       addwf   pcl,f

       goto    cancel
       goto    key0
       goto    key_ent
       goto    key9
       goto    key8
       goto    key7
       nop
       nop
       nop
       nop
       goto    key6
       goto    key5
       goto    key4
       goto    key3
       goto    key2
       goto    key1
       nop
       nop
       nop
       nop
       goto    k_in
       goto    k_bs
       goto    k_mc
       goto    k_pre
       goto    b_ej
       goto    b_rew
       nop
       nop
       nop
;-----------------------------cut-------------------

Ideas?

Jim

1996\04\30@154747 by Andrew Warren

face
flavicon
face
Jim Main <spamBeGonePICLISTspamMITVMA.MIT.EDU> wrote:

> The main part of the code just loops till the flag is set, then
> jumps to a label set at ORG 0200 (new sub page), rotates KEY_IN to
> the right (as INT is PB0) and adds the result to pcl.
> ....
> The problem is it doesn't work.. it seems to be resetting and
> running from the beginning again...
>
> I'd appreciate any help - this is driving me crazy!

Jim:

Add the following code before your "ADDWF PCL":

   MOVLW HIGH ($+3)
   MOVWF PCLATH

-Andy

Andrew Warren - spam_OUTfastfwdSTOPspamspamix.netcom.com
Fast Forward Engineering, Vista, California
http://www.geocities.com/SiliconValley/2499

1996\04\30@155844 by Byron A Jeff

face picon face
{Quote hidden}

Code deleted.

A computed goto only affects the lower 8 bits of the PC. Where does the
upper part of the address come from? PCLATH!

So while you diligently saved and restored PCLATH in your ISR, you didn't
utilize it for your computed goto. So your goto jumped right back into
page 0. Hence your problem.

Just set PCLATH to page 2 before the computed goto and everything will
work fine. if you have computed gotos on other pages be sure to change
PCLATH there too.

Because there are enough bits in the CALL and GOTO instructions, this only
affects computed goto's

hope this helps,

BAJ

1996\04\30@160256 by Andrew Warren

face
flavicon
face
I wrote:

> Add the following code before your "ADDWF PCL":
>
>     MOVLW HIGH ($+3)
>     MOVWF PCLATH

Uhh... Slight error here.  Sorry, Jim.

The "MOVLW" I suggested adding will, of course, corrupt the key value
in W.  Instead of inserting the above code just before the "ADDWF
PCL", insert the following right after the "RRF KEYIN,F":

   MOVLW HIGH ($+6)
   MOVWF PCLATH

-Andy

Andrew Warren - RemoveMEfastfwdspamspamix.netcom.com
Fast Forward Engineering, Vista, California
http://www.geocities.com/SiliconValley/2499

'[PIC]PortB Interrupt on change?'
1996\04\30@194040 by Xaq

flavicon
face
I have read through the MC data book and app notes and have not found much
info on PortB interrupt on change.

Do all of the pins (b4-b7) have to be used as interrupts when they are enabled?
Can you, for example, use bits b4 and b5 as external interrupts and use b6
and b7 as regular outputs?  Will outputs on those lines trigger an interrupt?

Also I am little confused about a line in the MC app notes (an566).  In
every example they use the following command as one of the first in the
interrupt service routine:

movf portb,1    ;Read portB (into itself) to end mismatch condition

What mismatch condition?  Why is this necessary?  What is really going on?


Thanks

Zach

'16C74 computed goto's / interrupt problem'
1996\04\30@203435 by Jim Main

flavicon
face
>A computed goto only affects the lower 8 bits of the PC. Where does the
>upper part of the address come from? PCLATH!

>So while you diligently saved and restored PCLATH in your ISR, you didn't
>utilize it for your computed goto. So your goto jumped right back into
>page 0. Hence your problem.

I did what you said and it works!!  I'd thought that PCLATH would already
have the high bits set, and it'd only be a problem if I went over a sub page
boundary (which is why I started off the computed goto at ORG 200)
..obviously not!

Thanks for the help - also to Andrew Warren, who came up with the answer also..

Jim


{Quote hidden}

'[PIC]PortB Interrupt on change?'
1996\04\30@220620 by John Payson

flavicon
face
> movf portb,1    ;Read portB (into itself) to end mismatch condition
>
> What mismatch condition?  Why is this necessary?  What is really going on?

For various design reasons, the interrupt-on-change circuitry uses a
"current state" latch-word (4-bits) which is compared with the actual
signals on port B.  Any time such values are different, the PIC will
set RBIF.  While it might have been possible to use synchronizers so
that the "current-state" latch-word would be updated automatically
after setting RBIF, such a design would have been a little tricky in
a context where there's no guaranteed clock (the CPU might be sleeping).

To force the "current-state" latch-word to match the port-pin values,
you must either read or write to PORTB.  Note that if FSR is pointing
to portB, a NOP or CLRW instruction may also have this function.  I
don't know whether a skipped instruction which [tried to] read PORTB
would or not; I don't know how the skipping logic works.


'[PIC]PortB Interrupt on change?'
1996\05\01@011458 by Andrew Warren
face
flavicon
face
Xaq <TakeThisOuTPICLISTspamspamRemoveMEMITVMA.MIT.EDU> wrote:

> I have read through the MC data book and app notes and have not
> found much info on PortB interrupt on change.
>
> Do all of the pins (b4-b7) have to be used as interrupts when they
> are enabled? Can you, for example, use bits b4 and b5 as external
> interrupts and use b6 and b7 as regular outputs?  Will outputs on
> those lines trigger an interrupt?

> Also I am little confused about a line in the MC app notes
> (an566). In every example they use the following command as one of
> the first in the interrupt service routine:
>
> movf portb,1    ;Read portB (into itself) to end mismatch condition
>
> What mismatch condition?  Why is this necessary?  What is really
> going on?

Zach:

Don't know how you missed this in your reading...

PIC16C7X Data Sheet, section 5.2 ("PORTB and TRISB Registers"):

   "Four of PORTB's pins, RB<7:4>, have an interrupt on change
   feature.  Only pins configured as inputs can cause this
   interrupt to occur (i.e., any RB7-RB4 pin configured as an
   output is excluded from the interrupt on change comparison).
   The input pins (of RB7-RB4) are compared with the old value
   latched on the last read of PORTB.  The "mismatch" outputs of
   RB7-RB4 are OR'ed together to generate the RBIF interrupt (flag
   latched in INTCON<0>."

-Andy

Andrew Warren - KILLspamfastfwdspamspamspam_OUTix.netcom.com
Fast Forward Engineering, Vista, California
http://www.geocities.com/SiliconValley/2499

1996\05\01@015445 by Xaq

flavicon
face
Thanks Andy,  for some reason I looked in the section on interrupts and
skipped the section about TRISB.  Next time I will try to look more thoroughly.

Thanks

Zach

'16C74 computed goto's / interrupt problem'
1996\05\01@025544 by Chaipi Wijnbergen

flavicon
picon face
Dear Jim,

I understand that your program works now (good for you), I wanted to say
two things.


1. You are clearing INTCON which also clears the INTE bit (RB0 external
interrupt enable) you need to re-set it for next interrupt. another
alternative to is to do bcf INTCONT, _INTF which just clears the
interrupt flag.

2. In your computed goto table, don't you want to do something like GOTO
NOP_ROUTINE which will do nothing, but will prevent your computed goto
table from continueing to the next key. I understand that you do not
expect to get there at all. but in case you will have a problem with the
keypad and the wrong key will come to port B then you will execute other
keys or if it is after the last key then the program will continue out of
the table to what ever is there.

Chaipi

                              \\\|///
                            \\  ~ ~  //
                             (  @ @  )
----------------------------oOOo-(_)-oOOo--------------------------------------
!                                                                             !
! Chaipi Wijnbergen                                                           !
! Electronics/Computer Eng. M.Sc.  Tel    : +972-8-9343079                    !
! Optical Imaging Laboratory       Fax    : +972-8-9344129                    !
! Brain Research Center            Email  : chaipiRemoveMEspamtohu0.weizmann.ac.il       !
! Weizmann Institute of Science    URL    : http://www.weizmann.ac.il/~chaipi !
! Rehovot 76100 ISRAEL             IPhone : chaipi                            !
!                                                                             !
------------------------------------Oooo.--------------------------------------
                         .oooO     (   )
                         (   )      ) /
                          \ (      (_/
                           \_)


On Tue, 30 Apr 1996, Jim Main wrote:

{Quote hidden}

was entered
>
>       movwf   temp_w                  ;store the contents of the w register
>       swapf   STATUS,w                ;and the status register, so that they
>       bcf     STATUS, RP0             ;(set RAM page 0)
>       movwf   temp_stat               ;can be restored before leaving the
interrupt
>       movf    pclath,w
>       movwf   temp_lath
>
>
>       clrf    intcon                  ;disable the keypad interrupt
>
> keypad
>       movf    PortB,w
>       movwf   key_in                  ;load key data into key_in register
>       bsf     mode,d_rdy              ;set the data ready bit of the mode
register
{Quote hidden}

;------------------------------------------------------------------------------
{Quote hidden}

sub page
>
> process bsf     portA,3                 ;an indicator to see if the code made
it this far..
>
>       rrf     key_in,f                ;rotate key_in to the right to get it
into position
>       movlw   0x3F                    ;mask top 2 msb's of key_in
>       andwf   key_in,w                ;so that top 2 bits are cleared and data
is in bottom 6 bits
>       movwf   portC                   ;to check that the correct amount's
about to be added to pcl
{Quote hidden}

1996\05\02@081040 by Jim Main

flavicon
face
Hi Chaipi

>1. You are clearing INTCON which also clears the INTE bit (RB0 external
>interrupt enable) you need to re-set it for next interrupt. another
>alternative to is to do bcf INTCONT, _INTF which just clears the
>interrupt flag.

yes, I'm going to do that - I've got another 2 interrupt sources and they
have to be disabled individually - this was just for quickness..

>2. In your computed goto table, don't you want to do something like GOTO
>NOP_ROUTINE which will do nothing, but will prevent your computed goto
>table from continueing to the next key.

Excellent idea! - save me from possible headscratching later on..

Thanks again

Jim

'Interrupts on 16C84'
1996\05\02@134952 by adrian

flavicon
picon face
Seeing as I have spent half a day chasing this bug, I thought I would share
it with you all.

If you write an interrupt handler on a 16C84, then you need to manually
store the W register and STATUS register to ensure they main program doesn't
go wrong. No problem so far. You also may need to store the FSR if used by
the main program and interrupts, as in a FIFO handling situation... Easy...

So at the start of the handler I store W and STATUS, and at the end I
restore STATUS and W.

I forgot that re-loading W would of course change the Z flag !!!
So you must restore STATUS, then restore W, and then set or clear Z
depending on the stored value of STATUS. What a mess...

ARGGGGGGGGGGGGGGGGG! half a day wasted... You learn something new every day.

--
_
(_) _| _ . _  _   Tel +44 973 222257  Nokia orange in stock *NOW*. E&OE
( )(_|(  |(_|| )  Fax UK 0500 222258  http://www.eaglenet.co.uk/aa/
Moving to Bracknell? large family ?   http://www.eaglenet.co.uk/aa/house/

1996\05\02@154919 by Andrew Warren

face
flavicon
face
Adrian Kennard <EraseMEadrianSTOPspamspamRemoveMErhanna.demon.co.uk> wrote:

> Seeing as I have spent half a day chasing this bug, I thought I
> would share it with you all.
>
> If you write an interrupt handler on a 16C84, then you need to
> manually store the W register and STATUS register to ensure they
> main program doesn't go wrong. .... I forgot that re-loading W would
> of course change the Z flag !!! So you must restore STATUS, then
> restore W, and then set or clear Z depending on the stored value of
> STATUS. What a mess...

Adrian:

Sorry you wasted half a day on this.  An easier way is the
following, which is on mmy web page and has been in the Microchip
data books for a couple of years now:

   INTW    EQU     [any page-0 register]
   INTS    EQU     [any page-0 register]

           ....

   ; INTERRUPT SERVICE ROUTINE:

   PUSH    MOVWF   INTW                    ;SAVE THE W-REGISTER.

           SWAPF   STATUS,W                ;SAVE THE STATUS
           MOVWF   INTS                    ;REGISTER.

           BCF     STATUS,RP0              ;MAKE SURE WE'RE ON
                                           ;REGISTER PAGE 0
                                           ;[optional].

           ....

   POP     SWAPF   INTS,W                  ;RESTORE THE STATUS
           MOVWF   STATUS                  ;REGISTER

           SWAPF   INTW                    ;RESTORE THE
           SWAPF   INTW,W                  ;W-REGISTER.

           RETFIE                          ;RETURN AND RE-ENABLE
                                           ;INTERRUPTS.

Note that the STATUS register doesn't HAVE to be SWAPFed into and
out of INTS; doing so just keeps the Z flag from being disturbed on
ENTRY to the interrupt handler.  I've never needed this feature, but
it doesn't take any more code or time than using MOVFs, so there's
no reason not to do it.

-Andy

Andrew Warren - spam_OUTfastfwdRemoveMEspamEraseMEix.netcom.com
Fast Forward Engineering, Vista, California
http://www.geocities.com/SiliconValley/2499

1996\05\02@162433 by Scott Dattalo

face
flavicon
face
Adrian Kennard wrote:

>  <snip>
> I forgot that re-loading W would of course change the Z flag !!!
> So you must restore STATUS, then restore W, and then set or clear Z
> depending on the stored value of STATUS. What a mess...
>


Actually, only it's the  MOVF reg,W  that modifies the Z flag. However,
if you follow the Microchip data sheet (at least the 16C6x one), you'll
see entry and exit code for an interrupt routine that looks something
like:


       MOVWF   Int_W           ;Copy W to a temporay register, (could be either
bank 0 or 1)
       SWAPF   STATUS,W        ;Copy status to be saved into W. Note that a
MOVF clears Z, which
                               ;would be O.K. now but not when we exit the ISR.
       BCF     STATUS,RP0      ;Point to BANK 0
       MOVWF   Int_Stat        ;Save status in bank 0

  ;Interrupt routine ...

       SWAPF   Int_Stat,W      ;Get the original status register
       MOVWF   STATUS          ;and restore it. (This also restores the
original bank pointer)
       SWAPF   Int_W, F        ;Restore W with original value. Again, we can't
use a MOVF because
       SWAPF   Int_W, W        ;the Z flagged gets corrupted
       RETFIE                  ;Return from Interrupt

Note that the SWAPF instruction does not affect the Z flag.

You can also check out Andy W's PIC question 44 at:

http://www.geocities.com/SiliconValley/2499/answers.html#PIC16/17 Index


Scott

P.S. Adrian, you're lucky it only took a half a day to find that bug. You must
have gotten
burned like this once before!

'Interrupts and machine state'
1996\05\03@020404 by Martin J. Maney

flavicon
face
On Thu, 2 May 1996, Andrew Warren wrote:

> Sorry you wasted half a day on this.  An easier way is the
> following, which is on mmy web page and has been in the Microchip
> data books for a couple of years now:

I haven't needed to deal with interrupts yet, but I think I'm going to
want to fairly soon, so I'd like to ask some questions about this
scheme in a more general context.

>     INTW    EQU     [any page-0 register]
>     INTS    EQU     [any page-0 register]
>             ....
>     ; INTERRUPT SERVICE ROUTINE:
>     PUSH    MOVWF   INTW                    ;SAVE THE W-REGISTER.
>             SWAPF   STATUS,W                ;SAVE THE STATUS
>             MOVWF   INTS                    ;REGISTER.
          <interrupt handler runs here>
>     POP     SWAPF   INTS,W                  ;RESTORE THE STATUS
>             MOVWF   STATUS                  ;REGISTER
>             SWAPF   INTW                    ;RESTORE THE
>             SWAPF   INTW,W                  ;W-REGISTER.
>             RETFIE                          ;RETURN AND RE-ENABLE
>                                             ;INTERRUPTS.

Okay, this is pretty simple (although I don't recall noticing that it
isn't necessary to use swapf to transfer the STATUS register until you
helpfully pointed that out).  Now, how does one do this for a PIC where
the register page select actually changes the (general purpose) register
that an instruction addresses?

I've seen the app note (nominally for the 17Cxx chips) that sets up a
data stack, but while I might be able to spare the RAM locations, I
really can't stand to lose FSR.  I can see two complementary approaches,
but before I work them out I thought I'd find out if that would duplicate
work someone has already done - laziness is the way of the programmer,
no?  ;-)

1996\05\03@031417 by Shel Michaels

picon face
In a message dated 96-05-03 02:06:27 EDT, Martin Maney wrote::

{Quote hidden}

Say, Andrew - I may have missed some of this thread since my mailer is
periodically broken, but...
In the 16C74 don't you find it necessary to do the following for the sake of
completeness??  I've marked with "***" the items that may trip unwary users:

1.  Allocate a byte we'll call WAtInt in BOTH *** page 0 and page 1, at the
same page-relative address
2.  movwf WAtInt  ;save interrupted W register - we don't know which page
we're saving in, but we
                          ;  haven't saved the page bit yet, so we can't be
picky
    swapf STATUS, W  ;save STATUS into W, including page bit
    clrb RP0          ;force to page 0, now that the page bit is preserved
in W***
    movwf SwappedStatusAtInt    ;preserve status in temp location in page 0
    ;preserve other commonly used registers here, particularly including FSR
and PCLATH ***

Best regards,
...Shel Michaels
TakeThisOuTsbmichaelsRemoveMEspam@spam@aol.com
http://members.aol.com/sbmichaels

1996\05\03@110338 by Andrew Warren

face
flavicon
face
Martin J. Maney <EraseMEPICLISTRemoveMEspamMITVMA.MIT.EDU> wrote:

{Quote hidden}

Martin:

That one's also on my web page.  It looks like this:

   INTW    EQU     [any page-0 register]
   INTS    EQU     [any page-0 register]
   INTW1   EQU     INTW + 080H

           ....

   ; INTERRUPT SERVICE ROUTINE:

   PUSH    MOVWF   INTW
           MOVF    STATUS,W
           BCF     STATUS,RP0
           MOVWF   INTS
           ; save PCLATH and FSR here.

           ....

   POP     ; restore PCLATH and FSR here.
           MOVF    INTS,W
           MOVWF   STATUS
           SWAPF   INTW
           SWAPF   INTW,W
           RETFIE

-Andy

Andrew Warren - spamfastfwd.....spamspamix.netcom.com
Fast Forward Engineering, Vista, California
http://www.geocities.com/SiliconValley/2499

1996\05\03@110344 by Andrew Warren

face
flavicon
face
Shel Michaels <PICLISTspam_OUTspam@spam@MITVMA.MIT.EDU> wrote:

> Say, Andrew - I may have missed some of this thread since my mailer
> is periodically broken, but... In the 16C74 don't you find it
> necessary to do the following for the sake of completeness??

Shel:

Yes, the 16C74 context-saving code is a little more complicated.
However, the original title of this thread was "Interrupts on the
16C84".

-Andy

Andrew Warren - .....fastfwdspamspam.....ix.netcom.com
Fast Forward Engineering, Vista, California
http://www.geocities.com/SiliconValley/2499

1996\05\03@123144 by Martin J. Maney

flavicon
face
On Fri, 3 May 1996, Andrew Warren wrote:

> That one's also on my web page.

I should have thought of that.  What can I say, it was late.  :-)

> It looks like this:

That's scary - aside from the names and use of mixed case, that's exactly
what I just sketched a few minutes ago, after I came across the echo of
my question and decided to reconsider it while fully awake.  I think what
I hadn't been able to see through the late-night fog was that as long as
you know which page the saved status is in you will all but inevitably
get the page bit where W was saved during the "pop" operation.

Looking at the versions on your most excellent web page, I'm now wondering
- why two versions?  As far as I can see, they differ only in that one
saves the STATUS nibble-swapped and the other doesn't, and that in one
you set a known register page select bit before the status is copied out
of W where in the other this is done after.  Assuming that you'll need to
set a known register page anyway (and I can imagine only a very special
case where this wouldn't be needed), there seems to be no reason to have
two different code sequences for the one-page-mapped and two-pages-really
sets of PICs.

'portE glitches and interrupts'
1996\05\14@145921 by Jim Main

flavicon
face
I'm using port E on a 16C74 into a 3:8 decoder to select various latches,
with the main data going out on portD.

I'm finding that if I leave my interrupt routine running over the period
when portE is being written to - that glitches appear on portE.

The interrupt routine only updates portA, and takes an input on portB - it
shouldn't be interfering with portE, but it does... (I'm saving & restoring
status, W, and PClath in the interrupt routine)

Is this a bug in the 16C74??

Jim

'Interrupt handling'
1996\05\16@141511 by Mike Jones

flavicon
face
Apologies in advance for this question. I know I should RTFM, but I
haven't been able to lay my hands on any manuals [ BTW - does anyone
know if there are any suppliers in the UK who still have the
Embedded Control Handbook and/or the Beginner's Guide to PIC
programming still in stock? - it's been on back order at my local
branch of Maplin for _months_ ]. Anyway, here's my question:-

How do I implement an interrupt service routine (particularly for
the PIC16C84, but I guess it's roughly the same for the other
devices)? I've tried putting the address of the routine at 0x04, but
the results seem to be unpredictable - sometimes the interrupt
causes a branch (sometimes to the interrupt server, sometimes
somewhere wildly different...), and returns don't always go back to
where I think they should.

What am I doing wrong?

TIA for any help....

Mike



=================================================================
Mike Jones.        || e-mail (home) mikeKILLspamspamEraseMEnewjay.win-uk.net
Newport, Gwent, UK ||        (work) mike%EraseMEcso2.uucp@spam@spam@spam@britain.eu.net
I thought PCs were a pain in the DOS, till I discovered Linux...
=================================================================

'Context saving in interrupts'
1996\05\22@123216 by Jim Main

flavicon
face
This is the start of my interrupt service routine - it saves W, STATUS, FSR
and PCLATH.  I'm thinking however that there'll be a problem if an interrupt
occurs when STATUS,RP0 is set.... temp_w is then in the wrong register bank,
and it'll overwrite whatever that location's being used for..

The only way round it is to leave the corresponding bank1 register free, so
that it doesn't matter - but then you'd have to know which bank to look in
when it comes time to restore the registers at the end of the routine..  eg
you'd have to restore the STATUS register before restoring the W register

Does this sound ok, or is there a simpler method?



       ORG     04                      ;This is the interrupt vector

       movwf   temp_w                  ;store the contents of the w register
       swapf   STATUS,w                ;and the status register, so that they
       bcf     STATUS, RP0             ;(set RAM page 0)
       movwf   temp_stat               ;can be restored before leaving the inte
rrupt

       movf    FSR,w
       movwf   temp_FSR

       movf    pclath,w
       movwf   temp_lath

1996\05\22@133941 by myke predko

flavicon
face
Jim's Interrupt Entry below:


>
>
>        ORG     04                      ;This is the interrupt vector
>
>        movwf   temp_w                  ;store the contents of the w register
>        swapf   STATUS,w                ;and the status register, so that they
>        bcf     STATUS, RP0             ;(set RAM page 0)
>        movwf   temp_stat               ;can be restored before leaving the
interrupt
>
>        movf    FSR,w
>        movwf   temp_FSR
>
>        movf    pclath,w
>        movwf   temp_lath
>
>

Hi Jim, if you are using a PIC that has unique RAM Registers in Page 1 (and
not shadowed with the values in Page 0), you're going to have to have two
"temp_w"s in your code - each one at the same location in each of the two
pages.  That way the data won't be lost between pages.

PCLATH is NOT a readable Register (it's just writeable).  So instead of
reading it and saving it, you should save the value you are programming in,
into "temp_lath" when PCLATH is being changed.

Good Luck!

Myke
Myke

"We're Starfleet officers, weird is part of the job."

Capt. Catherine Janeway

1996\05\22@140644 by fastfwd

face
flavicon
face
Jim Main <@spam@PICLISTspamspamKILLspamMITVMA.MIT.EDU> wrote:

> This is the start of my interrupt service routine - it saves W,
> STATUS, FSR and PCLATH.  I'm thinking however that there'll be a
> problem if an interrupt occurs when STATUS,RP0 is set.... temp_w is
> then in the wrong register bank, and it'll overwrite whatever that
> location's being used for..
>
> The only way round it is to leave the corresponding bank1 register
> free, so that it doesn't matter - but then you'd have to know which
> bank to look in when it comes time to restore the registers at the
> end of the routine..  eg you'd have to restore the STATUS register
> before restoring the W register
>
> Does this sound ok, or is there a simpler method?

Jim:

The method you describe is the commonly-accepted one (it's even in
the 16C7x data book).  It'll work just fine.

-Andy

Andrew Warren - spamBeGonefastfwdRemoveMEspamEraseMEix.netcom.com
Fast Forward Engineering, Vista, California
http://www.geocities.com/SiliconValley/2499

1996\05\22@142930 by fastfwd

face
flavicon
face
myke predko <RemoveMEPICLISTKILLspamspamRemoveMEMITVMA.MIT.EDU> wrote:

> PCLATH is NOT a readable Register (it's just writeable).

Nope.  The high byte of the PC isn't DIRECTLY readable; PCLATH, a
readable/writable register that shadows the high byte of the PC,
exists for precisely this reason.

-Andy

Andrew Warren - TakeThisOuTfastfwdspamix.netcom.com
Fast Forward Engineering, Vista, California
http://www.geocities.com/SiliconValley/2499

1996\05\22@165244 by Clyde Smith-Stubbs

flavicon
face
"Andrew Warren" <spamBeGonefastfwdKILLspamspamTakeThisOuTix.netcom.com> wrote:

> Nope.  The high byte of the PC isn't DIRECTLY readable; PCLATH, a
> readable/writable register that shadows the high byte of the PC,
> exists for precisely this reason.

Ummm.. bad choice of words there, Andy. It could confuse some people -
and then we'd get a slew of followups :-( So to forestall all that...

PCLATH does not shadow the high byte of the PC, all it does is provide
some of the bits to be loaded into the high byte of the PC when an
instruction changes the low byte of the PC, such as a direct write,
an add (more common) or a CALL or GOTO (in which case some low-order
bits of PCLATH are ignored since the CALL etc. instruction provides
them anyway). How many bits of PCLATH are used depends on how large
the program memory is.

The important thing to remember is that PCLATH is *never* updated when the
PC changes for any reason - the term "shadow" can be taken to imply that
it provides a way to find the value of the high byte of the PC, which
it doesn't, only to set it.


--
Clyde Smith-Stubbs       | HI-TECH Software,       | Voice: +61 7 3300 5011
EraseMEclyde.....spamKILLspamhitech.com.au      | P.O. Box 103, Alderley, | Fax:   +61 7 3300 5246
http://www.hitech.com.au | QLD, 4051, AUSTRALIA.   | BBS:   +61 7 3300 5235
----------------------------------------------------------------------------
For info on the World's best C cross compilers for embedded systems, point
your WWW browser at http://www.hitech.com.au, or email spaminfospamhitech.com.au

1996\05\22@175331 by fastfwd

face
flavicon
face
Clyde Smith-Stubbs <PICLISTSTOPspamspamMITVMA.MIT.EDU> wrote:

> "Andrew Warren" <fastfwdSTOPspamspamKILLspamix.netcom.com> wrote:
>
> > Nope.  The high byte of the PC isn't DIRECTLY readable; PCLATH, a
> > readable/writable register that shadows the high byte of the PC,
> > exists for precisely this reason.
>
> Ummm.. bad choice of words there, Andy. It could confuse some
> people
>
> ....
>
> The important thing to remember is that PCLATH is *never* updated
> when the PC changes for any reason - the term "shadow" can be taken
> to imply that it provides a way to find the value of the high byte
> of the PC, which it doesn't, only to set it.

   Thanks for clarifying my statement, Clyde... You're right;
   reading over it now, I see that the word "shadow" was completely
   wrong.

   -Andy

Andrew Warren - @spam@fastfwd.....spamspamix.netcom.com
Fast Forward Engineering, Vista, California
http://www.geocities.com/SiliconValley/2499

1996\05\22@214804 by Jim Main

flavicon
face
Hi Myke

>PCLATH is NOT a readable Register (it's just writeable).  So instead of
>reading it and saving it, you should save the value you are programming in,
>into "temp_lath" when PCLATH is being changed.

Would this always work - say I change pclath and store it in temp_lath at
the same time, then I cross a page boundary in the code before the interrupt
occurs - wouldn't the restored pclath cause a jump backwards after the
interrupt's finished??

Jim

1996\05\22@220256 by Clyde Smith-Stubbs

flavicon
face
Jim Main <spamjmain.....spam.....cqm.co.uk> wrote:

> >PCLATH is NOT a readable Register (it's just writeable).  So instead of
> >reading it and saving it, you should save the value you are programming in,
> >into "temp_lath" when PCLATH is being changed.
>
> Would this always work - say I change pclath and store it in temp_lath at
> the same time, then I cross a page boundary in the code before the interrupt
> occurs - wouldn't the restored pclath cause a jump backwards after the
> interrupt's finished??

Forget about PCLATH being write-only - it is readable and writable, but
it is NOT the high byte of the PC. Basically, if you use PCLATH in the
interrupt routine, you must save and restore it. If you do ANY gotos
or calls in your interrupt routine, and you are using more than 1 page
of ROM (2K words on the 14 bit PICS) then you must save PCLATH, then load
it with the high byte of your current address (usually 0 for interrupt
routines, since they start at location 4).

The actual saved PC from where the interrupt occurred is on the stack,
and is NOT affected by PCLATH. When you do the RETFIE at the end of the
interrupt routine, the entire PC will be restored from the stack. But
you must treat the processor like a national park - leave it like you
found it, including PCLATH.

Of course if you are using a 14-bit PIC with 2K words of ROM or less, then
you can ignore PCLATH unless you do computed gotos (addwf PCL).

Clyde

--
Clyde Smith-Stubbs       | HI-TECH Software,       | Voice: +61 7 3300 5011
clyde.....spamhitech.com.au      | P.O. Box 103, Alderley, | Fax:   +61 7 3300 5246
http://www.hitech.com.au | QLD, 4051, AUSTRALIA.   | BBS:   +61 7 3300 5235
----------------------------------------------------------------------------
For info on the World's best C cross compilers for embedded systems, point
your WWW browser at http://www.hitech.com.au, or email KILLspaminfospam_OUTspamhitech.com.au

1996\05\23@095829 by myke predko

flavicon
face
>Jim Main <spam_OUTjmainspamTakeThisOuTcqm.co.uk> wrote:
>
cut here...
>> Would this always work - say I change pclath and store it in temp_lath at
>> the same time, then I cross a page boundary in the code before the interrupt
>> occurs - wouldn't the restored pclath cause a jump backwards after the
>> interrupt's finished??
>
>Forget about PCLATH being write-only - it is readable and writable, but
>it is NOT the high byte of the PC. Basically, if you use PCLATH in the
>interrupt routine, you must save and restore it. If you do ANY gotos
>or calls in your interrupt routine, and you are using more than 1 page
>of ROM (2K words on the 14 bit PICS) then you must save PCLATH, then load
>it with the high byte of your current address (usually 0 for interrupt
>routines, since they start at location 4).
>
cut here...
>Of course if you are using a 14-bit PIC with 2K words of ROM or less, then
>you can ignore PCLATH unless you do computed gotos (addwf PCL).
>
>Clyde
>

This whole question has been a real education for me and an exercise in
re-reading manuals.

Right now, I have three different sets of documentation at my disposal; the
1994 Data Book, the 1995/1996 Data Book, and some PDF Files I've loaded off
the Microchip Web Site.

There is a real progression in how the information is provided.  When I
originally answered the question about pages, I was using the 1994 Data Book
as a reference - in that book, a "page" is a 256 address block of Program
Memory.  Looking in the later sources, a "page" is a 2K address range of
Program Memory (a "block" is a 256 address range).

The '94 book also does not explain PCL/PCLATH as explicitly as the later
sources.

As the documentation has been updated, it has gotten better and much more
consistant.  I guess I should pitch the '94 manual and just work with the
latest ones.

Let's see if I understand the operation of PCL/PCLATH correctly now:

If you are using a low range (12 Bit instructions - 16C5x) PIC then the high
value of the PC (address bits 8 and above) are loaded from PA1:PA0 of the
Status Register, if there is greater than 512 addresses.  For devices with
512 addresses of Program Memory the ninth bit (address bit 8) of the address
will always be loaded with a zero.

If you are using a mid range device (14 bit instructions) with less than 2K
of Program Memory, the only time PCLATH is accessed is when a computed goto
(ie "addwf PCL, f") is executed.  Now, knowing this, I try to put tables as
close to address 0x00 to make sure that I have the maximum amount of table
space without having to play with PCLATH.  If I have to change PCLATH, I
make sure that all the tables set up PCLATH before executing the computed goto.

For the mid range devices with greater than 2K of memory (ie 16C7x), PCLATH
must be set up correctly for "gotos" and "calls" because the goto/call
instruction don't have enough bits for the address to be put explicitly in
the instruction.  I've never used a device that has greater than 2K of
Program Memory, so I wasn't aware of this wrinkle.

Now, the high end devices, (17C4x) with 16 bit instructions (and Program
Counter) use PCL/PCLATH in exactly the same manner as the mid range devices
with less than 2K of Program Memory except that all 8 bits of PCLATH is
loaded into the PC.

Have I got it now?

Myke
Myke

"We're Starfleet officers, weird is part of the job."

Capt. Catherine Janeway

1996\05\23@102254 by Clyde Smith-Stubbs

flavicon
face
myke@passport.ca (myke predko) wrote:

> Let's see if I understand the operation of PCL/PCLATH correctly now:
>
> If you are using a low range (12 Bit instructions - 16C5x) PIC then the high
> value of the PC (address bits 8 and above) are loaded from PA1:PA0 of the
> Status Register, if there is greater than 512 addresses.  For devices with
> 512 addresses of Program Memory the ninth bit (address bit 8) of the address
> will always be loaded with a zero.

Nearly right. The loading of bit 8 with zero occurs only on a call instruction -
a goto encodes 9 bits in the instruction, a call only 8. That can be a real
bummer.

> Now, the high end devices, (17C4x) with 16 bit instructions (and Program
> Counter) use PCL/PCLATH in exactly the same manner as the mid range devices
> with less than 2K of Program Memory except that all 8 bits of PCLATH is
> loaded into the PC.

Not quite.  The 16 bit PICs operate a little differently to the others. Firstly,
PCLATH *does* get updated from the high byte of the PC in most cases, unlike the
14 bit PICs. But it gets worse; The CALL and GOTO instructions do NOT copy
bits out of PCLATH, rather they leave the high order 3 bits of the PC alone,
supplying 13 bits from the instruction. But the new PCH gets copied into PCLATH.

IF you write to PCL then PCLATH gets copied to PCH, just like the 14 bitters,
but reading PCL also updates PCLATH with PCH. There's also an LCALL instruction
-
stands for Long CALL but curiously enough it only has 8 bits of address in
the instruction! The remaining 8 bits come from PCLATH, unlike the "standard"
CALL instruction. There's no LGOTO instruction, but you can achieve this with
movwf pcl.

Not everything that updates PCH updates PCLATH; normal PC increment does not,
nor do RETURN, RETLW or interrupts.

Confused? Aren't we all!

--
Clyde Smith-Stubbs       | HI-TECH Software,       | Voice: +61 7 3300 5011
.....clyde.....spamRemoveMEhitech.com.au      | P.O. Box 103, Alderley, | Fax:   +61 7 3300 5246
http://www.hitech.com.au | QLD, 4051, AUSTRALIA.   | BBS:   +61 7 3300 5235
----------------------------------------------------------------------------
For info on the World's best C cross compilers for embedded systems, point
your WWW browser at http://www.hitech.com.au, or email spam_OUTinfoTakeThisOuTspamEraseMEhitech.com.au

1996\05\24@002247 by Steve Childress

flavicon
face
My understanding, and hence my code, is that you must allocate the same memory
location in all banks for, as you note it below, "temp_w". This is because as
you say
there is no assurance as to which page is active at the time of the interrupt.
So
I allocate the first RAM location in all pages to this temp location. Uck.

EraseMEstevecspamBeGonespamKILLspamrain.org


----------
From:   Jim Main[SMTP:RemoveMEjmainspamBeGonespamspamCQM.CO.UK]
Sent:   Wednesday, May 22, 1996 9:32 AM
To:     Multiple recipients of list PICLIST
Subject:        Context saving in interrupts

This is the start of my interrupt service routine - it saves W, STATUS, FSR
and PCLATH.  I'm thinking however that there'll be a problem if an interrupt
occurs when STATUS,RP0 is set.... temp_w is then in the wrong register bank,
and it'll overwrite whatever that location's being used for..

The only way round it is to leave the corresponding bank1 register free, so
that it doesn't matter - but then you'd have to know which bank to look in
when it comes time to restore the registers at the end of the routine..  eg
you'd have to restore the STATUS register before restoring the W register

Does this sound ok, or is there a simpler method?



       ORG     04                      ;This is the interrupt vector

       movwf   temp_w                  ;store the contents of the w register
       swapf   STATUS,w                ;and the status register, so that they
       bcf     STATUS, RP0             ;(set RAM page 0)
       movwf   temp_stat               ;can be restored before leaving the
interrupt

       movf    FSR,w
       movwf   temp_FSR

       movf    pclath,w
       movwf   temp_lath

'MPLAB-SIM and USART Interrupts'
1996\05\31@110025 by Peter L. Taylor

flavicon
face
-- [ From: Peter L. Taylor * EMC.Ver #2.5.02 ] --

I'm using a 16c74 to gather data off of some sensors I've attached to it.
Currently, the PIC will only gather the data when it receives a command from
a PC that is hooked to the serial port.

Up until now, I have been simulating with MPSIM to just make sure the PIC is
doing what I thought I programed it to do.  In MPSIM to simulate a USART
receive, I set the contents of the RCREG and then set PIR<5> to simulate a
receive interrupt.  This works fine. To simulate a transmission interrupt, I
just set PIR<4>.

Now I am trying to simulate the same program in the new MPLAB-SIM 3.01.  It
will let me change the RCREG, but I can't set PIR<5>, to simulate my serial
reception.  For transmission, MPLAB-SIM won't let me set PIR<4>.

What is the correct procedure to simulate USART transmission and reception
with the new MPLAB-SIM?

(No, I haven't been to the seminar, yet.  It will be in Salt Lake at the end
of June, and I plan on going, but would like to start using MPLAB-SIM now
and not wait until the end of June.)


--
Peter L. Taylor
~~~~~~~~~~~~~~~~~~~~~~~~
Email: @spam@petertspamspamtransera.com
~~~~~~~~~~~~~~~~~~~~~~~~
http://www.transera.com
~~~~~~~~~~~~~~~~~~~~~~~~
TransEra Corp.
345 East 800 South
Orem, Utah 84058
~~~~~~~~~~~~~~~~~~~~~~~~
Voice:  (801)224-6550
Fax:    (801)224-0355
~~~~~~~~~~~~~~~~~~~~~~~~


'pointer to info on using multiple interrupts on 16'
1996\06\01@180028 by David E. Queen
flavicon
face
I plan on usering both the timer1 and portB interrupt on change in a 16C65 and
I ado not see the info that tells me how to handle multiple interrupts,
could someone point me the right .pdf file and section?

1996\06\01@181724 by Clyde Smith-Stubbs

flavicon
face
"David E. Queen" <TakeThisOuTdqueenKILLspamspam@spam@nnl.net> wrote:

> I plan on usering both the timer1 and portB interrupt on change in a 16C65 and
> I ado not see the info that tells me how to handle multiple interrupts,
> could someone point me the right .pdf file and section?

There is only one interrupt; you have to test inside the interrupt routine
what bits are set to determine the interrupt source, and branch to appropriate
code.

Clyde

--
Clyde Smith-Stubbs       | HI-TECH Software,       | Voice: +61 7 3300 5011
.....clydeRemoveMEspamhitech.com.au      | P.O. Box 103, Alderley, | Fax:   +61 7 3300 5246
http://www.hitech.com.au | QLD, 4051, AUSTRALIA.   | BBS:   +61 7 3300 5235
----------------------------------------------------------------------------
For info on the World's best C cross compilers for embedded systems, point
your WWW browser at http://www.hitech.com.au, or email KILLspaminfospamTakeThisOuThitech.com.au

'Interrupts On The 16c74'
1996\06\10@051842 by pic

flavicon
face
Hi all,

I have been working on a 16c74 design which uses many different interrupt
sources. My question is, what happens if another interrupt occurs while
an ISR is executing ?

I realise GIE is off during an interrupt service, but will the PIC
jump to the interrupt vector when it returns from the first interrupt
simply because is see's that another interrupt flag has been set?

Thanks in advance for any help!

Wayne.

------------------------------------
Wayne G Boyd
(Digital Sys. Eng.)
E-mail: TakeThisOuTwaynespamspam_OUTjce.wintermute.co.uk
------------------------------------

1996\06\10@052254 by Clyde Smith-Stubbs

flavicon
face
pic<RemoveMEpicspamspamSTOPspamjce.wintermute.co.uk> wrote:

> I realise GIE is off during an interrupt service, but will the PIC
> jump to the interrupt vector when it returns from the first interrupt
> simply because is see's that another interrupt flag has been set?

Yes.

--
Clyde Smith-Stubbs       | HI-TECH Software,       | Voice: +61 7 3300 5011
.....clydeEraseMEspamhitech.com.au      | P.O. Box 103, Alderley, | Fax:   +61 7 3300 5246
http://www.hitech.com.au | QLD, 4051, AUSTRALIA.   | BBS:   +61 7 3300 5235
----------------------------------------------------------------------------
For info on the World's best C cross compilers for embedded systems, point
your WWW browser at http://www.hitech.com.au, or email spamBeGoneinfospamRemoveMEhitech.com.au

'RB Port Change Interrupt on the '84'
1996\06\11@110119 by myke predko

flavicon
face
Hi Gang,

I seem to remember somewhere that there was a problem with the RB Port
Change interrupt on the 16C84.  Does anybody know more about it?

Thanx,

Myke
Myke

"We're Starfleet officers, weird is part of the job."

Capt. Catherine Janeway

1996\06\11@141257 by John Payson

flavicon
face
> I seem to remember somewhere that there was a problem with the RB Port
> Change interrupt on the 16C84.  Does anybody know more about it?

In a nutshell, any instruction which does a write to any port will also do
a preceding read.  For most ports, this is not an issue since reading them
has little effect other than moving a few extra electrons around.  Reading
port B, however, will cause the compare latches to be read and clear any
pending interrupt-on-change condition.

Thus, the problems are these: [1] When doing a write to the port, the int-
on-change feature may be cleared; if the write happens just as the port
changes, the interrupt may never get flagged. [2] If a read happens just as
the port changes, the interrupt may never get flagged.

1996\06\11@214247 by Onat Ahmet

flavicon
face
>>>
> I seem to remember somewhere that there was a problem with the RB Port
> Change interrupt on the 16C84.  Does anybody know more about it?


Thus, the problems are these: [1] When doing a write to the port, the int-
on-change feature may be cleared; if the write happens just as the port
changes, the interrupt may never get flagged. [2] If a read happens just as
the port changes, the interrupt may never get flagged.
<<<

So, is there a workaround for this problem? Such as checking
for the interrupt flag before reading or writing to RB port?

Thanks;

| Ahmet ONAT  Kyoto Univ. Japan                                 |
| E-mail    : .....onatEraseMEspamkuee.kyoto-u.ac.jp                           |
| WWW page  : http://turbine.kuee.kyoto-u.ac.jp/staff/onat.html |
|             My 6 leg walker, RC airplanes & more in home page |

1996\06\11@235537 by Martin J. Maney

flavicon
face
On Wed, 12 Jun 1996, Onat Ahmet wrote:

> So, is there a workaround for this problem? Such as checking
> for the interrupt flag before reading or writing to RB port?

There's the work-around described in the datasheet (this has been in
there for at least some of the 16Cxx parts for a while):

 "The interrupt on change feature is recommended for wake-up on key
  depression operation and operations where PORTB is used only for the
  interrupt on change feature.  Polling of PORTB is not recommended
  while using the interrupt on change feature."

I also recall that Microchip said, some time ago, that future revisions
would fix this feature, but I don't recall just how future that was to be.
I think it may be fixed in the A-suffix versions of the 16C7x chips, etc.

1996\06\12@003138 by Neil Gandler

flavicon
face
On Tue, 11 Jun 1996, Martin J. Maney wrote:

> On Wed, 12 Jun 1996, Onat Ahmet wrote:
>
> > So, is there a workaround for this problem? Such as checking
> > for the interrupt flag before reading or writing to RB port?
>
> There's the work-around described in the datasheet (this has been in
> there for at least some of the 16Cxx parts for a while):
>
>   "The interrupt on change feature is recommended for wake-up on key
>    depression operation and operations where PORTB is used only for the
>    interrupt on change feature.  Polling of PORTB is not recommended
>    while using the interrupt on change feature."
>

So are you saying that if someone was to use a pin on port B with
the interrupt on change, that the rest of the ports pins shouldnt be
used for any other application?
I don't quite understadn what you meant.

               Neil Gandler

1996\06\12@004640 by John Payson

flavicon
face
>> Thus, the problems are these: [1] When doing a write to the port, the int-
>> on-change feature may be cleared; if the write happens just as the port
>> changes, the interrupt may never get flagged. [2] If a read happens just as
>> the port changes, the interrupt may never get flagged.
>
> So, is there a workaround for this problem? Such as checking
> for the interrupt flag before reading or writing to RB port?

For non-critical applications, checking the interrupt flag before or after
reading/writing the port will work most of the time, as will simply checking
when reading the port to see if it (the value read back) has changed.  This
will not work 100%, however, since the port value might change just as the
port is being read, resulting in the 'read' getting the old port state and
the latches getting the new state.

If this feature is being used in, e.g., a push-button remote control where
a failed interrupt detect will result in another button being pushed (which
WOULD then get detected) this is not a major problem; most consumers won't
notice if their controller misses a button push every 10,000 closures.  In
applications where a missed change-detect could result in a frozen system
(e.g. port B senses a relay closure which will remain until the system clears
it) other methods of sensing input changes should be used.

1996\06\12@012956 by John Payson

flavicon
face
>  So are you saying that if someone was to use a pin on port B with
> the interrupt on change, that the rest of the ports pins shouldnt be
> used for any other application?
> I don't quite understadn what you meant.

That's pretty much what it means, I'm afraid.  Basically there is one real
use for the interrupt-on-change feature that actually works fairly well:
using a PORTB trigger to wake from sleep.  While this will not be 100%
reliable in cases where the trigger condition may be "pre-existing", it is
good enough to be used for things like remote controls and items like that.

Further, even in a remote-control context it may be possible to make the
port B trigger reliable: if one can ensure that all the inputs WILL be in
an inactive state before the last time portB is read before sleep, then
any time they become active will cause an interrupt.  For example, assume
a keyboard is wired 4x4 using PB0-PB3 as output and PB4-PB7 as input.  The
following will cause the CPU to go to sleep but re-awaken if and when any
button is pushed [assuming pullups on PB0-PB3]:

       bsf     RP0     ; Bank 1
       movlw   $FF
       movwf   PORTB   ; Set TRISB to all inputs
       bcf     RP0     ; Bank 0
       clrf    PORTB   ; Prepares PORTB to ground outputs 0-3, but doesn't
                       ; do it YET [because of TRIS].
       bsf     RP0
       movlw   $F0
       movwf   PORTB   ; Set 4 LSB's to low outputs.  NOTE: This instruction
                       ; does NOT access PORTB and so cannot clear the PORTB
                       ; latches!
       bcf     RP0     ; Back to bank 0
       ...
       sleep           ; Frere Jacques... dormez-vous?

1996\06\12@023129 by Martin J. Maney

flavicon
face
On Wed, 12 Jun 1996, Neil Gandler wrote:

> On Tue, 11 Jun 1996, Martin J. Maney wrote:
> > There's the work-around described in the datasheet (this has been in
> > there for at least some of the 16Cxx parts for a while):
> >
> >   "The interrupt on change feature is recommended for wake-up on key
> >    depression operation and operations where PORTB is used only for the
> >    interrupt on change feature.  Polling of PORTB is not recommended
> >    while using the interrupt on change feature."
> >
>
>  So are you saying that if someone was to use a pin on port B with
> the interrupt on change, that the rest of the ports pins shouldnt be
> used for any other application?
> I don't quite understadn what you meant.

No, you've got it, near enough.  As John has explained (and given a nice
example of its intended use), this really isn't of much use as a general
interrupt source as you might expect in a general purpose machine.

About all I can think of to add is the observation that even if you can
afford to "waste" the rest of PORTB this probably can't be made entirely
reliable for more general use.  The catch is that you HAVE to read the
port in order to clear the interrupt that has occured, and that read can
cause another interrupt to be missed.  Not very often, perhaps, but if
you can't afford to miss the change...  (and, I tend to think, if you
could afford to miss an occasional change, forget about the interrupt on
change and just poll it from time to time and detect the changes
yourself - as many pins, on whatever ports as you need.)

1996\06\12@031140 by Prashant Bhandary

flavicon
picon face
I kinda anticipated these problems and what I intend to do in
one of my apps is use one of the PortB pins to read a bitstream
and interrupt on change. The Port B Change ISR sets the other
output pins on this port. The RTCC is set to interrupt on
wraparound. In case there is no change on Port B for a few RTCC
wraparounds I write to the port.

The bitstream is dynamic enough so that the PortB outputs don't
get delayed significantly. In case the bitstream is idle, the
RTCC interrupt will update the port after a few idle RTCC wraparounds.
This will mean I lose any port B changes that occur at that time
but any bits after a long idle period will have enough preceding sync
bits before sending anything important.

Anybody see any flaws in this scheme?

For those who followed the Model RR/DCC thread, the Port B input
reads the DCC signal. Port A does the PWM H bridge driving. The
other Port B pins are function outputs that control things like
lights, etc. which can tolerate some latency. On a 10 MHz 16C84,
the RTCC cycles every ~100us. This is used as the PWM base and
for timing the bitstream.

Regards

Prashant
+----------------+  -------------------------------------------------
|                |    Prashant Bhandary
|   +---+        |    Spatial Information Systems Section
|   |   |        |    Roads and Traffic Authority
|   |   |        |    Rosebery NSW 2018, AUSTRALIA
|   |   |        |    Tel:  +61-2-662 5299
|   |   +----+   |    Fax:  +61-2-662 5348
|   |        |   |    Email: spamprashbspam_OUTspam@spam@rta.nsw.gov.au
|   +--------+   |
| Still a newbie |    "2b|!2b" - William Shakespeare
+----------------+  -------------------------------------------------

1996\06\12@112458 by myke predko

flavicon
face
All yesterday afternoon and evening, my ISP was down, so I couldn't see all
the messages/suggestions, so I did the next best thing; I tried it empirically.

The reason for asking this is my version of the Electronics Now Runabout
Robot (March '96).  In my original code, I used RB0 and looked at each edge
(going up or down).  I wanted to try the bit change interrupt for two
reasons; The first was to allow two I/R receivers (essentially getting 360
degree coverage) without having to AND the outputs together before
intputting into the PIC.  The second reason was that my original code
required changing the interrupt edge and I thought that using the bit change
interrupt would eliminate this requirement.

So, I created some code to do try this out.  The hardware was simply the two
I/R receivers along with two LEDs to indicate when the Interrupt Handler was
entered and which of the I/R receiver was active (basically just copying the
port back to the LEDs in the interrupt handler).

The first problem I found was with the LED's on PORTB.  Initialization and
writing to them seemed to screw up how the bit change interrupt wasworking.
Moving the LEDs to PORTA seemed to clear this up without any problems.

In my final application, I require four output bits to control the two
motors, these can be used from PORTA without any problems (and maybe an
additional bit for indicating when an instruction is being received) and not
use PORTB for anything else.

Now, I'm curious to know if I can use other PORTB bits for Input.  ie will a
"movf PORTB, w" instruction to poll other bits cause a problem with port
change bits?

Thanx,

Myke
{Quote hidden}

Myke

"We're Starfleet officers, weird is part of the job."

Capt. Catherine Janeway

1996\06\12@130122 by Neil Gandler

flavicon
face
On Wed, 12 Jun 1996, Martin J. Maney wrote:

{Quote hidden}

____

I just want to make sure I got this. If I have one input on PORT B
lets say PB7, with 3 leds on PB0-PB2. And I can't spare port B since
I am using the PIC16C61. If I use the interrupt on change feature and
I change the state of one of the LEDs that would trigger the state
change interrupt? Also an idea to prevent the ocassionaly miss of a
switch. Just make sure the keys are well debounced with a small delay.
The interrupt routine lasts perhaps for less than 1ms ( unless your
code is huge), I don't know how many people can repeatedly press
a button every millisecond.

       Neil Gandler

1996\06\12@191605 by John Payson

flavicon
face
> I just want to make sure I got this. If I have one input on PORT B
> lets say PB7, with 3 leds on PB0-PB2. And I can't spare port B since
> I am using the PIC16C61. If I use the interrupt on change feature and
> I change the state of one of the LEDs that would trigger the state
> change interrupt? Also an idea to prevent the ocassionaly miss of a
> switch. Just make sure the keys are well debounced with a small delay.
> The interrupt routine lasts perhaps for less than 1ms ( unless your
> code is huge), I don't know how many people can repeatedly press
> a button every millisecond.

Actually, the problem is just the opposite: if the user pushes the button
precisely at the time you change the state of the LED's, the interrupt
WOULDN'T happen until the button again changed state [e.g. the user released
it].  Further, there is no really good way to check whether the button has
been pushed without reading the port; if the button's pushed precisely as
the port has read, the same potential problem still exists.

1996\06\12@205905 by Martin J. Maney

flavicon
face
Myke and Neil seem to be asking much the same question this afternoon, so
just one reply to both.  :-)

On Wed, 12 Jun 1996, myke predko wrote:

> Now, I'm curious to know if I can use other PORTB bits for Input.  ie will a
> "movf PORTB, w" instruction to poll other bits cause a problem with port
> change bits?

In earlier PICs with the interrupt on change (again, sorry, I don't seem
to have saved the message that mentioned when this was (supposed to be?)
fixed - perhaps the 16CxxA and recent non-A parts?), basically any
access, read or write, to PORTB will cause the latch that is part of the
change-detect logic to be reset.  This is exactly how you were intended
to reset it, in fact, but it proves to restrict the use one can make of
the interrutp on change for any application other than waking the PIC up
from sleep.  The PIC does internal reads (as part of a generic
read/operate/write cycle) of PORTB for at least reads, writes, or bit
operations on PORTB.

However, you can use PORTB pins for output if you're willing to go to
some small bother, and you can live with what amounts to an
open-collector output.  The trick would be to write all zeros to the
PORTB pins not used for interrupt-on-change, and to control the state of
these pins through TRISB.  Come to think of it, you could get active pull
up or down from each pin, depending on whether you set it to 0 or 1,
couldn't you?

Warning!  Warning!  I haven't tested this idea!  It's probably not
original with me, but I can't recall seeing it described before -
probably memory failure on my part, as it's pretty obvious after it's
been described, isn't it?  ;-)

There's been some discussion about when the PIC might unexpectedly read
PORTB, but I don't recall that we've ever gotten an authoritative answer
to some fascinating (and troublesome, if you want to use interrupt on
change) speculations about this.


PS: nothing is new... I was about to send this off when I remembered that
I've seen the trick of controlling an output by writing to TRIS instead
of the data register in a couple places - I think it's suggested for
driving the I2C bus, for example.  I've been browsing the specs and app
notes for this recently, so that's probably the spark.


'Interrupt flags (was TMR0 "gotcha")'
1996\07\09@034719 by Chaipi Wijnbergen
flavicon
picon face
On Mon, 8 Jul 1996, myke predko wrote:

> If you enable the timer in the 16C84 (ie direct OSC/4 to it) and NOT enable
> the interrupts (ie T0IE), the Timer0 Overflow Flag (T0IF) in INTCON will be
> set on Timer0 overflow.
>
> This isn't mentioned in the datasheets (although the overflow bit shown in
> the block diagrams shows that T0IF being set without being gated by T0IE).

I am using the 16C74, here, interrupt sources will set the interrupt
flag even if the interrupt is disabled, therefor, in the interrupt
service routine, I check to see it the interrupt flag is set, and if it
is then, I clear the interrupt flag and then check if the interrupt is
enabled, only if it is, then I do the things I need to do.

Chaipi


                              \\\|///
                            \\  ~ ~  //
                             (  @ @  )
----------------------------oOOo-(_)-oOOo--------------------------------------
!                                                                             !
! Chaipi Wijnbergen                                                           !
! Electronics/Computer Eng. M.Sc.  Tel    : +972-8-9343079                    !
! Optical Imaging Laboratory       Fax    : +972-8-9344129                    !
! Brain Research Center            Email  : spamchaipi@spam@spamSTOPspamtohu0.weizmann.ac.il       !
! Weizmann Institute of Science    URL    : http://www.weizmann.ac.il/~chaipi !
! Rehovot 76100 ISRAEL             IPhone : chaipi                            !
!                                                                             !
------------------------------------Oooo.--------------------------------------
                         .oooO     (   )
                         (   )      ) /
                          \ (      (_/
                           \_)

'TIMER 2 Interrupt Question:'
1996\07\09@122330 by Anson Fung

flavicon
face
I am currently work on a program which controls the speed of 2 motors (left
and right motors of a car). I am making use of the CCP module inside the
PIC16C74 to generate the PWM signal for the motors.

At the same time, I am making use of the TIMER2 interrupt which will get
into Interrupt Service Routine everytime TIMER2 is overflow in order to
change the speed of the car. What will happen if the ISR is so long that
TIMER2 is overflow again before the ISR is completed? Will it go back into
the ISR again right after the previous ISR is completed, or the previous ISR
will get interrupted and the new ISR will start?

Anson.

1996\07\10@041159 by Chaipi Wijnbergen

flavicon
picon face
On Tue, 9 Jul 1996, Anson Fung wrote:

> What will happen if the ISR is so long that
> TIMER2 is overflow again before the ISR is completed? Will it go back into
> the ISR again right after the previous ISR is completed, or the previous ISR
> will get interrupted and the new ISR will start?

Anson,

While the ISR is executing the global interrupt enable bit is reset, so,
no other interrupt can come through, also, you do not want to manualy
enable this bit, since, you are limited by the size of the hardware stack
(8 levels on the 16C74), and the way that we save the W, Status, FST &
PCLATH makes the ISR a non reentrent routine.

So, If you think that your routine might be too long, then clear the
interrupt flag as soon as posible (inside the ISR) and then do one of
two things:

- Wait until the ISR is finished and then if there is a new interrupt
 then the ISR will start again.

- Or, before exiting the ISR, check the interrupt flag again for another
 interrupt and reexecute the code of the ISR.

Chaipi

                              \\\|///
                            \\  ~ ~  //
                             (  @ @  )
----------------------------oOOo-(_)-oOOo--------------------------------------
!                                                                             !
! Chaipi Wijnbergen                                                           !
! Electronics/Computer Eng. M.Sc.  Tel    : +972-8-9343079                    !
! Optical Imaging Laboratory       Fax    : +972-8-9344129                    !
! Brain Research Center            Email  : spamBeGonechaipispamBeGonespam@spam@tohu0.weizmann.ac.il       !
! Weizmann Institute of Science    URL    : http://www.weizmann.ac.il/~chaipi !
! Rehovot 76100 ISRAEL             IPhone : chaipi                            !
!                                                                             !
------------------------------------Oooo.--------------------------------------
                         .oooO     (   )
                         (   )      ) /
                          \ (      (_/
                           \_)


'Interrupt latency'
1996\09\23@011723 by Steve Hardy
flavicon
face
Does anyone have a definitive answer for the following?

If the PIC16CXX is executing a goto, the manual states that the
CPU executes an internal NOP in place of the following instruction
which was prefetched (but not executed).

When an interrupt occurs, it could interrupt the goto in one of two
places: during the fetch of the goto or during the execution of the
NOP.

Alternatively, the architecture could block the interrupt until the
NOP is completed.

The first case implies that when the interrupt returns, it could
execute the pending NOP.  The second implies that an interrupt can
be delayed by up to one instruction cycle.  What actually happens?

The answer has implications for using the PIC as a clock generator.
E.g. assume TMR0 is set to interrupt every 256 instruction cycles.
Now if the mainline code is simply

loop    nop
       goto    loop

then, since the interrupt will occur at each one of 3 points (nop,
goto fetch, implicit nop) then the interrupt routine's timing may
exhibit subharmonics of the 256-cycle basic timing (i.e. 1 cycle
jitter) if the second alternative is actually implemented.  There
would be no jitter with the first alternative.

I have looked on an oscilloscope, but can't see any jitter; but then
again perhaps the 'scope's resolution isn't good enough (it's an old
20MHz analogue).

Regards,
SJH
Canberra, Australia

1996\09\23@100049 by John Payson

picon face
> Does anyone have a definitive answer for the following?
>
> If the PIC16CXX is executing a goto, the manual states that the
> CPU executes an internal NOP in place of the following instruction
> which was prefetched (but not executed).
>
> When an interrupt occurs, it could interrupt the goto in one of two
> places: during the fetch of the goto or during the execution of the
> NOP.
>
> Alternatively, the architecture could block the interrupt until the
> NOP is completed.

According to my understanding of the documentation, the first cycle follow-
ing an interrupt will either be a "skip" cycle [if the instruction just
executed was a skip] which advances the PC or a "dummy" cycle which does
not.  While the latency between the interrupt triggering and it being taken
will be constant, the total time taken by the interrupt may not; in prac-
tice this will almost never be an issue.

1996\09\23@184612 by TONY NIXON 54964

flavicon
picon face
I can't see that any interupt latency would matter on a simple clock.
The TMR0 IRQ bit will always be set every 256 cycles. Whether an
extra instruction, or not, is executed with the IRQ code does not
matter, as long as all the code fits into the IRQ timing space.
It's the same as trying to get the secs, mins and hours to update
simultaneously for the sake of accuracy. This of course can't be done
with a single processor, but it works fine anyway.

Regards

Tony


Just when I thought I knew it all,
I learned that I didn't.

1996\09\23@213417 by Steve Hardy

flavicon
face
> From: TONY NIXON 54964 <RemoveMEAnthony.nixonRemoveMEspamRemoveMEeng.monash.edu.au>
>
> I can't see that any interupt latency would matter on a simple clock.
> The TMR0 IRQ bit will always be set every 256 cycles. Whether an
> extra instruction, or not, is executed with the IRQ code does not
> matter, as long as all the code fits into the IRQ timing space.
>  It's the same as trying to get the secs, mins and hours to update
> simultaneously for the sake of accuracy. This of course can't be done
> with a single processor, but it works fine anyway.

This is true, but not only is the clock expected to have an average period
of 256 cycles, in this application it must also have a consistent cycle-to-
cycle period of _exactly_ 256 cycles.  This may not occur if the interrupt
latency is variable.

To clarify: suppose the average rate is 1000Hz (exactly).  Now suppose
every third interrupt has an extra cycle of latency (say 1us).  Then the
sequence of timings between each pulse is then

  1000us  1001us  999us

Fourier analysis would reveal small but significant harmonic content at
333.333 Hz.

John Payson <supercatKILLspamspamspammcs.net> says that there is in fact constant latency
in the PIC.  This is goodness.

Regards,
SJH
Canberra, Australia


'TOCK1 Interrupt'
1996\10\24@125627 by John Piccirillo
flavicon
face
Hi,

  I'm working my way through the beginners Easy Pic'N book and ran into a
problem with an exercise using the TOCK1 interrupt on RA4.  The program
(below)seems simple enough but the circuit doesn't catch the external clock
signal on RA4.  Basically, the program turns on a PORTB pin (LED) and waits
for a clock transition on RA4 to jump to an ISR which turns the pin off.
The problem may not be in the program.  I tried using a logic pulser for the
external clock signal (connecting it to ground an +5 on the circuit board)
and tried a slide switch between gnd and +5 on the board.  A meter shows
that +5 is getting on RA4 and a 'scope shows that the logic pulser is giving
a clean 0 - 5 v. transition.  On the other hand, if I attach a short wire
going nowhere to RA4, the LED goes out after several seconds.  I understand
that an open CMOS input will change states easily, but why doesn't it change
when it's pulsed??

;                       PICT17.ASM
;  timer/counter demo
;      external clock, no prescaler
;      interrupt timer

       list    p=16c84
       radix   hex

;   destination equates
w       equ     0
f       equ     1

;   file register equates
tmr0    equ     01
portb   equ     06
intcon  equ     0b

       org     0
       goto    start

       org     4
       goto    isr

start   movlw   0x00
       tris    portb
       clrf    portb
       bcf     intcon,2
       bsf     intcon,7
       bsf     intcon,5

       clrf    tmr0
       clrwdt
       movlw   b'01111111'
       option
       clrf    tmr0
       bsf     portb,1
circle  goto    circle

isr     bcf     portb,1
       bcf     intcon,2
       bcf     intcon,5
       retfie

       end

Thanks in advance.

John-




  -----------------------------------------------------------------
   John Piccirillo                 e-mail:  spam_OUTjpicciri@spam@spamnebula.tbe.com
   Teledyne Brown Eng./MS 200      phone:   205/ 726-3908
   300 Sparkman Drive              FAX:     205/ 726-2469
   Huntsville, AL  35807
   -----------------------------------------------------------------

1996\10\24@222745 by TONY NIXON 54964

flavicon
picon face
I think your program will work ok but not as you wanted.
TMR0 will increment with each transition of RA4 but the interupt will
only be serviced after TMR0 overflows. So you would have to toggle
RA4 256 times.

If RA4 is configured as an input with no pull up/down resistor
connected, then it may float between logic levels. As RA4 is a
shcmitt trigger input, it will then increment TMR0's counter turning off
the LED at random time intervals.

Use RB0 as your trigger detect.

Tony


Just when I thought I knew it all,
I learned that I didn't.

1996\10\25@012451 by Bob Bob XXVIII

flavicon
face
I an no expert on pics but inorder for pin RA.4 to work...it has to be held
high...I use a 330 ohm resistor....
if you haven't tried this....just connect a 330 ohm or something close to it
from pin RA.4 to +5 volts and see if it works...don't change anything else
though....
And if you have tried this...GOOD LUCK....:)

'Interrupt on change'
1996\10\25@175339 by Bob Blick

picon face
Hi all,

It's my understanding that if interrupt-on-change is enabled, it is enabled
for all four pins(RB4,5,6,7), no choosing. Let's use a PIC16C72 as an example.

I'm not clear on the use of those four pins if some are used solely as
output pins. My questions are:

If I use two of the pins(RB4,5) for outputs, the other two(RB6,7) for
inputs, and enable interrupt-on-change, will my manipulation of the two
output pins cause an interrupt, or otherwise mangle the correct operation of
the interrupt?

Second question: will reading port B mess with the use of the
interrupt-on-change feature? Do I need to use the first four pins(RB0,1,2,3)
of port B output-only if I enable interrupt-on-change? Must I read port B
only when servicing the interrupt?

Thanks, Bob

1996\10\26@104010 by John Payson

picon face
> It's my understanding that if interrupt-on-change is enabled, it is enabled
> for all four pins(RB4,5,6,7), no choosing. Let's use a PIC16C72 as an example.
>
> I'm not clear on the use of those four pins if some are used solely as
> output pins. My questions are:
>
> If I use two of the pins(RB4,5) for outputs, the other two(RB6,7) for
> inputs, and enable interrupt-on-change, will my manipulation of the two
> output pins cause an interrupt, or otherwise mangle the correct operation of
> the interrupt?

Changing the outputs will not trigger the interrupt; even if something
external to the device forces the outputs to change that will not trigger
the interrupt.  HOWEVER...

> Second question: will reading port B mess with the use of the
> interrupt-on-change feature? Do I need to use the first four pins(RB0,1,2,3)
> of port B output-only if I enable interrupt-on-change? Must I read port B
> only when servicing the interrupt?

Either reading or writing to the port will CLEAR the interrupt on many/most
16Cxx variants.  I think there is a supposed fix on the later parts to avoid
this, but I have not tried it.  Note that on these later parts, PORTB is now
required to change long enough to be latched (I don't know what that means
if the part is asleep).

1996\10\26@104426 by fastfwd

face
flavicon
face
Bob Blick <TakeThisOuTpicsspam_OUTspamparallaxinc.com> wrote:

> It's my understanding that if interrupt-on-change is enabled, it is
> enabled for all four pins(RB4,5,6,7), no choosing. Let's use a
> PIC16C72 as an example.
>
> I'm not clear on the use of those four pins if some are used solely
> as output pins. My questions are:
>
> If I use two of the pins(RB4,5) for outputs, the other two(RB6,7)
> for inputs, and enable interrupt-on-change, will my manipulation of
> the two output pins cause an interrupt, or otherwise mangle the
> correct operation of the interrupt?

   Bob:

   No.  The change-on-portb interrupt is only triggered when INPUT
   pins change states.

> Second question: will reading port B mess with the use of the
> interrupt-on-change feature?

   Probably.  If a change occurs just as a read operation is being
   performed on port B, no interrupt will be generated.

   Worse, it seems that even WRITING to port B can make the PIC
   miss interrupts, since ALL register accesses (even MOVWF, etc.)
   perform a read first.

> Do I need to use the first four pins(RB0,1,2,3) of port B
> output-only if I enable interrupt-on-change? Must I read port B only
> when servicing the interrupt?

   Doing those things will HELP the situation, but they won't
   guarantee that you'll never miss interrupts.  In general, the only
   time the change-on-portb interrupts are truly reliable is when
   they're used to wake the processor from Sleep Mode.

   As I said in the answer to a similar question posted to my
   company's web page, "Sucks, don't it?"

   Sorry to be the bearer of bad news.

   -Andy

=== Andrew Warren - KILLspamfastfwd.....spamTakeThisOuTix.netcom.com                 ===
=== Fast Forward Engineering - Vista, California          ===
===                                                       ===
=== Custodian of the PICLIST Fund -- For more info, see:  ===
=== http://www.geocities.com/SiliconValley/2499/fund.html ===

'Problems with PCLATH, Long Calls and Interrupts (P'
1996\10\26@153955 by NEIL GANDLER

flavicon
face
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

1996\10\27@141221 by fastfwd

face
flavicon
face
NEIL GANDLER <TakeThisOuTPICLISTEraseMEspamRemoveMEMITVMA.MIT.EDU> 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.

Neil:

It sounds as though you're not properly resetting PCLATH after
calling your subroutines.  After an inter-page call, you must reset
the PCLATH register:

   MOVLW   HIGH destination
   MOVWF   PCLATH
   CALL    destination
   MOVLW   HIGH ($+2)
   MOVWF   PCLATH

In your interrupt handler, you must do three things:

   1.  Save the PCLATH value at the start of the interrupt handler
   (right after you save W and STATUS).

   2.  DO NOT let your interrupt code execute any GOTOs or calls
   until after PCLATH is saved.  This seems obvious, but you'd be
   amazed at how often people will put a GOTO right at the
   interrupt vector (address 0x04).

   3.  Restore PCLATH at the end of your interrupt handler (just
   before restoring W and STATUS).

Everything should work fine if you follow these guidelines.

-Andy

Andrew Warren - spam_OUTfastfwdRemoveMEspam.....ix.netcom.com
Fast Forward Engineering, Vista, California
http://www.geocities.com/SiliconValley/2499

1996\10\28@085831 by Mike Riendeau

flavicon
face
>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,

I use the following fragment. It doesn't modify w and uses
goto's and calls carefully. I use a register "SaveRP" to record
the interrupted page and ram bank setting. My interrupt routine
is in page1. You can change that if you wish. Leave enough room
at the interrupt vector for the following code. It's a little
ugly, but if anybody else has a better way, I would love to
see it. You can't depend on the regular swaps to save the ram
bank setting, because you have to define it in order to save the
page setting.

ORG IntVector
btfss PCLATH,3   ;Interrupted a page1 routine
goto $+11        ;goto is safe, already using page0
bcf   PCLATH,3   ;set page0 so we can use goto's
btfss STATUS,RP0 ;Test which ram bank is set
goto $+4
bcf   STATUS,RP0 ;Set bank0 so we can use SaveRP register
bsf   SaveRP,1   ;Save bank1 status
goto $+2
bcf   SaveRP,1   ;Save bank0 status
bsf   SaveRP,0   ;set page1 as saved page
bsf   PCLATH,3   ;interrupt routine in page 1
goto  Int_svc    ;vector to interrupt service
btfss STATUS,RP0 ;Test which ram bank is set
goto $+4
bcf   STATUS,RP0 ;Set bank0 so we can use SaveRP register
bsf   SaveRP,1   ;Save bank1 status
goto $+2
bcf   SaveRP,1   ;Save bank0 status
bcf   SaveRP,0   ;set page0 as saved page
bsf   PCLATH,3   ;interrupt routine in page 1
goto  Int_svc    ;vector to interrupt service


Int_svc:
      (save w)
      (save status)
      (save fsr)
.     blah.. blah.. blah..
 .
 .
 .    (restore fsr)
      (restore status)
      (restore w)
      bcf STATUS,RP0 ;Set bank0
      btfss SaveRP,0 ;Test page setting
      bcf   PCLATH,3 ;set page0
      btfsc SaveRP,1 ;test bank setting
      bsf STATUS,RP0 ;set bank1
      retfie


'Interrupts moving in stange ways'
1996\11\01@081827 by tjaart
flavicon
face
This is the first time I have seen anything like this, and its driving
me nuts.

I am sending a buffer of characters to the UART on the 16C74 with an
interrupt. As soon as I use TMR0 I start getting weird effects on the
RS232. My baud rate is 300 baud, and the time that the TMR0 code spend
in the interrupt service routine, is WAY shorter than the RS232 byte
rate.

Hey docter - is that funny white jacket with the long sleeves for me?

--
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             |
|______________________________________________________________|

'Interrupts (17C44) in MPLAB-SIM?'
1996\11\08@070203 by liebchen

flavicon
face
Hi all,

I have a working program for a 17C44.
It uses some interrupt driven routines for sending and receiving
characters through serial line and for timers.
Although the program runs in real silicon, the simulator doesn't
create any interrupts?!?
The version of MPLAB is 3.10.??. Is there a known bug in the simulator
for 17C44 or do I myself have a bug?
Would version 3.12 help?
I would appreciate your help!

regards Wolfram

--

+------------------------------------------------+
! Wolfram Liebchen, Forschungsinstitut fŸr Optik !
! spamliebchenKILLspamspamKILLspamffo.fgan.de                    !
+------------------------------------------------+

'Interrupt problems with 16C74'
1996\11\17@141530 by Jim Main

flavicon
picon face
For some reason, my interrupts have stopped working.

I think it's something to do with Program memory bank 1 - my code's
gotten to the stage where I've had to start dumping routines into the
second bank - calling them from the first bank.

When I call a routine in bank 1 and loop there waiting for an interrupt
driven timer to time out, it never does - it just goes round and round
the loop.  The SCI interrupt and the keyboard interrupt don't work
either.

What's happening?  I've checked and double checked that GIE is set and
doesn't get disabled anywhere else - and I presume that when an
interrupt happens when the code's in page 1 that it'll still jump back
to the interrupt vector at 04h.

I'm saving context ok in the interrupt (W,Status,FSR and PCLATH) - and
in fact the interrupt code never seems to get run at all (I put a port
flag in to check and it never gets set)

Any ideas?
--
Jim

1996\11\17@234508 by Steve Hardy

flavicon
face
> From: Jim Main <spamjimspam_OUTspamEWCOMM.DEMON.CO.UK>
>
> For some reason, my interrupts have stopped working.
>
> I think it's something to do with Program memory bank 1 - my code's
> gotten to the stage where I've had to start dumping routines into the
> second bank - calling them from the first bank.
>
> When I call a routine in bank 1 and loop there waiting for an interrupt
> driven timer to time out, it never does - it just goes round and round
> the loop.  The SCI interrupt and the keyboard interrupt don't work
> either.
>
> What's happening?  I've checked and double checked that GIE is set and
> doesn't get disabled anywhere else - and I presume that when an
> interrupt happens when the code's in page 1 that it'll still jump back
> to the interrupt vector at 04h.

GIE is not the only flag.  The individual int enables must be set.

>
> I'm saving context ok in the interrupt (W,Status,FSR and PCLATH) - and
> in fact the interrupt code never seems to get run at all (I put a port
> flag in to check and it never gets set)
>
> Any ideas?
> --
> Jim
>

Will need to see your code to help further.  Have you checked your
assembler listing to ensure code is at the expected places?  What
PIC are you using and what development environment simulator or emulator?

Regards,
SJH
Canberra, Australia

1996\11\18@130226 by Bob Blick

picon face
I've got no experience with the problem you're outlining, but here's what
I'd look at:

Have you tried making the interrupt service routine immediately turn on an
LED, not even save any registers, to see if the interrupt is really getting
called?

Do you have mirrored registers in both bank 0 and 1 for saving the status
register in? You might be accidentally trashing a register you're using for
something else.

Neither of these addresses the use of code in the second page of memory,
which if what you said started the problem, but maybe you started using the
second bank of registers about the same time as you started using the second
page of ROM, and you're looking in the wrong place for the problem.

Cheers, Bob

{Quote hidden}

1996\11\18@134344 by Shawn Ellis

flavicon
face
{Quote hidden}

Sounds like your program may be getting a little large for .asm.  If speed
is not too critical, you might consider a "C" compiler from CCS.  It will
handle page bank switching and interrupts for you and it's only $100.  It
saved me mountians of time!

1996\11\18@170845 by TONY NIXON 54964

flavicon
picon face
These problems can be very hard to trace, especially in large multi
page programs.
As the processor is very obedient, it likes to do what it is told and not what
we want it to do. It sounds as though you forgot to set/reset a ROM or RAM
page bit correctly when you transferred your code to the upper page.

This may be painstaking, but you may have to trace your code through
with MPSIM. Set a break point at the first instruction of the
interupt routine and see if it does break at that point. If it does,
follow your code through the interupt. If it doesn't get to the
interupt break point you will have to monitor your code to see if
a page bit is changed to the wrong state. Make sure that the status
etc. are restored correctly after the IRQ.
I would concentrate on monitoring the code that you moved. You can also
try 'steering' the program to code that you want to test by using GOTO's to
bypass excessive timing loops etc. and to test certain code fragments.
This makes debugging a little easier with larger programs

FrUstratioN is part of the fun of programming.

Hope this helps

Tony


Just when I thought I knew it all,
I learned that I didn't.

1996\11\19@151812 by Jim Main

flavicon
picon face
>Have you tried making the interrupt service routine immediately turn on an
>LED, not even save any registers, to see if the interrupt is really getting
>called?

Solved it!  Your suggestion put me on the right track.

What was happening was - the interrupt happened only once and then never
again.  I'd correctly implemented the context saving bits of code - but
I'd forgotten to explicitly clear PCLATH,3 after saving PCLATH to a
temp_lath register.  So, if PCLATH,3 was set and an interrupt occured
(as it would when I was looping around in page 1), then the first GOTO
in the interrupt routine would jump to page 1 (shortly before the loop
as it happened!) and since the RETFIE never happened, the interrupt
never happens again, and it just loops indefinitely.

Easy in hindsight isn't it!!!
--
Jim

1996\11\19@220911 by Dwayne Reid

flavicon
face
>For some reason, my interrupts have stopped working.
>
>I think it's something to do with Program memory bank 1 - my code's
>gotten to the stage where I've had to start dumping routines into the
>second bank - calling them from the first bank.
>
>When I call a routine in bank 1 and loop there waiting for an interrupt
>driven timer to time out, it never does - it just goes round and round
>the loop.  The SCI interrupt and the keyboard interrupt don't work
>either.
snip
>I'm saving context ok in the interrupt (W,Status,FSR and PCLATH) - and
>in fact the interrupt code never seems to get run at all (I put a port
>flag in to check and it never gets set)

One idea: do you do something like:

       org 04
       goto interrupt

If so, the goto is the problem... pclath is pointing to ROM Pg1 and you jump
to somewhere not intended.  The way that I handle it is to put all the
context saving stuff right at the start as follows:

   ORG         00H
   goto        COLDBOOT

   ORG         04H
;save W, STATUS, PCLATH, FSR
   movwf       W_SAVE          ;save w (could be on either ram page)
   movfw       STATUS          ;status register now trashed
   clrf        STATUS          ;ensure ram page 0
   movwf       S_SAVE          ;good copy of status register in Page 0
   movfw       PCLATH          ;remember to also save FSR if necessary
   movwf       P_SAVE
   clrf        PCLATH          ;ensure ROM page 0

;which interrupt?  Parse interrupt flags here to reduce jumps (and time)
   btfsc       INTF            ;RB0 interrupt?
     goto      RB0_ISR
   btfss       T0IF            ;timer 0 interrupt?
     goto      TMR0_ISR
   goto        INT_END         ;this shouldn't happen!


;jump tables live here


;interrupt routines live here


'Unwanted Periodic Interrupt'
1996\12\09@210437 by Chong Wei Pang
flavicon
face
Hello...

       Can anyone help me with this problem. I am using the PIC16C65A for my
project.
I use MLAB 3.12 in simulation mode to do the programming. Since 65A is not
in the list
of processors  simulated by MLAB, I choose 74A. The problem I encounter is
that I
keep on getting periodic receive interrupt during the simulation. I really
wonder what
have I missed out. How can I get receive interrupt when there is nothing to
trigger
it? I wanted to use the USART receive interrupt but I just cannot figure
out why it
keep on interrupting me periodically with nothing to trigger it.

       Is there any configurations I need to set in MLAB or any registers I nee
d
to set?
I have turned of al the other unwanted interrupt ( at least I think ) by
setting the
values of INTCON to B'11010000', PIE1 to B'00100000' and PIE2 to
B'00000000'.
All assistance will be greatly appreciated. Pls. bear with me if the
question seem to be
elementary......


Chong
STOPspamchongwpspam_OUTspamspamBeGoneadroit.com.sg

'Change on PORTB interrupt'
1996\12\11@153746 by D. R. Chicotel

flavicon
face
I am using MPSIM with a stimulus file which changes pins 4 and 5 on PortB
(PIC16C64).
I am trying (desperately) to cause a Change on PortB interrupt to happen.
When the
pins change value, the interrupt (at org 0x04) is not called.  I can see
that INTCON
changes though.  Does MPSIM simulate this interrupt or am I just wishing?
If it
does, obviously I have some code problems.  This is my first attempt at
using this
interrupt.  I thought I followed AN566 (Using the PortB Int. on Change as
an...) and
AN552 (Implementing Wake-up on Key Stroke) pretty closely.   What am I
forgetting?
If anyone has sample code (bare bones) that does this, could you please
share it.

Thanks alot in advance.   DRC

'PIC 16C84 interrupts'
1996\12\23@090204 by Wendal Carkner

flavicon
face
I'd like article on RB4-7 interrupt on change function occasionally failing.
Wendal Carkner

1996\12\23@100615 by John Payson

picon face
> I'd like article on RB4-7 interrupt on change function occasionally failing.

Essentially, what happens is that on the PIC any read or write [even MOVWF]
to the port B register will latch the compare register; if a port pin happens
to change just as such a read or write is taking place, it's possible for
there never to be a mismatch because the comparator could be comparing 0<->0
at one moment and 1<->1 the next.

Later PICs have logic to deal with this, though as a consequence they may not
detect changes shorter than one clock cycle.  I don't know how this circuitry
works when the chip goes into "sleep" mode [since one clock cycle could be a
REALLY LONG time...


'saving context during interrupts'
1997\01\05@120138 by Eric Johnson
flavicon
face
When saving status during interrupts on the 16c74,
 Microchip recommends the following:
movwf   W_Temp         ;Copy W to TEMP register, could be bank one or zero
swapf   STATUS, w      ;Swap status to be saved into W
bcf     STATUS, RP0    ;Change to bank zero, regardless of current bank
movwf   STATUS_TEMP    ;Save status to bank zero STATUS_TEMP register
:(ISR)
swapf   STATUS_TEMP, w ;Swap STATUS_TEMP register into W
                     ;(sets bank to original state)
movwf   STATUS         ;Move W into STATUS register
swapf   W_TEMP, f      ;Swap W_TEMP
swapf   W_TEMP, w      ;Swap W_TEMP into W

 Why not:
swapf   W_Temp         ;save w with nibbles reversed, could be either bank
swapf   STATUS, w      ;get status and reverse the nibbles
bcf     STATUS, RP0    ;set bank 0
movwf   STATUS_TEMP    ;save old status with nibbles reversed
:(ISR)                ;interrupt service routine
swapf   STATUS_TEMP, w ;get old status
movwf   STATUS         ;restore old status (and bank register)
swapf   W_TEMP, w      ;get back w with correct nibble order

By pre-swapping w, it looks like I can save a step.

 I also like to:
movf    FSR, w        ;get indirect file select register
movwf   Temp_Fsr, f   ;save indirect files select register
:(ISR)                  ;interrupt routine
movf    Temp_Fsr, w   ;get saved indirect file select register
movwf   FSR, f        ;restore indirect files select register
clrwdt               ;clear watchdog timer

What do you guys think?

Eric Johnson- Champaign, Illinois USA.
spam_OUTlazrbitespamspamBeGonepdnt.com

1997\01\05@125026 by Brooke

flavicon
face
Eric Johnson wrote:
>
> When saving status during interrupts on the 16c74,
>   Microchip recommends the following:
> movwf   W_Temp         ;Copy W to TEMP register, could be bank one or zero

Note that W_Temp MUST be defined so that it appears in the same location
independent
of the RP0 (RP1, ...) bits. For example W_Temp equ h'20' AND W_Temp equ
h'A0'.

{Quote hidden}

This is not the proper syntax for swapf.
The assembler will convert the above instruction to swapf W_Temp,F
ie. swap the nibbles in file W_Temp and put the result into file F
(W_Temp).

The syntax is: swapf f,d where f=a file(RAM) location and d=destination
(W or F)
Note that in the Harvard architecture there are no instructions that
move data
from one file (RAM) location to another file (RAM) location.  Data
always moves
to/from the W register.  This is because there are not enough bits in a
single
command word to contain 2 file (RAM) addresses.  Von Neumann machines
use a
variable number of bytes/instruction to handle this.

{Quote hidden}

Required if you are using FSR.  DO after STATUS & W are saved.

Thanks for asking, I think I now understand this better myself,
Brooke

PS I wonder if Harvard architecture machines would be easier to
understand
if the instructions that worked with RAM were different from
instructions
that worked with the program space in some way that made it clear which
space was being used?

'saving context during interrupts -PART 2'
1997\01\05@135458 by Brooke

flavicon
face
Eric Johnson wrote:
>
> When saving status during interrupts on the 16c74,
>   Microchip recommends the following:
> movwf   W_Temp         ;Copy W to TEMP register, could be bank one or zero

This is VERY important.
The movf & swapf instructions only have 7 (NOT 8) bits for the ram
address.
They use the value in RP0 for the high order bit.  At the time of the
interupt
the RP0 bit might be a 0 or 1 (unknown to the ISR when movwf W_Temp is
executed).
W_Temp is defined like normal and "Dummy" is defined so that the lower
seven
bits of Dummy match W_Temp but with the msb different.
When the interupt occurs and the movwf W_Temp instruction is executed,
the value of W_Temp will have the lower seven bits be those from the
W_Temp
defination but the upper bit will be wherever the RP0 bit is set.

> swapf   STATUS, w      ;Swap status to be saved into W
> bcf     STATUS, RP0    ;Change to bank zero, regardless of current bank
> movwf   STATUS_TEMP    ;Save status to bank zero STATUS_TEMP register
> :(ISR)
> swapf   STATUS_TEMP, w ;Swap STATUS_TEMP register into W
>                       ;(sets bank to original state)

This is important because the RP0 bit is part of STATUS.
Once status is restored so is RP0 so when we do swapf W_Temp,F
the data from the correct bank will be read.  This is why
upon restoring the values the STATUS register MUST be done first.

{Quote hidden}

PS the above ", f' is not allowed since this instruction moves W to
Temp_Fsr.
>

Thanks again, this has been of great help to me,
Brooke

1997\01\05@201347 by Jim Main

flavicon
picon face
In article <EraseME32CFE892.5BEFspamKILLspampacific.net>, Brooke <EraseMEbrookeRemoveMEspamPACIFIC.NET>
writes
>> When saving status during interrupts on the 16c74,
>>   Microchip recommends the following:
>> movwf   W_Temp         ;Copy W to TEMP register, could be bank one or zero
>
>Note that W_Temp MUST be defined so that it appears in the same location
>independent
>of the RP0 (RP1, ...) bits. For example W_Temp equ h'20' AND W_Temp equ
>h'A0'.

I don't see anyone mentioning PCLATH context saving here! Essential if
you venture into page 1 of program memory..

To do it, you would add..

>
>> swapf   STATUS, w      ;Swap status to be saved into W
>> bcf     STATUS, RP0    ;Change to bank zero, regardless of current bank
>> movwf   STATUS_TEMP    ;Save status to bank zero STATUS_TEMP register
  movf    PCLATH,w
  movwf   temp_lath
  bcf     PCLATH,3       ;this line is crucial, otherwise your first
                         ;GOTO or CALL in the ISR could jump into the
                         ;other program page with terminal results..
                         ;(this is assuming your ISR resides in page 0)
>> :(ISR)

  movf    temp_lath,w
  movwf   PCLATH
>> swapf   STATUS_TEMP, w ;Swap STATUS_TEMP register into W
>>                       ;(sets bank to original state)
>> movwf   STATUS         ;Move W into STATUS register
>> swapf   W_TEMP, f      ;Swap W_TEMP
>> swapf   W_TEMP, w      ;Swap W_TEMP into W

--
Jim Main
.....jimspamspam_OUTewcomm.demon.co.uk
Visit Eastwood Communications at http://www.ewcomm.demon.co.uk
Broadcast Electronics & Custom Design

1997\01\05@211842 by aab

flavicon
face
In mail.pic you write:

>Note that in the Harvard architecture there are no instructions that
>move data
>from one file (RAM) location to another file (RAM) location.

I believe that this is a characteristic of load-store architectures
(what used to be called RISC). Harvard means seperate data and code
memory spaces.

>Data always moves
>to/from the W register.  This is because there are not enough bits in a
>single command word to contain 2 file (RAM) addresses.  Von Neumann machines
>use a variable number of bytes/instruction to handle this.

Von-neumann means combined data & code memory. Either could use
memory to memory instructions or variable sized instructions and still
be harvard or von-neumann.

Then again, I can't find a basic computer architecture text right
now to check this so I could be mis-remembering.

I hope this is of interest to my fellow pic'ers.

1997\01\05@213302 by John Payson

picon face
> I don't see anyone mentioning PCLATH context saving here! Essential if
> you venture into page 1 of program memory..
>
> To do it, you would add..

> >> swapf   STATUS, w      ;Swap status to be saved into W
> >> bcf     STATUS, RP0    ;Change to bank zero, regardless of current bank
> >> movwf   STATUS_TEMP    ;Save status to bank zero STATUS_TEMP register
>    movf    PCLATH,w
>    movwf   temp_lath
>    bcf     PCLATH,3       ;this line is crucial, otherwise your first
>                           ;GOTO or CALL in the ISR could jump into the
>                           ;other program page with terminal results..
>                           ;(this is assuming your ISR resides in page 0)

A couple of points to consider, though:

[1] If your ISR has no program-control instructions, there is no need to
   save/restore PCLATH at all.  While the concept of an ISR without any
   program-control instructions may seem ridiculous, such a thing is not
   at all out of the question given the btfss/btfsc,incfsz/decfsz opcodes.
   In addition, for an ISR which will 'usually' execute very quickly and
   then leave, it may be useful to do something like:

ISR:
       movwf   WSAVE
       swapf   STATUS,w
       bcf     STATUS,5
       movwf   STSAVE
       ... do the common stuff here
       swapf   STSAVE,w
       movwf   STATUS
       swapf   WSAVE,f
       swapf   WSAVE,w
       decfsz  Counter
        retfie
       bcf     STATUS,5
       movf    PCLATH
       movwf   PCSAVE
       clrf    PCLATH
       ... do the rare stuff here
       movf    PCSAVE,w
       movwf   PCLATH
       swapf   STSAVE,w
       movwf   STATUS
       swapf   WSAVE,w
       retfie

This will waste three cycles in the "rare" case but will save four in the
common case.  Another independent--though sometimes useful--technique, is
to split the common and rare cases this way:

       movwf   WSAVE
       swapf   STATUS,w
       bcf     STATUS,5
       movwf   STSAVE
       .. do the common stuff here
       swapf   STSAVE,w
       movwf   STATUS
       swapf   WSAVE,f
       swapf   WSAVE,w
       decfsz  Counter
        retfie
       bsf     INTCON,7        ;Global interrupt enable
       movwf   WSAVE2
       swapf   STATUS,w
       bcf     STATUS,5
       movwf   STSAVE2

       movf    PCLATH,w        ; If needed
       movwf   PCSAVE

       .. do the rare stuff here

       movf    PCSAVE,w        ; If needed
       movwf   PCLATH

       swapf   STSAVE2,w
       movwf   STATUS
       swapf   WSAVE2,f
       swapf   WSAVE,f
       retfie                  ; Or return--doesn't really matter

Note that this latter formulation allows the rare part of the ISR to take
longer than one interrupt-time to complete.  Of course, if it takes too
long it may impact the performance of the main program and if it takes
much too long it may recurse and trash its saved registers.

[2] If the ONLY reason you are saving PCLATH is so you can clear bit 3,
   and if you know that the main program never uses it for computed
   gotos in the second half of either page, you may simplify the code
   a little bit thus:



       movwf   WSAVE
       swapf   STATUS,w
       movwf   STSAVE
       rlf     PCLATH          ; Old bit 3 is now in bit 4, which is
                               ; ignored.  Old bit 2, which we know to
                               ; be zero, is in bit 3.
       .. ISR goes here
       rrf     PCLATH          ; All is as it was, except that bit 4
                               ; (which the '74 ignores) is trashed.
       swapf   STSAVE,w
       movwf   STATUS
       swapf   WSAVE,f
       swapf   WSAVE,w
       retfie

1997\01\07@021450 by Marv

flavicon
face
Hi,
 As long as we are on the topic, has anyone considered and resolved the
context save problem for the PIC 16C554?  Microchip recommends, on the data
sheet, the same routine that is currently being discussed for the 16C74.
This is problematic on the '554 as it has no bank 1 RAM!

Thanks in advance for any suggestions,
  Marv

1997\01\07@123946 by Dwayne Reid

flavicon
face
Eric Johnson wrote:

>When saving status during interrupts on the 16c74,
>  Microchip recommends the following:
>movwf   W_Temp
       small snip
>
>  Why not:
>swapf   W_Temp         ;save w with nibbles reversed, could be either bank

You CAN'T do this!  The object is to save W during the ISR.  Performing the
swapf like you show just swaps the nybbles in W_Temp but does NOT move the
current contents of W to W_Temp.  Using swapf W_Temp,W won't work either: it
just copies the swapped nybbles from W_Temp to W, overwriting what was in W.

Sorry to dash what would be a good idea.  I'm sure most of us on the list
have spent hours trying to cut the number of cycles it takes for context
saving.  Personally, I tailor context saving to the bare minimum that each
program requires.  This is one place where a "one size fits all" macro
doesn't cut it.

Dwayne

'RCA 1802 interrupt'
1997\01\09@121203 by Marv

flavicon
face
>Bob Fehrenbach wrote

>...
>The electronics was built around an RCA 1802 processor - anyone else
>ever use one of these?  No interrupts, no onboard timers, no call
>instruction, all indirect addressing.  A fun project.
>

 Point of fact: The RCA 1802, indeed, has an interrupt.

An old timer,
 Marv


'How fast can the PC handle interrupts from LPT1'
1997\02\26@140154 by Norm Cramer
flavicon
face
I am trying to measure some pulse widths using the PC.  I would like to use
the printer port interrupt as my timing input.  How fast can the PC handle
the interrupts (i.e. can it handle them at about a 50usec interval?)  This
will be under DOS.  Also how long does the interrupt pulse need to be to
get seen.  (i.e. would a 2usec pulse every 50usec get seen by the PC?)

The PIC relation is that the pulses are being generated by a PIC.

BTW thanks to all who helped with the PC timing info.

Thanks,

Norm

1997\02\27@194443 by sdavidson

flavicon
face
Not sure how fast the PC can respond, but for timing the resolution of the PC
clock under Windows is about 50ms.  I would suggest using a 20MHz PIC timing
the pulses and passing the data to the PC.

Steve
--- On Wed, 26 Feb 1997 13:00:11 -0600  Norm Cramer <@spam@cramerEraseMEspamspamDSEG.TI.COM>
wrote:
I am trying to measure some pulse widths using the PC.  I would like to use
the printer port interrupt as my timing input.  How fast can the PC handle
the interrupts (i.e. can it handle them at about a 50usec interval?)  This
will be under DOS.  Also how long does the interrupt pulse need to be to
get seen.  (i.e. would a 2usec pulse every 50usec get seen by the PC?)

The PIC relation is that the pulses are being generated by a PIC.

BTW thanks to all who helped with the PC timing info.

Thanks,

Norm


-----------------End of Original Message-----------------

-------------------------------------
E-mail: sdavidsonTakeThisOuTspamKILLspamits.bldrdoc.gov
Steven Davidson
Dept. of Comm.  NTIA-ITS.N2
325 Broadway
Boulder, CO  80303
W 303-497-3411  FAX 5995
-------------------------------------

1997\02\27@201853 by Robert Zeff

flavicon
face
True, for ordinary timers.  But, for Win95 and WinNT there
are multimedia timers that can resolve much better than
50mS. Multimedia timers are required for accurate timing
for MIDI data.  Also, in WinNT there are performance timers
which can resolve to 50uS or so.  I've used them to get
reasonable measurements to 200us.  Also, the ordinary
printer ports drivers do not use interrupts, but are polled
after a timer event.  IE, you tell your machine to print,
then the following happens:
1.  Set timer interrupt.
2.  See if port can accept data on timer interrupt.

So, what I did was set a performance timer interrupt for 100us
and check the port for data on each interrupt.
It was a fast machine, a dual PPro..

Regards
             \\\|///
           \\  ~ ~  //
            (  @ @  )
+----------oOOo-(_)-oOOo---------+
|                                |
|          Robert Zeff           |
|        RemoveMErzeffTakeThisOuTspamNikola.com        |
|        http://Zapco.com        |
|        http://Nikola.com       |
|        ^^^^^^^^^^^^^^^^^       |
| Free circuit simution software |
|                                |
+----------------Oooo------------+
         oooO   (   )
        (   )    ) /
         \ (    (_/
          \_)


----------
> From: @spam@sdavidsonSTOPspamspamITS.BLDRDOC.GOV
> To: TakeThisOuTPICLISTTakeThisOuTspamRemoveMEMITVMA.MIT.EDU
> Subject: Re: How fast can the PC handle interrupts from LPT1
> Date: Thursday, February 27, 1997 5:26 PM
>
> Not sure how fast the PC can respond, but for timing the resolution of
the PC
> clock under Windows is about 50ms.  I would suggest using a 20MHz PIC
timing
> the pulses and passing the data to the PC.
>
> Steve
> --- On Wed, 26 Feb 1997 13:00:11 -0600  Norm Cramer <spam_OUTcramerspamspam.....DSEG.TI.COM>
> wrote:
> I am trying to measure some pulse widths using the PC.  I would like to
use
> the printer port interrupt as my timing input.  How fast can the PC
handle
> the interrupts (i.e. can it handle them at about a 50usec interval?)
This
{Quote hidden}


'Tmr1 interrupt on a 16C73'
1997\03\20@155652 by mike
flavicon
picon face
Hi,

I am having problems with the interrupt on Tmr1 on a C73.

I have it configured to interrupt from a RC0, I set Tmr1H
and Tmr1L to $FF.

The first time a +ve edge comes along I get the interrupt,
which is then followed by 3 other +ve edges, I do what I have
to do, then on leaving the interrupt handler set Tmr1H and
Tmr1L back to $FF and clear the Tmr1IF ready for the next time.

The next +ve edge comes along and gets ignored. The one after
that causes an interrupt and off I go, but this time I am
one edge out of sync.

Anyone got any ideas?

Thanks and regards,


Mike Watson

1997\03\20@190855 by Andrew Warren

face
flavicon
face
Mayes uk <spamBeGonemikespamspam_OUTd-m-g.demon.co.uk> wrote:

> I am having problems with the interrupt on Tmr1 on a C73.
>
> I have it configured to interrupt from a RC0, I set Tmr1H
> and Tmr1L to $FF.
>
> The first time a +ve edge comes along I get the interrupt,
> which is then followed by 3 other +ve edges, I do what I have
> to do, then on leaving the interrupt handler set Tmr1H and
> Tmr1L back to $FF and clear the Tmr1IF ready for the next time.
>
> The next +ve edge comes along and gets ignored. The one after
> that causes an interrupt and off I go, but this time I am
> one edge out of sync.
>
> Anyone got any ideas?

Mike:

Is it possible that, rather than ignoring 3 edges while you're in
your interrupt service routine, you're actually ignoring FOUR?  If
you're still in the interrupt routine when the edge you want comes
through, clearing the TMR1IF flag will keep it from being processed.

I don't know how you're ignoring those three edges, but if you're
actually counting those edges in the ISR, you should clear the TMR1IF
flag IMMEDIATELY after seeing the third ignored edge.  That way, if
the fourth edge comes through before you exit the ISR, it'll generate
an interrupt as soon as your RETFIE is executed.

Did that make sense?  If not, let me know and I'll rephrase it... I'm
pretty tired right now.

-Andy

=== Andrew Warren - EraseMEfastfwd.....spamix.netcom.com
=== Fast Forward Engineering, Vista, California
=== http://www.geocities.com/SiliconValley/2499

1997\03\21@044541 by mike

flavicon
picon face
In message  <spam199703210007.SAA21738KILLspamspam@spam@dfw-ix9.ix.netcom.com> PICLISTspamspamTakeThisOuTMITVMA.MIT.EDU
writes:
> Mike:
>
> Is it possible that, rather than ignoring 3 edges while you're in
> your interrupt service routine, you're actually ignoring FOUR?  If
> you're still in the interrupt routine when the edge you want comes
> through, clearing the TMR1IF flag will keep it from being processed.
>
> I don't know how you're ignoring those three edges, but if you're
> actually counting those edges in the ISR, you should clear the TMR1IF
> flag IMMEDIATELY after seeing the third ignored edge.  That way, if
> the fourth edge comes through before you exit the ISR, it'll generate
> an interrupt as soon as your RETFIE is executed.
>
> Did that make sense?  If not, let me know and I'll rephrase it... I'm
> pretty tired right now.
>
Andy,

That made perfect sense - thanks.

I am counting the edges in the ISR. The edges are about 100us
apart. The next group is some 5ms later. I have a port pin
set when I enter the ISR and clear when I leave, and I have
left the ISR before the 1st edge of the second group.

Regards,


Mike Watson

1997\03\21@205315 by The LeBlanc's

flavicon
face
----------
{Quote hidden}


'Interrupt problem'
1997\04\29@121148 by FrankT
picon face
I use 3 interrupts with the 16c74, I2C,Timer1 and Timer0

Timer 0 is a system timer wich interrupts every ms
Timer 1 is used with the compare register to generate a frequency signal on
a port pin. The signal
can be changed and switched on/off via i2c.
I2c interrupt decodes the received mixed mode I2C command.

This works fine for some time, but after some actions I don't return in my
main loop? What can cause this ?

Frank Temmerman

1997\04\29@123808 by Miller, Steve

flavicon
face
>I use 3 interrupts with the 16c74, I2C,Timer1 and Timer0

>Timer 0 is a system timer wich interrupts every ms
>Timer 1 is used with the compare register to generate a frequency signal
on
>a port pin. The signal
>can be changed and switched on/off via i2c.
>I2c interrupt decodes the received mixed mode I2C command.

>This works fine for some time, but after some actions I don't return in
my
>main loop? What can cause this ?

>Frank Temmerman


Frank,

The most common reason for this is that interrupts are occurring
simultaneously and you are not handling this condition properly.

1.  Look carefully on how you are handling interrupts occurring within
interrupts and the piority that you are using.

2.  Physically disable one interrupt at a time and see if the problem
goes away.  If you find that disabling one or more interrupts keeps the
code running, then look at those areas of the interrupt handler code.

Good Luck.

----- Steve

1997\04\30@003132 by tjaart

flavicon
face
FrankT wrote:
>
> I use 3 interrupts with the 16c74, I2C,Timer1 and Timer0
>
> Timer 0 is a system timer wich interrupts every ms
> Timer 1 is used with the compare register to generate a frequency signal on
> a port pin. The signal
> can be changed and switched on/off via i2c.
> I2c interrupt decodes the received mixed mode I2C command.
>
> This works fine for some time, but after some actions I don't return in my
> main loop? What can cause this ?
>
> Frank Temmerman

Check to see if your ISR is not longer than any of the timer interrupt
periods. This will keep your program in the ISR forever.

--
Friendly Regards

Tjaart van der Walt
spamBeGonetjaartKILLspamspamwasp.co.za
_____________________________________________________________
| Another sun-deprived R&D Engineer slaving away in a dungeon |
|             WASP International  http://wasp.co.za           |
|             GSM and GPS value-added applications            |
|  Voice : +27-(0)11-622-8686   |   Fax : +27-(0)11-622-8973  |
|_____________________________________________________________|


'Interrupt problem'
1997\05\02@042810 by Jon Mills
flavicon
face
It sounds like it could be a stack overflow problem to me..

'example c-code, handeling interrupts'
1997\05\12@063613 by FrankT

picon face
can anybody tell me where I can find some example c-code on how to handles
multiple interrupts (enabeling global interrupt, save and restore context
etc...)
FrankT

1997\05\12@235249 by Mike Smith

flavicon
face
For what C compiler?  It tends to be handled as a non-standard extension to
C

MikeS
<mikesmith_oz@spam@spamKILLspamrelaymail.net>

----------
> From: FrankT <EraseMEgymnaRemoveMEspam@spam@COMPUSERVE.COM>
> To: RemoveMEPICLISTspamspamEraseMEMITVMA.MIT.EDU
> Subject: example c-code, handeling interrupts
> Date: Monday, 12 May 1997 19:53
>
> can anybody tell me where I can find some example c-code on how to
handles
> multiple interrupts (enabeling global interrupt, save and restore context
> etc...)
> FrankT

1997\05\13@030027 by FrankT

picon face
At the moment I am using Mplab-C compiler on the 16c74


Frank Temmerman

1997\05\13@033955 by tjaart

flavicon
face
FrankT wrote:
>
> At the moment I am using Mplab-C compiler on the 16c74
>
> Frank Temmerman

I hate to tell you this, but Microchip has kindly neglected
adding the context saving section to the 16C74.h file. This
means you have to wade through the following registers and
decide which have to be saved for an interrupt :

temp_WREG
__WImage
temp_WImage
temp_STATUS
temp_PCLATH
temp_FSR
__FSRImage
temp_FSRImage
__longAC
__longAC_H
__longIX_L
__longIX_H
temp_longAC_L
temp_longAC_H
temp_longIX_L
temp_longIX_H

If you complain about it (as I have ad naseum), there will be
one more voice in the choir.

Here we go again :
**************************************************************
**Please Microchip, fix up the obvious bugs and omissions us**
** plebians have paid good money for.                       **
**************************************************************

--
Friendly Regards

Tjaart van der Walt
STOPspamtjaart.....spamwasp.co.za
_____________________________________________________________
| Another sun-deprived R&D Engineer slaving away in a dungeon |
|             WASP International  http://wasp.co.za           |
|             GSM and GPS value-added applications            |
|  Voice : +27-(0)11-622-8686   |   Fax : +27-(0)11-622-8973  |
|_____________________________________________________________|

1997\05\13@145555 by mbonner

flavicon
face
Tjaart van der Walt wrote:
>
> FrankT wrote:
> >
> > At the moment I am using Mplab-C compiler on the 16c74
> >
> > Frank Temmerman
>
> I hate to tell you this, but Microchip has kindly neglected
> adding the context saving section to the 16C74.h file. This
> means you have to wade through the following registers and
> decide which have to be saved for an interrupt :
>
<snip>
{Quote hidden}

For those of you trying to choose a good compiler - ByteCraft's MPC
address all the issues mentioned in this thread.  It's expensive (about
CDN $900), but good with good tech support

- Matt
--
Matthew Bonner B.Eng.
Product Development Engineer
Sunada Technology Corp. Calgary, Alberta
spamBeGonembonnerRemoveMEspamRemoveMEsunada.com

'TMR0 interrupt (PIC16c84 and PWM)'
1997\05\14@104002 by Osama ALASSIRY

flavicon
face
I can't get TMR0 overflow interrupt to work at all.

I use it to increment a counter (PWMCOUNTER) which is compared with a
certain value (PWM), if PWMCOUNTER<PWM a bit in PORTB is set, otherwise it
is reset. (using 1/8 prescaler on RTCC, INTCON: GIE and T0IE are 1, all
others 0)

I can't get it to work: the output is always LOW, which means the interrupt
doesn't happen. It works in MPSIM.

does anybody have a working fragment of such a thing. (anything with a TMR0
overflow interrupt would be great)

thank you,
_____________________________________________________
Osama ALASSIRY  @spam@osamaspamBeGonespamqatar.net.qa spam_OUTosamaspamspamalassiry.com
                             http://www.alassiry.com

1997\05\14@115214 by Jorge Miguel Cabral

flavicon
face
part 0 389 bytes
I can't get it to work: the output is always LOW, which means the interrupt
doesn't happen. It works in MPSIM.

does anybody have a working fragment of such a thing. (anything with a TMR0
overflow interrupt would be great)

thank you,


Did you clear the bit RTS (option.5) and set the PSA (option.3) and RTE
(option.4)?

If soo please email me the relevant part of the code!

Cabral.

1997\05\14@130735 by Jason E. Brown

flavicon
face
At 05:28 PM 5/14/97 +0300, you wrote:
>I can't get TMR0 overflow interrupt to work at all.
>
>I use it to increment a counter (PWMCOUNTER) which is compared with a
>certain value (PWM), if PWMCOUNTER<PWM a bit in PORTB is set, otherwise it
>is reset. (using 1/8 prescaler on RTCC, INTCON: GIE and T0IE are 1, all
>others 0)
>
>I can't get it to work: the output is always LOW, which means the interrupt
>doesn't happen. It works in MPSIM.
>
>does anybody have a working fragment of such a thing. (anything with a TMR0
>overflow interrupt would be great)
>
>thank you,
>_____________________________________________________
>Osama ALASSIRY  spamosamaspamspamspamqatar.net.qa spamBeGoneosamaKILLspamspamKILLspamalassiry.com
>                              http://www.alassiry.com

If it works in MPSIM, I would suggest looking to make sure you are
initializing all of you variables and registers to a known value in some
starup code..

The PIC starts up with "random" values in all of it's RAM locations,
(except some registers, see data sheet)

MPSIM starts up with all of these values at zero..

I am programming a chip today to test my PWM code using TMR0 intterupts,
I'll let you know what I find out....


Jason E. Brown
Other Worlds
3801 Dayton Blvd
Chattanooga TN 37415
(423)870-1074

TakeThisOuTothrwrldspamspamcdc.net = business.
spamBeGonejebrownspamcdc.net   = me.

1997\05\14@174622 by Osama ALASSIRY

flavicon
face
----
From: Jorge Miguel Cabral <EraseMEJorge.CabralEraseMEspamDEI.UMINHO.PT>
To: spamBeGonePICLISTspam_OUTspam.....MITVMA.MIT.EDU
Date: 15 May 1997 0:48 AM
Subject: Re: TMR0 interrupt (PIC16c84 and PWM)

>
<!--SNIPPED-->
> Did you clear the bit RTS (option.5) and set the PSA (option.3) and RTE
> (option.4)?
yes!

> If soo please email me the relevant part of the code!

it was something like this (original code not on my computer right now):
|   org 0
|   goto start
|   org 4
|isr
|  ;SAVE W and STATUS (from a microchip book)
|  BCF INTCON,IT0F (or something like that, clear overflow)
|  INCF PWMCOUNTER
|  ;COMPARE PWMCOUNTER with PWM
|  ;if < : bsf PORTB,0
|  ;if > : bcf PORTB,0
|  ;Restore W and STATUS (from a microchip book)
|   RETFIE
|start goto start ; infinite loop



I just  don't know what could be wrong...

1997\05\15@095859 by myke predko

flavicon
face
Osama,

Could you please post the *actual* code?  I find that little problems in
assembler that screw up the whole program can be stared at for hours by the
author without seeing them.

As well, have you run your code through the simulator (my first line of
defense/verification before I burn a part)?

myke
{Quote hidden}

"My ancestors didn't spend millions of years clawing their way to the top of
the food chain, just so I could become a vegetarian"

1997\05\15@111420 by Osama ALASSIRY

flavicon
face
the *ACTUAL* code is at the uni (closed Thursdays and Fridays :(  )  i'll
get it on Saturday and post it...

it does run on the simulator. (this is what puzzles me most! shouldn't
MPSIM be fully compatible with the real thing?)

thanks.
----
From: myke predko <EraseMEmykespamBeGonespamspamPASSPORT.CA>
To: KILLspamPICLISTspamMITVMA.MIT.EDU
Date: 15 May 1997 23:46 PM
Subject: Re: TMR0 interrupt (PIC16c84 and PWM)

>Osama,
>
>Could you please post the *actual* code?  I find that little problems in
>assembler that screw up the whole program can be stared at for hours by
the
>author without seeing them.
>
>As well, have you run your code through the simulator (my first line of
>defense/verification before I burn a part)?
>
>myke

1997\05\15@170402 by myke predko

flavicon
face
Osama wrote:
>the *ACTUAL* code is at the uni (closed Thursdays and Fridays :(  )  i'll
>get it on Saturday and post it...
>
>it does run on the simulator. (this is what puzzles me most! shouldn't
>MPSIM be fully compatible with the real thing?)

What I mean to say there are a lot of cases where the simulator seems to
indicate that something is working, but when you get out into the real
world, it upchucks.

Last year, I spent about three weeks trying to nail down a problem that
worked fine in the simulator, but when I actually tried it out on hardware,
the device just sat there and did nothing.  I finally traced the problem to
how I was simulating it, I had a delay routine that I skipped over in the
simulator because it took about an hour and a half to run (it delayed the
PIC for about 3 seconds).

The problem ended up being that the interrupt routine that I was debugging
was active during this delay, but needed variables which were initialized
*after* the delay routine.  It worked fine when the delay routine was
skipped and the interrupt didn't happen until after the variables were
initialized, but wouldn't work at all when the delay routine was working.

It didn't matter how hard I stared at it - it worked fine in the simulator
and wouldn't work in the device.  Maybe this is a case that would be
immediately obvious if you had an emulator.


Just reviewing this and realizing there is one MAJOR difference between
MPSIM (and MPLAB-SIM) and a real PIC.  That's in how the registers come up
initialized.  In both simulators, they are initialized to 0x000 and in the
PIC, they can be anything.

I just went back to your original note and I'm thinking that this is
probably your problem.  In the code you wrote, you didn't show how the PWM
variables were initialized.  I suspect that you probably don't initialize
PWMCounter (because it shows up as 0x000 in the simulator) and when you run
your code it's actually greater than the test values (and nothing ever gets
output).


Just a question for everybody who's used a PIC emulator more than I have
(because I didn't think to look for this when I was lent a PICMaster), what
do the Register Values initialize to?


When you get the code, we should be able to find the problem,

myke
{Quote hidden}

"My ancestors didn't spend millions of years clawing their way to the top of
the food chain, just so I could become a vegetarian"

1997\05\17@042703 by Osama ALASSIRY

flavicon
face
part 0 3674 bytes content-type:application/octet-stream;thank you.
----
From: myke predko <spamBeGonemyke.....spamPASSPORT.CA>
To: .....PICLIST@spam@spamMITVMA.MIT.EDU
Date: 16 May 1997 6:45 AM
Subject: Re: TMR0 interrupt (PIC16c84 and PWM)

>Osama wrote:
>>the *ACTUAL* code is at the uni (closed Thursdays and Fridays :(  )
i'll
{Quote hidden}

hardware,
>the device just sat there and did nothing.  I finally traced the problem
to
>how I was simulating it, I had a delay routine that I skipped over in the
>simulator because it took about an hour and a half to run (it delayed the
>PIC for about 3 seconds).
>
>The problem ended up being that the interrupt routine that I was
debugging
>was active during this delay, but needed variables which were initialized
>*after* the delay routine.  It worked fine when the delay routine was
>skipped and the interrupt didn't happen until after the variables were
>initialized, but wouldn't work at all when the delay routine was working.
>
>It didn't matter how hard I stared at it - it worked fine in the
simulator
>and wouldn't work in the device.  Maybe this is a case that would be
>immediately obvious if you had an emulator.
>
>
>Just reviewing this and realizing there is one MAJOR difference between
>MPSIM (and MPLAB-SIM) and a real PIC.  That's in how the registers come
up
>initialized.  In both simulators, they are initialized to 0x000 and in
the
>PIC, they can be anything.
>
>I just went back to your original note and I'm thinking that this is
>probably your problem.  In the code you wrote, you didn't show how the
PWM
>variables were initialized.  I suspect that you probably don't initialize
>PWMCounter (because it shows up as 0x000 in the simulator) and when you
run
>your code it's actually greater than the test values (and nothing ever
gets
>output).
>
>
>Just a question for everybody who's used a PIC emulator more than I have
>(because I didn't think to look for this when I was lent a PICMaster),
what
{Quote hidden}

in
{Quote hidden}

of
>the food chain, just so I could become a vegetarian"
>

Content-Type: application/octet-stream;
       name="Pwm.asm"
Content-Disposition: attachment;
       filename="Pwm.asm"

Attachment converted: wonderland:Pwm.asm (????/----) (00002DF8)

1997\05\18@005528 by Mike Smith

flavicon
face
----------
> From: Osama ALASSIRY <spamosamaspamALASSIRY.COM>
> To: PICLISTspam_OUTspamTakeThisOuTMITVMA.MIT.EDU
> Subject: Re: TMR0 interrupt (PIC16c84 and PWM)
> Date: Saturday, 17 May 1997 17:46
>
> attached the code, I hope somebody can see what's wrong!!
>

Just for a start, DON'T re-enable GIE inside the ISR.  The RETFIE
instruction does this automagically, and, if you have had an int whilst
processing the isr, you'll blow your stack really quickly this way.  This
is the sort of thing a simulator will probably never find, BTW, as its very
time-sensitive.

MikeS
<spam_OUTmikesmith_oz@spam@spamRemoveMErelaymail.net>

'Thanks: TMR0 interrupt (PIC16c84 and PWM) SOLVED'
1997\05\18@080300 by Osama ALASSIRY

flavicon
face
Thank you. Problem solved
Now we get a good PWM response , 15 steps from 0% to 94% duty cycle

GOOD!

----
From: Mike Smith <spammikesmith_ozspamspamRELAYMAIL.NET>
To: @spam@PICLISTspam_OUTspamMITVMA.MIT.EDU
Date: 18 May 1997 13:51 PM
Subject: Re: TMR0 interrupt (PIC16c84 and PWM)

{Quote hidden}

very
>time-sensitive.
>
>MikeS
><RemoveMEmikesmith_ozRemoveMEspamrelaymail.net>
>

'TMR0 interrupt (PIC16c84 and PWM)'
1997\05\18@204103 by John Payson

picon face
> Just for a start, DON'T re-enable GIE inside the ISR.  The RETFIE
> instruction does this automagically, and, if you have had an int whilst
> processing the isr, you'll blow your stack really quickly this way.  This
> is the sort of thing a simulator will probably never find, BTW, as its very
> time-sensitive.

As a slight clarification, never enable GIE within an ISR unless you are
absolutely sure you know what you're doing *AND* you have counted up the
stack overhead.  I have on a couple of programs used a short ISR which ran,
essentially, this:

       [ save W and PSW ]
       [ do a little bit of work]
       [ restore W and PSW ]
       decfsz  counter,f
        retfie
       bsf     gie
       [ save W and PSW to another pair of locations]
       [ set up counter again]
       [ do 'a lot' more work (more than a timer-ticks' worth ]
       [ restore PSW and W]
       retfie

My smaller interrupt routine does not make any sub-calls.  My larger one
does make one level of calls, but they are "guarded" with disable-timer
interrupt and enable-timer interrupt instructions.

For applications where an ISR has to do periodic "thinks" but mostly just
keeps a counter or two, I think this approach is an excellent one.  Has
anyone else used it?

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