Interrupt mystery - need some guru help
In the code below, something strange happens.
(I'm using an LCD display to check what's happening in the program.)
When the program starts, it seems to jump directly to the On Interrupt routine and when the porta pins states are displayed I see that the values are those I expect:
A.0=1, A.1=1, A.2=1, A.3=0, A.4=1, A.5=1 so no interrupt should have occured because there is absolutely nothing connected to portA.
WHY???
Can someone help me to solve this mystery.
Thanks for any help.
@ device pic16F684, intrc_osc_noclkout, BOD_OFF, PWRT_OFF, wdt_off, mclr_off, protect_off
DEFINE OSC 8 'set OSC value to 8MHz for instructions PAUSE, PAUSEus and SOUND
'-----------------------------------------
DEFINE LCD_DREG PORTC 'data port out is portc
DEFINE LCD_DBIT 0 'data on portc0-portc3
DEFINE LCD_RSREG PORTC 'rs is on portC5
DEFINE LCD_RSBIT 5
DEFINE LCD_EREG PORTC 'enable in on portC4
DEFINE LCD_EBIT 4
DEFINE LCD_BITS 4 '4bits data bus
DEFINE LCD_LINES 2 '2lines display
DEFINE LCD_COMMANDUS 2000 '2ms cmd delay
DEFINE LCD_DATAUS 50 '50us data delay
CLEAR
OSCCON = %01110001
CMCON0 = %00000111 'comparators OFF, val = 7
ANSEL = %00000000 'choose digital i/o, val = 0
OPTION_REG = %01111111 'enable porta weak pullups (no weak pull-up available for porta.3), p12
WPUA = %110111 'enable internal weak pull ups resistors individually on portA pins to bring them HIGH internaly, except for porta.3 (Ra3 can be set as mclr or as i/o port with config words)
INTCON = %10001000 'enable GIE and porta interrupts on change, datasheet p13
IOCA = %111111 'no int for ra4 = r/s bit
TRISA = %111111
TRISC = %000000 'all portc pins are set to output mode, PWM starts if CCP1CON is enabled
'PORTA = %000000 'turn off porta pins
'PORTC = %000000 'turn off portc pins
i VAR BYTE
ON INTERRUPT GOTO in_sig 'when interrupt occurs on any portA pin (except portA.3) go to int routine
loop1: 'main program is a stupid loop waiting for a int on change triggered by an ir signal on sensors
'-----------------
'test
lcdout $fe,2 'home pos
lcdout $fe,1,"loop1" 'clear and display
'-----------------
PAUSEus 15 'shortest pause possible to quickly jump to routine for extracting bullet signal contents
'at 8MHz, minimum delay is 12 uS (or 24 uS at 4MHz)
'in my routine, some uS can be wasted until the signal decoding occurs, too much and the signal will be invalid because of the offset
GOTO loop1
DISABLE
'disable interrupts while executing the interrupt routine (do not put check interrupts calls after each instruction)
in_sig: 'int routine code starts here
'--------------
for i = 0 to 5
LCDOUT $FE, 1,"value",#i,"=",#portA.0(i)
PAUSE 2000
nEXT i
INTCON.0 = 0
resume 'end int routine
enable 'REENABLE interrupts (global flag), PBP lame instruction
END 'end of program
'1. How can I reference a BIT in a BYTE?
'http://www.picbasic.co.uk/forum/archive/index.php/t-544.html
' For MyVar=0 to 7
'MyBit=MyByte.0(MyVar)
'LCDOut $FE,1,"Bit ",#MyVar,"=",#MyBit
'Pause 2000
'Next MyVar
no more riddles, need advises
Please, no more riddles.
I beleive the portA has to be read prior to enabling interrupts.
Are these steps order right?
- enable weak pullups with OPTION_REG = %01111111 (even if I DON'T know what should be the settings for bits 0 to 6, which seem not useful for me)
- enable WPU for desired ports, for me it should be: 010111 (no WPU for RA3 which is used as an input port) (no WPU for RA5 which is used with default 0V and is activated when 5V gets to this pin)
- TRISA = %101111 because all porta pins has to be input except for pin RA4 which is used for R/S bit for an LCD pannel
- TRISC = %000000 (all output)
- PORTA.5 = 0 (I set specificaly RA5 to 0 because I want it to be LOW at the start, all other porta pins will be brought high automatically by WPU)
- PORTC = %000000 (I set all portC pins low)
- I initialize all my variables
- I put some stuff here like display on LCD
- IOCA = %101111 because I enable PORTA change interrupt for all porta pins except for the pin used for LCD R/S bit
- INTCON = %10001000 (I enable interrupts: GIE and portachange)
- ON INTERRUPT GOTO myroutine
Is that correct?
solving interrupt mysteries
Quote:
Originally Posted by
Darrel Taylor
Remind me not to fly on one of your planes.
When people get thrown extra duty because they didn't know something and the boss refused to help.
It's likely they won't bother asking questions the next time they have problems.
Who know's what goes un-fixed.
Fine, I'll do it.
xnihilo,
Code:
i VAR BYTE
i = PORTA ' Clear mismatch condition
INTCON = %00001000 ' enable porta interrupts on change and clear flag
ON INTERRUPT GOTO in_sig ' int routine
Remove the other INTCON statement.
Thank you very much, I'll report if it worked for me.
Have a nice WE.