PDA

View Full Version : Interrupt questions



ruijc
- 19th August 2008, 11:03
Hi all,

I'm working on a module to receive data from a logger and display the data on a LCD.

From my previous post i came up with a solution to receive the data from the logger into an eeprom. I'm using the code:


DEBUGIN [DEC VALUE]

All works fine except when the logger stops sending data and i have to go back to the main menu to display the received data.

I thought of using interrupts but came across some issues:

First let me show you the test code:



'PIC 16F88 - module for logger

CMCON=7 'comparators off
CVRCON=0 'Vref Off
CCP1CON=0
T1CON=0

TRISA=%00101010
TRISB=%00000011

INTCON.1 = 0 'Clear RB0/INT External Interrupt Flag bit & re-enable interrupts

'************************************************* ****************************
'DEFINEs
'************************************************* ****************************
@ DEVICE INTRC_OSC
@ DEVICE MCLR_OFF
@ DEVICE PROTECT_OFF

DEFINE OSC 8

@ DEVICE CPD_OFF
@ DEVICE LVP_OFF
@ DEVICE BOD_OFF
@ DEVICE PWRT_OFF
@ DEVICE WDT_OFF

'************************************************* ****************************
ADCON1=%00000000
ADCON0=%00000000
ANSEL=%00000000
'************************************************* ****************************
' DEFINE LCD pins

DEFINE LCD_DREG PORTB
DEFINE LCD_DBIT 4
DEFINE LCD_RSREG PORTA
DEFINE LCD_RSBIT 6
DEFINE LCD_EREG PORTA
DEFINE LCD_EBIT 7
DEFINE LCD_BITS 4
DEFINE LCD_COMMANDUS 2000

'************************************************* ****************************
Include "modedefs.bas" 'Include serial modes

DEFINE DEBUG_REG PORTA
DEFINE DEBUG_BIT 0
DEFINE DEBUG_BAUD 9600
DEFINE DEBUG_MODE 1

DEFINE DEBUGIN_REG PORTA
DEFINE DEBUGIN_BIT 1
DEFINE DEBUGIN_BAUD 9600
DEFINE DEBUGIN_MODE 1

'************************************************* ****************************
'PINS


out var PORTA.0 'also used for ICSP
in var PORTA.1 'also used for ICSP
LED var porta.2 'change led for a button
A3 var porta.3 'NC
a4 var porta.4 'check PCB
pgm var porta.5 'reserved for ICSP
RsBit var porta.6 'RS-Bit for LCD
EBit var porta.7 'E-Bit for LCD
BUT1 var portb.0 'interrupt button
BUT2 var portb.1 'button2
SCL var PORTB.2 ' eeprom SCL pin
SDA var PORTB.3 ' eeprom SDA pin
lcd4 var portb.4 'Data pin for LCD
lcd5 var portb.5 'Data pin for LCD
lcd6 var portb.6 'Data pin for LCD
lcd7 var portb.7 'Data pin for LCD


'************************************************* ****************************

'variables

value var WORD 'value received

'************************************************* ****************************

INIT:

high out
debug $0D, $0A,13,10
PAUSE 50

debug "Module initialization...",13,10
lcdout $fe,1,"initialization"


'************************************************* ****************************

STP:
pause 500
lcdout $fe,1,"1-READ - 2-WRITE"
debug "1-READ - 2-WRITE",13,10

IF BUT1=1 then
WHILE BUT1=1
WEND
INTCON=$90
INTCON.1 = 0 'Clear RB0/INT External Interrupt Flag bit & re-enable interrupts
On Interrupt Goto stall
GOTO rd
ENDIF

IF BUT2=1 then
WHILE BUT2=1
WEND
GOTO wt
ENDIF
GOTO STP

'************************************************* ****************************
rd:
lcdout $fe,1,"choosen 1-READ"
DEBUGIN [DEC VALUE]
lcdout $fe,1,"1-READ...cont"
pause 1500
INTCON=$80
goto stp

'************************************************* ****************************

wt:
lcdout $fe,1,"choosen 2-WRITE"
pause 1500
goto stp

'************************************************* ****************************
disable
stall:
lcdout $fe,1,"pressed interupt"
INTCON.1 = 0
pause 1500
resume

end



After checking the manual, it states that it should have the RESUME line. So far so good, but i dont what it to resume but instead go to one label and then go where ever i want. So i did this:



stall:
lcdout $fe,1,"pressed interupt"
INTCON.1 = 0
pause 1500
'resume
goto stp


The result was that the program after the interrupt just stayed looped inside the labeled stall.Is it a must to resume ???


One other thing is that following the manual's example of placing


On Interrupt Goto stall
INTCON=$90 'start interrupts

Does not work because pressing the button it goes directly to the labeled stall ( not passing through the labeled rd ).

I changed it with



INTCON=$90 'start interrupts
On Interrupt Goto stall

And this way works as expected. Is the manual wrong ?

One last thing i noticed is that when a PAUSE command is being executed the interrupt needs to wait until it jumps to it's label.
This is also true with the DEBUGIN [DEC VALUE] command. Meaning that not receiving any data it will hang here. The interrupt will not cancel this line.
Being true how can I cancel the input of data when it's finish ??

Sorry for the long post

HenrikOlsson
- 19th August 2008, 14:04
Hi,
You are right that the interrupt routine won't execute untill the current PBP statement is finished so it WILL hang on the DEBUGIN statement. This is clearly stated in the manual and the biggest drawback of PBP's way of handling interrupts in Basic. Regarding RESUME....You could say RESUME Label and the execution will continue at Label instead of where it was interrupted.

However, it seems to me that a simple timeout may be enough and DebugIn HAS an optional timeout function that you can use to jump back to your main routine if no data is received within the specified time - that is, as soon as the dataline has been "silent" for the specified time it jumps to the routine of your choise.

If you need to use interrupts in more advanced way than than PBP offers natively then look no further than to Darrel's Instant Interrupt routines, it lets you write your interrupt code in Basic without the drawback of PBP way of handling it.

/Henrik.

Melanie
- 19th August 2008, 14:14
Hi,
...that is, as soon as the dataline has been "silent" for the specified time it jumps to the routine of your choise.


Only if is silent (ie no noise) AND it idles in the correct state.

ruijc
- 19th August 2008, 14:47
Greetings HenrikOlsson ,

thanks for the tip about the timeout, i didnt noticed it.

I will try it, but i think it's the most logical way to do this.

I've noticed that the timeout is used in milliseconds, but it doesnt say what is the max value it can accept?

I will need maybe 30sec at least.

Melanie,

thank you also for reminding that. Makes perfect sense ;)

.

HenrikOlsson
- 19th August 2008, 16:47
Hi,
I'm not sure what the maximum timeout value is but I'd guess it's 65535. If you find the limit to be lower than what you need you could stack multiple DEBUGIN statements so when the first one times out it jumps to the second etc.

/Henrik.

ruijc
- 19th August 2008, 22:18
Works as expected :)

thanks

@ Melanie

I used a 33pF cap between signal and gnd to reduce noise.