View Full Version : On Interrupt question
peu
- 27th January 2006, 03:24
Hi, im trying to understand how to use ON INTERRUPT, so I created this little program:
@ device pic16F628A, intrc_osc_noclkout, wdt_on, mclr_off, protect_off
DEFINE OSC 4
trisb =%00110000
trisa =%00000000
'ansel =%00000001
cmcon =%00000111 'Comparators Off
vrcon =%00000000
intcon =%10101000 'interrupts enable
OPTION_REG =%01010001
but1 var trisb.4
but2 var trisb.5
ledwork var trisa.0
led1 var trisa.1
led2 var trisa.2
led3 var trisa.3
rs var trisa.5
conta var byte
on interrupt goto interrupcion
;SerOut rs,2,[10,13]
;SerOut rs,2,["inicio"]
;SerOut rs,2,[10,13]
enable
loop:
;disable
;SerOut rs,2,[10,13]
;SerOut rs,2,["Loop"]
;SerOut rs,2,[10,13]
;enable
for conta=0 to 255 step 16 'working led rise routine
pwm ledwork, conta, 10
next conta
high ledwork
for conta =0 to 100
pause 10
next conta
low led1 'set status buttons leds off
low led2
low led3
for conta=0 to 255 step 16 'Fall routine
pwm ledwork, 255-conta, 10
next conta
low ledwork
for conta =0 to 100
pause 10
next conta
low led1 'set button status leds off
low led2
low led3
goto loop
end
disable
interrupcion:
;SerOut rs,2,[10,13]
;SerOut rs,2,["Interrupt"]
;SerOut rs,2,[10,13]
intcon.0=0
intcon.1=0
intcon.2=0
if but1=1 then
but1=0
high led1
endif
if but2=1 then
but2=0
high led2
endif
high led3
resume
enable
The idea is to trigger an interrupt when any of the buttons (but1 & but2) are pressed, to show the status a led (led1 & led2) is turned on for a second and off again. led3 is used as a way to know an interruption has been triggered.
To simulate a real loop the "payload" of the program is a PWM pulse on ledwork
There are serouts all over the place, but since I cant make the basic version to work, these are commented out.
IMHO this program should work, but it doesn't. Could someone guide me in the right direction to fully understand how this should work?
Thanks!
mister_e
- 27th January 2006, 03:36
begin by changing this
but1 var trisb.4
but2 var trisb.5
ledwork var trisa.0
led1 var trisa.1
led2 var trisa.2
led3 var trisa.3
rs var trisa.5
to
but1 var PORTB.4
but2 var PORTB.5
ledwork var PORTB.0
led1 var PORTB.1
led2 var PORTB.2
led3 var PORTB.3
rs var PORTB.5
Let's see what happen now. i didn't go deeper than this.. for now ;)
peu
- 27th January 2006, 04:20
I changed as you suggested but corrected the ports, I guess this is what you meant
but1 var PORTB.4
but2 var PORTB.5
ledwork var PORTA.0
led1 var PORTA.1
led2 var PORTA.2
led3 var PORTA.3
rs var PORTA.5
And before the loop starts I added:
porta=0
portb=0
Now I can see the led1/led2 trigger after pressing for about a second, but the generic interrupt led3 is ON all the time which indicates me that the interrupt is being triggered constantly, regardless of the button presses.
Any idea?
Thanks
Pablo
peu
- 27th January 2006, 16:04
Im still puzzled by this, I know I must be near, but Im missing the finish line by a byte or two :)
Thanks, help is appreciated
sougata
- 27th January 2006, 16:24
Hi,
You are turning on the LED3 in the interrupt routine and turning it off in the main loop. So technically it should work. Now consider this :
Your buttons are not debounced so it may quite happen that another rising edge is setting up your interrupt. Since you have the buttons pressed while in interrupt you are being able to detect it and light led1 and led2.
So introduce a pause inside your interrupt after turning on the LEDs and as soon as you inside the interrupt release the button. Then while getting out clear the interrupt flags. This might solve your problem.
Regards
Sougata
peu
- 27th January 2006, 17:10
Hi,
You are turning on the LED3 in the interrupt routine and turning it off in the main loop. So technically it should work. Now consider this :
Your buttons are not debounced so it may quite happen that another rising edge is setting up your interrupt. Since you have the buttons pressed while in interrupt you are being able to detect it and light led1 and led2.
So introduce a pause inside your interrupt after turning on the LEDs and as soon as you inside the interrupt release the button. Then while getting out clear the interrupt flags. This might solve your problem.
Regards
Sougata
Hi Sougata,
If I enter any pause in the interrupt routine (I just tried it) I severelly impair the PWM loops, and this is another indication that the interrupt is being triggered constantly.
Here is the schematic:
http://peu.net/temp/int-test.gif
Thanks
Pablo
sougata
- 27th January 2006, 17:32
Hi,
It seems at a quick glance that you are using the interrupt on change feature on portb. This means you trigger an interrupt on every change on portb<4:7> . In plain english on every edge , a press or release of the button. So the program is jumping into the routine. Without rewiring your circuit you can disable the interrupt altogether in the interrupt routine and then clear flags and set the interrupt in the main loop.
BTW its 22:05 here and time to go home so signing off now.
Regards
Sougata
peu
- 27th January 2006, 17:43
The interrupt is triggered as soon the pic starts, without even pressing a single time any button.
I set the OPTION_REG as follows
bit7 = 1 PORTB pull-ups are disabled
bit6 = 1 Interrupt on rising edge of RB0/INT pin
bit5 = 0 Internal instruction cycle clock (CLKOUT)
bit4 = 1 Increment on high-to-low transition on RA4/T0CKI pin
bit3 = 0 Prescaler is assigned to the Timer0 module
bit2 = 0 Prescaler Rate Select bits
bit1 = 0
bit0 = 1 TMR0 Rate 1:4 WDT Rate 1:2
I can rewire the schematic at will, so if you have a solution this way, please let me know.
Thanks!
sougata
- 27th January 2006, 18:26
Hi,
Try using the portb.0 interrupt pin. Clear the interrupt flags (other than Global int.7) just before the resume and your circuit should work. Try using some sort of debounce circuitry as well. Good Luck. BTW your PIC has a hardware PWM. After the experiment put it to good use.
Regards
Sougata
peu
- 27th January 2006, 18:30
Hi again Sougata,
I need 3 PWM thats why I use the soft version. And regarding the interrupts I need 2 buttons, thats why I choosed the port change instead of the single PortB.0 method.
Any idea on how to do that?
Thanks again!
Archilochus
- 27th January 2006, 19:13
Hi Pablo,
As sougata mentioned, you'll have problems with switch bounce and button press duration causing repeated interrupt flag resets.
Since your code is not 'seeing' an interrupt until after the PWM statements are finished, why not just test the state of the interrupt flag in the pauses in between your PWM loops?
As far as interrupting on power up without a button press, you might try a bit a a pause at the start of the program, then clear the interrupt flags.
Arch
EDIT - ooh... that won't work 'cause it won't sort out the different buttons - darn!
sougata
- 28th January 2006, 04:04
Hi,
On a closer look at your prog I found that you have timer0 to use external clock via RA4. Possibily you did this because there is no timer0 enable disable bit. You wanted your timer not to work. But you have kept the input floating. Spurious counting is going on. Also you have turned on the timer0 interrupt bit in your intcon settings. So a timer0 overflow would trigger the interrupt.
So my suggestions :
1. Disable the T0IE bit
Regards
Sougata
peu
- 28th January 2006, 14:32
Thanks Sougata, I changed that bit and now it works as expected.
A single bit keep me puzzled half week, you gotta love pics... :D
Here is the working example, so others can learn too:
@ device pic16F628A, intrc_osc_noclkout, wdt_on, mclr_off, protect_off
DEFINE OSC 4
trisb =%11111111
trisa =%00000000
cmcon =%00000111 'Comparators Off
vrcon =%00000000
intcon =%10001000'interrupts enable // was %10101000
'OPTION_REG =%11010001
but1 var PORTB.4
but2 var PORTB.5
ledwork var PORTA.0
led1 var PORTA.1
led2 var PORTA.2
led3 var PORTA.3
rs var PORTb.2
conta var byte
porta=0
portb=0
on interrupt goto interrupcion
SerOut rs,2,[" ",10,13]
SerOut rs,2,["Begin",10,13]
LOOP:
SerOut rs,2,["Loop",10,13]
for conta=0 to 255 step 16 'working led rise routine
pwm ledwork, conta, 10
next conta
high ledwork
for conta =0 to 10
pause 10
next conta
low led1 'set button status leds off
low led2
low led3
goto loop
end
disable
interrupcion:
SerOut rs,2,["Interrupt",10,13]
intcon.0=0
intcon.1=0
intcon.2=0
if but1=1 then
but1=0
high led1
SerOut rs,2,["Set",10,13]
endif
if but2=1 then
but2=0
high led2
SerOut rs,2,["Mode",10,13]
endif
high led3
resume
enable
I commented out the OPTION_REG because the program worked ok with and without it. Of course the serouts can be removed, I use them to know where the program is.
Thanks to all for the help provided
Pablo
sougata
- 28th January 2006, 17:15
Hi,
In helping you out I also added my experience. It really feels good when a puzzle gets solved. If you hadn't given the hints that it is jumping to the interrupt even without a button pressed I couldn't have pointed it out. So the credit goes to you for all the labour and time spent.This is only the beginning now concentrate on the PWM part and add some sparkle to your design.
I myself do not rely on the PBP interrupt and tend to use asm as my apps demand.It is not that tough if you give it a try. I am a complete self-taught without much of an academic background. My schedule doesn't permit me always to be active in this forum still I love to.
I am myself very much facinated with RGB LEDs and plan to design an ambilight as in the Phillips plasma TVs. (I cannot afford a LCD or Plasma)But everytime my hobby gets the least attention due to job pressure. I am still in my struggling phase to establish myself as a PIC programmer. I live in a city where neither PICs nor RGB LEDs are easily available. I have to get them from another metro and it is costly in terms of our economy. Still with all of you around I know I am not alone. Thanks to this forum and all PICers out there.
Have a great PICing time.
Regards
Sougata
peu
- 28th January 2006, 17:36
Here is what I did with the previous version that did not used interrupts, just a simple loop of 6 for-next:
What happens when you mix: A toilet scrub and a vase
I hope you didn't bet on this art deco artifact :
http://peu.net/mods/scrub/scrubflower.jpg
Well, you need to add some electronics to the mix: a pic microcontroller, some mosfets, a few resistors, a few luxeon leds, a heatsink, a difuser and a li-ion battery...
and you get this:
luxeons attached to heatsink and difuser over leds:
http://peu.net/mods/scrub/inside.jpg
here is a sequence of frames:
http://peu.net/mods/scrub/sweep.jpg
If you can view DivX files, here is the complete color sweep (480k) (http://peu.net/mods/scrub/rgb-lamp.avi)
Hope you all like it
Pablo
sougata
- 29th January 2006, 14:31
Hi,
Hats off to your vase. Nifty stuff. How about adding a beat detector with a mic input that adapts your PIC to music playin around.
Regards
Sougata
Powered by vBulletin® Version 4.1.7 Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.