I am confuse with the following code, because it didn't work as expected.
Perhaps I am missing something. Can somebody on the list please correct my
mistake.
I don't see why you have to clear and set GIE (no it is not done automatically, you have to do it, if you need to do it). The most important thing is that you need to clear the interrupt flag, otherwise once you get an interrupt, interrupt will be reentered. Try this as the first line in your ISR_RBIF code:
BCF INTCON, RBIF ; clear the interrupt flag
This is true for all interrupts. You will need to clear the interrupt flags *for each of the interrupts you have setup*.
>I don't see why you have to clear and set GIE (no it is not done automatically, you have to do it, if you need to do it). The most important thing is that you need to clear the interrupt flag, otherwise once you get an interrupt, interrupt will be reentered. Try this as the first line in your ISR_RBIF code:
>
>BCF INTCON, RBIF ; clear the interrupt flag
>
>This is true for all interrupts. You will need to clear the interrupt flags *for each of the interrupts you have setup*.
>
>
You just have to clear the interrupt flag before you exit the ISR.
It makes no difference wether it's at the start or end of it.
David...
> -----Original Message-----
> From: Ömer Yalhi [.....oyalhiKILLspam.....TEKSAN.COM.TR]
> Sent: 17 October 2003 06:33
> To: EraseMEPICLISTspam_OUTTakeThisOuTMITVMA.MIT.EDU
> Subject: Re: [PIC]: RB change ISR
>
>
> I don't see why you have to clear and set GIE (no it is not
> done automatically, you have to do it, if you need to do it).
No, GIE is cleared automaticaly. If you want to try some kind of nested
interrupt system you would have to deliberatly enable it.
> The most important thing is that you need to clear the
> interrupt flag, otherwise once you get an interrupt,
> interrupt will be reentered. Try this as the first line in
> your ISR_RBIF code:
>
> BCF INTCON, RBIF ; clear the interrupt flag
>
> This is true for all interrupts. You will need to clear the
> interrupt flags *for each of the interrupts you have setup*.
You have to clear the interrupt flag before exiting the ISR (and nearly
always it's a good idea to clear the flag as soon as possible in the ISR).
However, if GIE remained enabled the PIC would effectivly lock up as every
instruction the PC would jump to the ISR vector.
To answer the original poster, if you read the datasheet you will see that
you must perform a read of PORTB in order to end the mistmatch condition
that exists after a change has been detected.
Regards
Mike
=======================================================================
This e-mail is intended for the person it is addressed to only. The
information contained in it may be confidential and/or protected by
law. If you are not the intended recipient of this message, you must
not make any use of this information, or copy or show it to any
person. Please contact us immediately to tell us that you have
received this e-mail, and return the original to us. Any use,
forwarding, printing or copying of this message is strictly prohibited.
No part of this message can be considered a request for goods or
services.
=======================================================================
Any questions about Bookham's E-Mail service should be directed to postmasterspam_OUTbookham.com.
The "Global Interrupt Enable flag" (GIE) is handled
automaticly (cleared when the interrupt code is called
and set by the RETFIE instruction). You should only
clear this bit if you want to globaly disable interrupts
*outside* of your ISR.
On the other side, you have to clear the specific "XX Interrupt
Flag" (RBIF in your case) that caused the interrupt to happen.
If not, your ISR will be called recursively as soon as he RETFIE
instruction is executed.
Now, regarding your code...
What *did* you expect ?
How *did* it work ?
One thing, this code :
BTFSC PORTB, 7
GOTO BIT_7
will goto "BIT_7" if "PORTB, 7" is set ("1"), no matter
if it has changed since last time. Is that what you want ?
If you realy want to check for changes, you have to
save the last state of each bit and compare with that.
And, if two bits changes at the same time, you will probably
miss one of them.
>will goto "BIT_7" if "PORTB, 7" is set ("1"), no matter
>if it has changed since last time. Is that what you want ?
Actually I wish to monitor a change from 'low' to 'high' of each RB4 ~ RB7.
When this happen I would like to trigger some jobs in sequence. As a
preliminary study of RB change ISR, I just output a string of character, say
'RB7 changed' to a LCD.
But the LCD show somthing that I can't understand.
>And, if two bits changes at the same time, you will probably
>miss one of them.
Only one line could go 'high' at a time, I think there is no problem with
this.
>
> Actually I wish to monitor a change from 'low' to 'high' of
> each RB4 ~ RB7. When this happen I would like to trigger some
> jobs in sequence. As a preliminary study of RB change ISR, I
> just output a string of character, say 'RB7 changed' to a LCD.
>
Then you want something a bit like this in your ISR
movf PORTB,W ; which bits have changed?
xorwf OLD_PORTB,F
; now inspect the bits of OLD_PORTB,
; a bit is high if it changed on portb since last time we ran
<add your inspection code here, branch as necessary>
; or, f you only want to know which bits changed from 0 -> 1
; ignoring which bits changed from 1 -> 0
; do this as well
movf PORTB,W
andwf OLD_PORTB,F
; and check the bits of OLD_PORTB here: a high indicates a bit that
was low before and is high now
<add your inspection code here, branch as necessary>
movf PORTB,W ; save this portb value for next change
comparison
movwf OLD_PORTB
You need to maintain a copy of what *used* to be in PORTB, define OLD_PORTB
as a global var. In your initialisation, you should read portb and write it
to this var before you enable interupts, else your first ISR call will be
junk
WH Tan wrote:
> I am confuse with the following code, because it didn't work as
> expected. Perhaps I am missing something. Can somebody on the list
> please correct my mistake.
>
> ORG 0x0000 ; RESET vector location
Absolute mode is bad idea. You will eventually waste more time than it
would take to read the linker chapter.
> GOTO START
>
> ORG 0x0004
> MOVWF W_TEMP
W_TEMP needs to be in unbanked RAM or reserved separtely in each RAM bank.
> SWAPF STATUS, W
> MOVWF STATUS_TEMP
Note that the bank is unkown here. This means STATUS_TEMP needs to be in
unbanked RAM or reserved in all banks, which is a waste. Insert CLRF
STATUS between these two instructions.
If this PIC has more than one code page, you need to CLRF PCLATH also. If
you don't, any GOTO or CALL in the ISR can jump to an unexpected location.
> BCF INTCON, GIE ;Is this code is a must, or
> ;PIC will do it for me?
You could of course get the answer from the manual or the simulator. To
answer the question: No, yes.
> END_ISR
Again, you have a banking problem here. Start this section with CLRF
STATUS.
> SWAPF STATUS_TEMP, W
> MOVWF STATUS
> SWAPF W_TEMP, F
> SWAPF W_TEMP, W
>
> BCF INTCON, RBIF
This doesn't belong here. It should be with the code that handles the
RGIF interrupt.
> BSF INTCON, GIE ; Again, is this code necessary?
No. In fact it's a very bad idea because you can get a nested interrupt.
> RETFIE
All in all it is silly to reinvent an ISR. There aren't a lot of ways of
doing it and others have done this many times before. There are many
examples out there, including my own. See the 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
> I don't see why you have to clear and set GIE (no it is not done
> automatically, you have to do it, if you need to do it).
No, the PIC clears GIE before the ISR is started. The RETFIE instruction
sets GIE and returns as one indivisible operation so that you can't get a
nested interrupt. You shouldn't otherwise mess with GIE within an
interrupt.
*****************************************************************
Embed Inc, embedded system specialists in Littleton Massachusetts
(978) 742-9014, http://www.embedinc.com
> BSF INTCON, GIE ; Again, is this code necessary?
This is one of the pitfalls. Thanks Olin, as well as Omer. I thinks this the
reason why the PIC ran for some time, and then halted. I was introducing a
nested interrupt, and the stack was trashed.
The second pitfall is the paging problem.
HEX2ASC
;***************************************************************************
***
; Description: Convert W lower 4 bits to ASCII table defined in HD44780
;
; B7 B6 B5 B4 B3 B2 B1 B0
; x x x x B3 B2 B1 B0
;
; Conditions: Value to be converted in W (4 LSB)
; Result of conversion (8-bits) in W
;
;***************************************************************************
***
ANDLW 0x0F
MOVWF W0
MOVLW HIGH TABLE_ASCII
MOVWF PCLATH
MOVLW LOW TABLE_ASCII
ADDWF W0, W
SKPNC
INCF PCLATH, F
MOVWF PCL
TABLE_ASCII RETLW 0x30 ; '0'
RETLW 0x31 ; '1'
RETLW 0x32 ; '2'
RETLW 0x33 ; '3'
RETLW 0x34 ; '4'
RETLW 0x35 ; '5'
RETLW 0x36 ; '6'
RETLW 0x37 ; '7'
RETLW 0x38 ; '8'
RETLW 0x39 ; '9'
RETLW 0x41 ; 'A'
RETLW 0x42 ; 'B'
RETLW 0x43 ; 'C'
RETLW 0x44 ; 'D'
RETLW 0x45 ; 'E'
RETLW 0x46 ; 'F'
Originally that is only 'ANDLW 0x0F' and 'ADDWF PCL, F' instead of the first
9 line of codes.
When I was first writing this code, it stay below 0x100 of page 0. As codes
are added little by little, it is pushed out the 0x100 boundary. One
question is will this codes work in pages other than page 0? Of course then
I have to use the FCALL macro, but will this code work without effecting
other paging issue.
Jan, I thinks this is the reason I get funny things shown in LCD. Thanks a
lot for your response.
> ***
> ANDLW 0x0F
> MOVWF W0
> MOVLW HIGH TABLE_ASCII
> MOVWF PCLATH
> MOVLW LOW TABLE_ASCII
> ADDWF W0, W
> SKPNC
> INCF PCLATH, F
> MOVWF PCL
> TABLE_ASCII
> RETLW 0x30 ; '0'
> RETLW 0x31 ; '1'
> ...
> ...
> RETLW 0x46 ; 'F'
>
> Originally that is only 'ANDLW 0x0F' and 'ADDWF PCL, F' instead of the first
> 9 line of codes.
>
> When I was first writing this code, it stay below 0x100 of page 0. As codes
> are added little by little, it is pushed out the 0x100 boundary. One
> question is will this codes work in pages other than page 0?
Yes, anyware.
> as long as the whole table is Of course then
> I have to use the FCALL macro,
Note that on the 18-series, the CALL and GOTO instructions directly
can call or jump to *any* program location in the whole 2Mb Flash
program space without any special page handling. Nice... :-)
>Note that on the 18-series, the CALL and GOTO instructions directly
>can call or jump to *any* program location in the whole 2Mb Flash
I have in hand some 18F458 chips. It would be a pressure to play around with
those 18 series. Anyway I feel is still not the time for the beginner like
me. I only will start 18F when I get familiar with 16F series.
OT, but try looking through the 18F docs sometime, they are waaaaaaaaaaay
easier for a beginner than the 16Fs. No banking (at least none that a
beginner would need to), true table read-writes, lots of other goodies...
WH Tan wrote:
> I have in hand some 18F458 chips. It would be a pressure to play around
> with those 18 series. Anyway I feel is still not the time for the
> beginner like me. I only will start 18F when I get familiar with 16F
> series.
If you're a beginner and doing this for a hobby or other low volume use, I
would start with the 18F series and not look back. Many of the beginner
pitfalls of the 16 series have been reduced or eliminated. For example,
you can pretty much ignore paging on the 18 series, and banking is easier
to deal with.
As general hobby PICs, I recommend the 18F252 for a 28 pin device, and the
18F452 for a 40 pin device. I wouldn't touch the others unless you need
their specific features. For example, I wouldn't use a 18F458 unless I
was trying to do CAN.
*****************************************************************
Embed Inc, embedded system specialists in Littleton Massachusetts
(978) 742-9014, http://www.embedinc.com
What's the consensus on the 17 series? I have so far got the impression that
they're a bit of an ugly-duckling, an accidental child, and that 16 was
middle of the road, 17 was hush-hush we're embarrassed, and 18 is the high
perf. beast.
> WH Tan wrote:
> > I have in hand some 18F458 chips. It would be a pressure to play around
> > with those 18 series. Anyway I feel is still not the time for the
> > beginner like me. I only will start 18F when I get familiar with 16F
> > series.
>
> If you're a beginner and doing this for a hobby or other low volume use, I
> would start with the 18F series and not look back. Many of the beginner
> pitfalls of the 16 series have been reduced or eliminated. For example,
> you can pretty much ignore paging on the 18 series, and banking is easier
> to deal with.
All true, unless you want to use a free C compiler, in which case, and
correct me if I'm wrong, a 16F or 12F is your only choice. TTYL
Herbert Graf wrote:
> All true, unless you want to use a free C compiler, in which case, and
> correct me if I'm wrong, a 16F or 12F is your only choice. TTYL
The Microchip free demo compiler maybe ?
Jan-Erik.
> Herbert Graf wrote:
> > All true, unless you want to use a free C compiler, in which case, and
> > correct me if I'm wrong, a 16F or 12F is your only choice. TTYL
>
>
>
> The Microchip free demo compiler maybe ?
> Jan-Erik.
Herbert Graf wrote:
>> Herbert Graf wrote:
>>> All true, unless you want to use a free C compiler, in which case,
>>> and correct me if I'm wrong, a 16F or 12F is your only choice. TTYL
>>
>>
>>
>> The Microchip free demo compiler maybe ?
>> Jan-Erik.
>
> I thought it was time limited? Thanks, TTYL
It was mentioned just recently by numerous people that you simply
uninstall/reinstall every month and it keeps on going, just like the
Energizer bunny. ;-)
> Herbert Graf wrote:
> >> Herbert Graf wrote:
> >>> All true, unless you want to use a free C compiler, in which case,
> >>> and correct me if I'm wrong, a 16F or 12F is your only choice. TTYL
> >>
> >>
> >>
> >> The Microchip free demo compiler maybe ?
> >> Jan-Erik.
> >
> > I thought it was time limited? Thanks, TTYL
>
> It was mentioned just recently by numerous people that you simply
> uninstall/reinstall every month and it keeps on going, just like the
> Energizer bunny. ;-)
Hmm, that's interesting, I guess that would be an option, but I'd certainly
feel uncomfortable using it in that way. To each his/her own. TTYL
> What's the consensus on the 17 series? I have so far got the impression
> that they're a bit of an ugly-duckling, an accidental child, and that
> 16 was middle of the road, 17 was hush-hush we're embarrassed, and 18
> is the high perf. beast.
The 17 series actually predates the 16 series. Microchip found it
overshot the mark, and the 16 series was accepted much better by
customers. The 16 series is now the low end. Even the newer "12F" parts
are really misnamed 16F parts in an 8 pin package. The current high end,
soon to be midrange is the 18 series. The 30 series (dsPIC) will soon be
the high end.
I've only used a 17 PIC a few times. Each time to get two hardware UARTs
in a single package before this was available from an 18 PIC.
*****************************************************************
Embed Inc, embedded system specialists in Littleton Massachusetts
(978) 742-9014, http://www.embedinc.com
>Why start in the *hard* end. The 18-series are easier to use...
For many reasons.
Among them, the web resources come out to be the top. Anyone ever notice
that most of the application notes from Microchip is related to 16 series.
Furthermore I can find many of tutorials writen by some expert for 16 series
compare to 18 series. Please correct me if I am wrong.
That is the reason when I was going to start PIC, I choose 16F874/877
series.
> Anyone ever notice
> that most of the application notes from Microchip is related
> to 16 series.
> Furthermore I can find many of tutorials writen by some
> expert for 16 series
> compare to 18 series.
But that is at least partially compensated by the fact that for the
16F's there are so much more quircks to explain.