PDA

View Full Version : Interrupt?? problem



scorpion
- 14th July 2005, 21:43
I havent posted anything up on here for a while... things have been going good.... untill now. I kindof feel bad that I always ask for help, but never offer any good solutions to other peoples problems.

anyways, here is my newest problem.
This program doesnt do much, all it does is takes the input from a hall sensor and outputs a pwm proportional to the input.

I have the data sheet memorised and I read most of the threads that i could find. I did read the olympic timer example as many of you can tell by my formatting.

I am sure that the problem rests somewhere in the timer or interrupt. Im sure its just something simple that I am missing.

here is the code:

'PIC SETTINGS
'------------
define osc 20 '20MHz Oscillator used
define adc_bits 10 'ADC result is 10 bit

'I/O Declarations
'----------------
pwmout var portc.2 'Output Pin for one chan PWM
pwmout2 var Portc.3 'PWM Output Pin #2

'Variable declorations
'---------------------
offval var word 'innital reading. holds min input value
offmax var word 'the min input value + some hysterisys
span var word 'The total possible input span
current var word 'Holds the current ADC value
above var word 'the value above 0
abovex var word 'above x 100 for percent division
percent var word 'input percentage
outspan var word 'the total output span (min to max)
steps var word 'the size of output steps between min and max
stepsabove var word 'the number of steps above min
onsteps var word 'the total number of steps the output is high
tick var byte 'keeps count of the number of interrupts

'constants
'---------
maxper con 80 'max output percent
minper con 20 'min output percent
hys con 20 'hysterisys for zero position
inmax con 1023 'max input value


'Program Start
'=============
'Initialise Controller
'---------------------
TRISA = %00000000 'all of port A set to output
TRISC = %00010011 '1, 2, and 5 set to inputs
ADCON0 = %10010101 'Set up to use AN5 as the input, right justified,VDD reference.
ADCON1 = %00100000 'conversion clock set to 1:32 (fastest with 20MHz clock
cmcon = 7 'Turn off the comparitors.

'timer/interrupt
'----------------
'do something here????
on interrupt goto ticker
option_reg = 0 'Tmr0: Internal clock. Prescaler set to min (1:2)
intcon = %10100000 'enable Tmr0 Interrupt



'get offval
'----------
adcin 5, offval 'get the start position of the hall

'calculate offmax and span
'-------------------------
offmax = offval + hys 'hysterisys for off position
span = inmax - offval 'The total input span (assuming 1024 is fully depressed)

'main loop
'---------
main:
adcin 5, current 'Get the current value
if current < offmax then goto main 'If its off forget the rest
above = current - offval 'calculate the current value from 0
abovex = above * 100 'multiply it by 100
percent = abovex / span 'calculate the percentage
outspan = maxper - minper 'figure out the output span
steps = outspan / 100 'find the size of steps
stepsabove = steps * percent 'how many steps to move
onsteps = stepsabove + minper 'add the min output value
goto main

ticker:
disable 'disable interrupts
intcon.2 = 0 'clear flag
TMR0 = 129 'Set Preload
tick = tick + 1 'keeps track of times it was interrupted
if tick = onsteps then low pwmout 'if its where it needs to be to be switched, switch it
if tick = 100 then 'if its at the end
if current > offmax then high pwmout'and its above hysterisys then turn reset the PWM
tick = 0 'and restart the ticker
endif
enable 'enable interrupts
resume 'Restart the main program from where it left off



TIA for any help
-Scorp

Bruce
- 15th July 2005, 02:45
Hi Scorp,

Place disable before your interrupt sub-routine label, and place resume before
enable at the end. Resume inserts retfie. Enable tells PBP to start inserting
code to continue testing for the interrupt condition again. If you reverse the
two, you're jumping out of the interrupt service routine to test for the
interrupt condition you're already servicing.

If you're using ADCIN, you don't need to mess with ADCON0. PBP handles this
one for you automatically. TRIS, ADCON1, (ANSEL where applicable) must
already be setup before using ADCIN, so make sure you set whatever A/D
input pin you're using up as an input first.

scorpion
- 15th July 2005, 03:23
I will try it first thing tomorow, but one question: If I move the disable and enable how will it ever get run? wouldnt it just skip right past those??? maybe im not sure exactly what you mean:

disable 'disable interrupts
ticker:
intcon.2 = 0 'clear flag
TMR0 = 129 'Set Preload
tick = tick + 1 'keeps track of times it was interrupted
if tick = onsteps then low pwmout 'if its where it needs to be to be switched, switch it
if tick = 100 then 'if its at the end
if current > offmax then high pwmout'and its above hysterisys then turn reset the PWM
tick = 0 'and restart the ticker
endif
resume 'Restart the main program from where it left off
enable 'enable interrupts

I really cant see how this would work. i am assuming that i misunderstood.....

Bruce
- 15th July 2005, 03:53
Disable tells PBP to STOP auto-insertion of interrupt checking code. Placing
disable "before" the interrupt service label doesn't actually disable interrupts.
It just tells PBP to stop automatically placing interrupt checking code between
each BASIC command. Your interrupt will work either way.

ON INTERRUPT GOTO ? tells PBP where the interrupt service routine is located.

Resume inserts RETFIE right at the end of your interrupt handler "code", and
that's where you want RETFIE to be.

Enable tells PBP to start auto-inserting interrupt testing code after each
BASIC instruction, and you want this at the very end or after RESUME. Just
like the ON INTERRUPT example shown in the manual.

scorpion
- 15th July 2005, 04:14
gotcha.
thanks for the help!
-scorp