Searching \ for '[PIC] 16F628 Interrupts problem' 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: '16F628 Interrupts problem'.

Exact match. Not showing close matches.
PICList Thread
'[PIC] 16F628 Interrupts problem'
2005\08\23@122509 by Michael Tandy

picon face
Hi there,

I'm having trouble with interrupts on a 16F628 (in assembly), and I'd be
very grateful for any help/advice anyone could offer.

Similar, unresolved problem in the archives: http://tinyurl.com/9maan

Basically, when I have interrupts enabled, I experience odd behaviour,
in the form of programs getting stuck in loops when the exit conditions
ought to have come true, and similar problems. It's as if the status
byte isn't getting restored properly, or the program counter is jumping
over certain commands, or something similar.

I'm using a 16F628 - I've also tried a 16F627 which exhibits the same
problem, so it's not a single-chip defect. The problem isn't highly
consistent, in that changes made pursuing it often hide it only to have
it come back later.

I've put together some example code that demonstrates the problem:
http://michaelt.uwcs.co.uk/crashtest.asm

The program will flash all appropriate ports for a short time, but soon
after will 'lock up', having got stuck in ExampleLoop2.

I don't believe the problem is the length of my interrupt handling loop,
since said loop isn't anywhere near 256 commands long. To the best of my
knowledge, my interrupt routine stores and restores W and STATUS
correctly, as in Microchip's code examples. On the other hand, I can
find no mention of this fault in the chip errata, so a fault in my code
is surely more likely. I just don't know what that fault is.

I'm stumped by this problem; I have tried my best to find a solution,
but to no avail. I'd be very grateful for any advice or suggestions
other piclisters could offer!

Thanks,

Michael Tandy

2005\08\23@124044 by Mchipguru

picon face
If your interrupt is other than a T0 overflow you never clear the cause of the interrupt and keep going back in slowing everything way down and appearing to hang.

Larry
{Quote hidden}

> --

2005\08\23@130508 by Michael Tandy

picon face
AFAIK it only goes to interrupt upon T0 overflow. That's how I've tried
to set the INTCON mask bits, anyway.

To clarify, RA7 still flashes, telling me it returns from interrupt and
goes about processing the main program (roughly) where if left off, just
it eventually becomes stuck inside the loop.

Cheers,

Michael

mchipguruspamKILLspamcharter.net wrote:
{Quote hidden}

>> Michael Tand

2005\08\23@130522 by Maarten Hofman

face picon face
Rochester, 23 augustus 2005.

Dear Michael,

Could it have something to do with you not restoring the STATUS byte correctly?

Your code reads:

movfw STATUS

Which seems to be incorrect, in my opinion. One of the reasons why I
tend to avoid the movfw instruction alltogether.

Greetings,
Maarten Hofman.

2005\08\23@132947 by olin piclist

face picon face
Michael Tandy wrote:
> Basically, when I have interrupts enabled, I experience odd behaviour,
> in the form of programs getting stuck in loops when the exit conditions
> ought to have come true, and similar problems. It's as if the status
> byte isn't getting restored properly, or the program counter is jumping
> over certain commands, or something similar.

That sure sounds like the interrupt routine is corrupting foreground state.

> INT_VAR_shared UDATA_SHR
> Int_w_store RES  1           ;We store W here on interrupt and restore it
> before RETFIE
> Int_status_store RES 1
>
> INT_VAR  UDATA   0x20

Why does this need to be at exactly 20h?

> RESET_VECTOR CODE 0x000      ;processor reset vector
>          goto    start       ;go to beginning of program
>
> INTERRUPT_VECTOR CODE 0x004  ;In case of interrupt...
>          goto    interrupt_handler ;...goto appropriate code
>
>          ; Using GOTO instead of code here due to funny default linker
>          ; script - I preferred GOTO to changing linker script.

Bad idea.  Instead of fixing the problem you now have stupid code in
addition to the stupid linker script.  Your method wastes a word and a cycle
on the 16F628 but will break on PICs with more than one code page since you
don't know what PCLATH is set to when an interrupt occurs.

> interrupt_handler
>          movwf   Int_w_store ;Store W; it gets restored before we RETFIE
>          movf    STATUS, w
>          movwf   Int_status_store ;Also store STATUS/memory bank selection
>          bcf     INTCON, GIE ;Disable interrupts

Interrupts are already off.  This does nothing useful.

>          bcf     STATUS, RP0 ;Make sure we're looking at Bank 0

On machines that only have two banks.  CLRF STATUS sets both direct bank
bits and the indirect bank bit to bank 0.

{Quote hidden}

Actually the "E" refers to the fact that interrupts are re-enabled.

I don't see anything obviously wrong with your interrupt handler other than
noted, but I don't understand why everyone tries to re-invent interrupt
entry/exit code that is just a little different from the many existing
templates that have already been tested.  You're setting yourself up for
trouble on PICs that have more than one code page.

For a well tested interrupt template, see my QQQ_INTR.ASPIC module at
http://www.embedinc.com/pic.


*****************************************************************
Embed Inc, embedded system specialists in Littleton Massachusetts
(978) 742-9014, http://www.embedinc.com

2005\08\23@135807 by Michael Tandy

picon face
Well blow me down with a feather:- there's a command called movfw, and
I'm using instead of movwf! That would certainly explain what's wrong!
Thanks, Maarten!

Hmm, I feel pretty silly now.

Thanks again,

Michael


Maarten Hofman wrote:
{Quote hidden}

2005\08\23@143821 by Mchipguru

picon face
I would try toggling a pin in the interrupt routine, If it happens only on a T0 then it will be consistant. If it speeds up dramatically when things hang something is sending you to the interrupt other than T0 and not getting reset.
Another thing I see is yout save and restore in interrupt seems to not quite match unless I am missing something.
try something like this

MOVWF W_TEMP ;Copy W to TEMP register, could be bank one or zero
SWAPF STATUS,W ;Swap status to be saved into W
CLRF STATUS ;bank 0, regardless of current bank, Clears IRP,RP1,RP0
MOVWF STATUS_TEMP ;Save status to bank zero STATUS_TEMP register
MOVF PCLATH, W ;Only required if using pages 1, 2 and/or 3
MOVWF PCLATH_TEMP ;Save PCLATH into W
CLRF PCLATH ;Page zero, regardless of current page
BCF STATUS, IRP ;Return to Bank 0
MOVF FSR, W ;Copy FSR to W
MOVWF FSR_TEMP ;Copy FSR from W to FSR_TEMP
:
:(ISR)
:
MOVF PCLATH_TEMP, W ;Restore PCLATH
MOVWF PCLATH ;Move W into 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


{Quote hidden}

> >> Michael Tand

2005\08\23@150700 by Michael Tandy

picon face
Hi there Olin,

Thanks for your reply. I think/hope Maarten has solved my problems
(turns out I was using movfw instead of movwf, something the assembler
doesn't complain about) but I'll try to explain my design decisions
anyway, for the sake of discussion.

>> INT_VAR  UDATA   0x20
>
> Why does this need to be at exactly 20h?

Short answer is 'because that's where the memory starts'

I had a problem, and examination with MPLAB SIM told me the address of
my first reserved memory space was 0x120, and went from there on up. I
don't know why this would be, but it was causing problems, so I added
the 0x20 and the problems were fixed.

Also, the official Microchip object template includes the 0x20.

>> ; Using GOTO instead of code here due to funny default linker ;
>> script - I preferred GOTO to changing linker script.
>
>
> Bad idea.  Instead of fixing the problem you now have stupid code in
>  addition to the stupid linker script.  Your method wastes a word and
>  a cycle on the 16F628 but will break on PICs with more than one code
>  page since you don't know what PCLATH is set to when an interrupt
> occurs.

Not having any other PICs, I didn't know that; I'll certainly take it
into account. Thanks!

Basically I chose to use the goto so I didn't have to edit the linker
script. I didn't want to assign an arbitrary amount of space for
interrupt handling code by editing the linker script, since I
didn't/don't know how long my interrupts are going to be.

> Interrupts are already off.  This does nothing useful.

I wasn't sure interrupts got turned off, so when I encountered problems,
I put that in to be safe. If it doesn't do anything, I'll remove it.

Once again, thanks!

>> bcf     STATUS, RP0 ;Make sure we're looking at Bank 0
>
> On machines that only have two banks.  CLRF STATUS sets both direct
> bank bits and the indirect bank bit to bank 0.

My code only deals with the first two banks.

Hmm, on the other hand, it wouldn't hurt to set the second bit just to
be safe, so I think I might do that.

>> retfie              ;RETurn From IntErrupt
>
> Actually the "E" refers to the fact that interrupts are re-enabled.
>

Aha, I wondered what that E was doing there...

> I don't understand why everyone tries to re-invent interrupt
> entry/exit code that is just a little different from the many
> existing templates that have already been tested.

I would say a few of the joys of re-implementation include:

1. I have to understand what, say, a subtract-and-shift integer division
function does, meaning I learn things. As a student, that's useful.

2. Easier problem solving because you (theoretically) know exactly what
the program /should/ be doing - which useful when it doesn't. Other
people's assembly code can be scary!

3. No figuring out bsd/gpl/attribution/whatever licensing.


Cheers,

Michael

2005\08\23@164252 by olin piclist

face picon face
Michael Tandy wrote:
> Thanks for your reply. I think/hope Maarten has solved my problems

I don't think so.

> (turns out I was using movfw instead of movwf, something the assembler
> doesn't complain about)

If I remember right, you used MOVFW to get a file register value into W.  I
*think* the "MOVFW xxx" abbreviation stands for "MOVF xxx, W".  I think
these abbreviations are a bad idea too, and I wish they were illegal in
MPASM.  It would catch more typos and putting ", w" after the intstruction
is hardly a big deal.

So if MOVFW is what I think it is, it doesn't explain your problem.

>>> INT_VAR  UDATA   0x20
>>
>> Why does this need to be at exactly 20h?
>
> Short answer is 'because that's where the memory starts'

Well, yeah, on *that* PIC.  I can't see a reason you need those variables to
start at 20h.  All you are counting on is that they are in bank 0.  Let the
linker figure out where the memory is and encode the parts that really
matter in the source code:

bank0  code
myvar   res   1

> I had a problem, and examination with MPLAB SIM told me the address of
> my first reserved memory space was 0x120, and went from there on up.

That is because you didn't specify what bank it should be in, so the linker
picked the smallest region that fit the variables you asked for.

> Also, the official Microchip object template includes the 0x20.

Rule 1: Microchip example code sucks.  Microchip examples are irrelevant in
a discussion of how things should be.

> Basically I chose to use the goto so I didn't have to edit the linker
> script.

It's only minor change to one line and deleting one or two more.  Or you
could use my linker file for the 16F628 directly.

> I didn't want to assign an arbitrary amount of space for
> interrupt handling code by editing the linker script, since I
> didn't/don't know how long my interrupts are going to be.

Right.  There is absolutely no reason for defining a separate memory region
for the interrupt code, and some good reaons why not.  See rule 1.

> I wasn't sure interrupts got turned off, so when I encountered
> problems, I put that in to be safe. If it doesn't do anything, I'll
> remove it.

Why not just wave a dead fish over it?  All the remedies other than reading
the manual are about as good.

> My code only deals with the first two banks.

This time, on this machine.  CLRF STATUS gets all of them for the same price
as a single instruction.

> I would say a few of the joys of re-implementation include:

But you can still look at examples.  Many of the things I'm pointing out are
already taken care of in a well written interupt entry/exit template.


*****************************************************************
Embed Inc, embedded system specialists in Littleton Massachusetts
(978) 742-9014, http://www.embedinc.com

2005\08\23@174801 by Jinx

face picon face
> "MOVFW xxx" abbreviation stands for "MOVF xxx, W".
>  I think these abbreviations are a bad idea too, and I wish
> they were illegal in MPASM.  It would catch more typos

You can identify movfw quite easily. It can't make you think
about the logic of what you're doing of course. I have these
colours set in MPLAB ; dark blue for reserved words, purple
for labels. In a 628 project, movwf is dark blue, movfw is
purple

Edit / Properties / Text / Choose Colors

2005\08\23@190330 by Maarten Hofman

face picon face
Rochester, 23 augustus 2005.

Dear all,

As you all know by now I am a bit of a newbie, and should probably
keep my mouth shut. But I was a bit disappointed by Olin's Email, and
needed to respond. My apologies if my response is considered
offensive.

Greetings,
Maarten Hofman.

> > Thanks for your reply. I think/hope Maarten has solved my problems
>
> I don't think so.

I think so, though.

>
> > (turns out I was using movfw instead of movwf, something the assembler
> > doesn't complain about)
>
> If I remember right, you used MOVFW to get a file register value into W.  I
> *think* the "MOVFW xxx" abbreviation stands for "MOVF xxx, W".  I think
> these abbreviations are a bad idea too, and I wish they were illegal in
> MPASM.  It would catch more typos and putting ", w" after the intstruction
> is hardly a big deal.

Instead of remembering, it might be good to read the actual code. The
movfw instruction in question was meant to restore the STATUS word to
its original value. He first loaded the original value into the W
register, and then did movfw STATUS. Unfortunately, this does not
change the STATUS register, but instead changes the contents of the W
register, as you correctly described above. This means that after the
interrupt is complete, the STATUS was not reset correctly.

>
> So if MOVFW is what I think it is, it doesn't explain your problem.
>

I think it does, but I admit, I might be wrong as well.

{Quote hidden}

Thank you... Always good to learn new things. However, I design my
applications in advance, and know exactly which PICmicro is going to
run it. So creating it such that I can easily change the PICmicro to
another type seems like a lot of overhead to me. But then, I'm not
really into this "relocatable code" anyway.

> Rule 1: Microchip example code sucks.  Microchip examples are irrelevant in
> a discussion of how things should be.

Strong words. I believe this wasn't a discussion on how things should
be, but a question to have a problem solved. So far you only wrote
what you think is not the problem, and commented on issues with the
code. It might be helpful to also add the solution to the problem.

> Why not just wave a dead fish over it?  All the remedies other than reading
> the manual are about as good.

Doesn't that manual contain sample code from Microchip?

2005\08\23@193724 by Jinx

face picon face
> Doesn't that manual contain sample code from Microchip?

Hi Maarten

You have to be aware of possible errors in datasheets. I've
seen code examples of just a half-dozen lines that won't work.
This is unacceptable in a manual. A beginner or somebody
unfamiliar with a device, especially any poor soul who does
not belong to a user group like this, does not know what they
don't know and can't easily spot even simple mistakes. To
compound matters, MC are extremely slow to correct errors
pointed out to them. Like others here, I still try, as I have for
a number of years, but have yet to see anything fixed

2005\08\23@195935 by olin piclist
face picon face
Maarten Hofman wrote:
> Instead of remembering, it might be good to read the actual code.

Yes it would be, and I would have if the code hadn't been on another machine
20 miles away where I downloaded it some hours earlier.

> The
> movfw instruction in question was meant to restore the STATUS word to
> its original value.

If that is correct, then I agree that MOVFW is a problem.

> However, I design my
> applications in advance, and know exactly which PICmicro is going to
> run it.

Sigh, where to start? ...

First, sooner or later you, or maybe someone else, will try to use that code
on another PIC.  Code takes on a life of its own.  The argument for doing
this right is not much different from the one for proper commenting and
readable style.

I think the best argument though is that the source code should describe
what to do and what the requirments are, and the linker file should define
the memory layout of that particular PIC.  If it's not obvious why that's a
good idea then I might as well give up.

> So creating it such that I can easily change the PICmicro to
> another type seems like a lot of overhead to me.

What overhead?  Nothing I've suggested is more difficult, only smarter.

> But then, I'm not
> really into this "relocatable code" anyway.

That's another bad habit you should fix.

> I believe this wasn't a discussion on how things should
> be, but a question to have a problem solved.

First, I can comment on anything I like.  Second, just because some of the
things I pointed out didn't in fact cause the problem originally asked about
doesn't make them any less bugs waiting to happen.  Newbies seem to pick up
bad habits early, then stick to them.  It's important to get people down the
right path as soon as possible.


*****************************************************************
Embed Inc, embedded system specialists in Littleton Massachusetts
(978) 742-9014, http://www.embedinc.com

2005\08\23@202223 by Michael Tandy

picon face

>>>Thanks for your reply. I think/hope Maarten has solved my problems
>>
>>I don't think so.
>  
> I think so, though.
>

Well, the fault has been elusive in the past so I can't say for certain
that it's solved, but Maarten's solution seemed logically and
computationally sound. As a quick reminder, he pointed out that (a) My
problem resembled the status word not restoring correctly and (b) My
code to copy Int_status_store to status was:

  movf Int_status_store, w
  movfw STATUS

...code which is functionally identical to:

  movf Int_status_store, w
  movf STATUS, w

Haha, as you can imagine, it didn't work very well!

In any case, my problem appears to be solved, so all at piclist have my
thanks!

Cheers,

Michael

2005\08\24@035851 by Alan B. Pearce

face picon face
>> Well, yeah, on *that* PIC.  I can't see a reason you need those
>> variables to start at 20h.  All you are counting on is that they
>> are in bank 0.  Let the linker figure out where the memory is
>> and encode the parts that really matter in the source code:
>>
>> bank0  code
>> myvar   res   1
>>
>
>Thank you... Always good to learn new things. However, I design my
>applications in advance, and know exactly which PICmicro is going to
>run it. So creating it such that I can easily change the PICmicro to
>another type seems like a lot of overhead to me. But then, I'm not
>really into this "relocatable code" anyway.

I'm with Olin on this one. Using scripts correctly (particularly the ones
Olin has made available) means that you can design without needing to deal
with the quirks of memory being in a different place, dealing with memory
size, dealing with banked versus unbanked RAM and registers, all becomes
second nature. You don't need to keep track of which particular micro you
are using today, or if you happen to be dealing with a bigger one over in
that part of the project versus the small one in this part. The scripts make
the interface a lot more common between them.

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