Problems to identify Interrupts
Moderators: David Barker, Jerry Messina
- David Barker
- Swordfish Developer
- Posts: 1214
- Joined: Tue Oct 03, 2006 7:01 pm
- Location: Saltburn by the Sea, UK
- Contact:
> Thanks Dave. Your explanations make it clearer to me now.
No problem. Glad it was of some use.
> Now I want go back to the beginning of this thread
Here is a program which will switch on an LED connected to PORTA.0 if a button connected to PORTB.0 is held for more than (n) milliseconds. The LED is switched off when the button is released. It also supports a simple debouncing mechanism.
This program has been tested and works OK on my hardware. It can be extended to support more buttons...
No problem. Glad it was of some use.
> Now I want go back to the beginning of this thread
Here is a program which will switch on an LED connected to PORTA.0 if a button connected to PORTB.0 is held for more than (n) milliseconds. The LED is switched off when the button is released. It also supports a simple debouncing mechanism.
This program has been tested and works OK on my hardware. It can be extended to support more buttons...
Code: Select all
// program constants...
const
ReloadTimerValue = 65536 - _clock * 250,
btnDebounce = 20, // 20 millseconds
btnTimeout = 5000 // 5 second hold time...
// timer registers...
dim
TMR0 as TMR1L.AsWord,
TMR0IF as PIR1.Booleans(0),
TMR0IE as PIE1.Booleans(0),
TMR0On as T1CON.Booleans(0),
RBPU as INTCON2.7,
INT0IE as INTCON.4,
INT0IF as INTCON.1
// button structure...
structure TButton
Timeout as word
Debounce as byte
end structure
dim Button as TButton
// an interrupt declaration with no param
// is high priority by default
interrupt OnChange()
if INT0IF = 1 then
INT0IF = 0
Button.Debounce = btnDebounce
Button.Timeout = btnTimeout
elseif TMR0IF then
TMR0IF = false
TMR0 = TMR0 + word(ReloadTimerValue)
if Button.Debounce > 0 then
dec(Button.Debounce)
elseif PORTB.0 = 1 then
Button.Timeout = 0
low(PORTA.0)
elseif Button.Timeout > 0 then
dec(Button.Timeout)
if Button.Timeout = 0 then
high(PORTA.0)
endif
endif
endif
end interrupt
// program start...
clear(Button) // init button
ADCON1 = $07 // set ANx to digital
low(PORTA.0) // LED A is low, set to output
INTCON2.6 = 0 // INT0 on falling edge
RBPU = 0 // enable weak pullups
INT0IE = 1 // enable INT0
enable(OnChange) // enable interrupt handler
TMR0 = ReloadTimerValue
TMR0IF = false // clear TMR0 IF
TMR0IE = true // enable TMR0 interrupts
TMR0On = true // switch timer on
// loop forever...
while true
wend
- David Barker
- Swordfish Developer
- Posts: 1214
- Joined: Tue Oct 03, 2006 7:01 pm
- Location: Saltburn by the Sea, UK
- Contact:
> It looks very complex...
You could remove the debounce if you like, it would work OK given the amount of time you have to detect a button hold state. Makes it a little easier to follow - just thought it nice to show how easy it is to add debouncing.
Anyway, here are the changes...
You could remove the debounce if you like, it would work OK given the amount of time you have to detect a button hold state. Makes it a little easier to follow - just thought it nice to show how easy it is to add debouncing.
Anyway, here are the changes...
Code: Select all
dim ButtonTimeout as word
// an interrupt declaration with no param
// is high priority by default
interrupt OnChange()
if INT0IF = 1 then
INT0IF = 0
ButtonTimeout = btnTimeout
elseif TMR0IF then
TMR0IF = false
TMR0 = TMR0 + word(ReloadTimerValue)
if PORTB.0 = 1 then
ButtonTimeout = 0
low(PORTA.0)
elseif ButtonTimeout > 0 then
dec(ButtonTimeout)
if ButtonTimeout = 0 then
high(PORTA.0)
endif
endif
endif
end interrupt
// program start...
clear(ButtonTimeout) // init button
Hi David,
The debounce thing is quit nice because I normaly use a RC-Komponent to debounce the switches. (I asked for debouncing some posts ago so it is nice to have it although I didn't understand it yet.)
Only for understanding and using the right form of declarations in the future I want to know wich is the right one
For my understanding it means tha the bit 0 from register PIR1 can have the true or the false (first line). It is like 1 and 0 (second line). Wich is the normaly used way?Thanks
CS
The debounce thing is quit nice because I normaly use a RC-Komponent to debounce the switches. (I asked for debouncing some posts ago so it is nice to have it although I didn't understand it yet.)
Only for understanding and using the right form of declarations in the future I want to know wich is the right one
Code: Select all
DIM TMR0IF As PIR1.Booleans(0)
OR
DIM TMR0IF As PIR1.0
CS
- David Barker
- Swordfish Developer
- Posts: 1214
- Joined: Tue Oct 03, 2006 7:01 pm
- Location: Saltburn by the Sea, UK
- Contact:
> For my understanding it means tha the bit 0 from register PIR1
> can have the true or the false (first line). It is like 1 and 0
> (second line). Wich is the normaly used way?
Good question. It's just a style of coding issue. It's entirely up to you which one you use.
I quite like making bits 'boolean' types. Although
has the virtue of matching the MCU datasheet notation, which I know many people prefer (I do sometimes, it just depends on what I am doing). In some situations, using booleans can make the code more readable, particulary with constructs that require a boolean expression. For example,
but is does take you away from the datsheet somewhat. However, it can really help for some things. For example, take
then you would probably need to comment the code, indicating that when a button is released do something. With a boolean you can almost self document. For example,
In summary
are treated the same - Swordfish is very flexible in this regard, so choose the style you prefer...
> can have the true or the false (first line). It is like 1 and 0
> (second line). Wich is the normaly used way?
Good question. It's just a style of coding issue. It's entirely up to you which one you use.
I quite like making bits 'boolean' types. Although
Code: Select all
DIM TMR0IF As PIR1.0
Code: Select all
dim TimerIsFlagged as PIR1.Booleans(0)
if TimerIsFlagged then
...
endif
Code: Select all
if PORTB.1 = 1 then
...
endif
Code: Select all
dim ButtonIsReleased as PORTB.Booleans(0)
if ButtonIsReleased then
...
endif
Code: Select all
if PIR1.0 = 1 then
...
endif
dim TMR0IF as PIR1.0
if TMR0IF = 1 then
...
endif
dim TMR0IF as PIR1.Booleans(0)
if TMR0IF then
...
endif