DT INTs which int to use??
working with a 16F690 PIC
My program is supposed to generate 1 or more pulses of specific length and quantity.
Thought I had Darrels Instant Interrupts working in my code...
But when I remarked out these lines (because I thought they were redundant with DT INT's)
Code:
'IOCB.7=1 'enable INT on change RB7
'IOCB.6=1 'enable INT on change RB6
'IOCB.5=1 'enable INT on change RB5 rotary push button
My rotary encoder stopped working.
I had this code in my program also... but I don't think I have the correct interrupt selected.
Code:
ASM
INT_LIST macro ; IntSource, Label, Type, Resetflag?
INT_Handler IOC_INT, _Encoder, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM
So my question is... How does one know which INT to use?? I am wanting to interrupt on change for B.5, B.6, B.7 and sometimes B.4 .
I am looking at the 16F690 documentation but am confused on exactly how to determine which INT to use.
I also would like to, at times, disable B.5,6&7 but keep B.4 as interruptable.
Here is my complete code...
Code:
#CONFIG
__CONFIG _INTRC_OSC_NOCLKOUT & _WDT_OFF & _PWRTE_OFF & _MCLRE_OFF & _CP_OFF & _CPD_OFF & _BOD_OFF & _IESO_OFF & _FCMEN_OFF
#endconfig
include "ALLDIGITAL.pbp" ' makes all I/O pins digital, no analog
INCLUDE "DT_INTS-14.bas" ; Base Interrupt System
INCLUDE "ReEnterPBP.bas" ; Include if using PBP interrupts
wsave VAR BYTE $70 SYSTEM ' alternate save location for W
DEFINE OSC 4
Define LCD_DREG PORTC
Define LCD_DBIT 4
Define LCD_RSREG PORTA
define LCD_RSBIT 4
define LCD_EREG PORTA
define LCD_EBIT 5
define LCD_BITS 4
define LCD_LINES 4
define LCD_COMMANDUS 3000
define LCD_DATAUS 100
red var PortC.0
grn var PortC.1
sLCD var PortA.2 'serial LCD (if used)
TrisA = %00000000 'xx543210
TrisB = %11110000 '7654xxxx
TrisC = %00001000 '76543210
' N/U PortB.0 (output)
' N/U PortB.1 (output)
' N/U PortB.2 (output)
' N/U PortB.3 (output)
' N/U PortB.4 (input - to be grounded)
' Encoder PushButton PortB.5 (input)
' Encoder channel A PortB.6 (use pullups resistor if necessary)
' Encoder channel B PortB.7 (use pullups resistor if necessary)
'-------------------------------------------------------------------------
eeprom 0,[2,0,3,1,1,3,0,2]
PortB = 0
Flag var byte
BtnFlag var byte '0=adj P1, 1=adj P2, 2=adj Cnt
CFlag var bit
Q_New var Byte
Q_Old var byte
M_Count var byte [4]
P_Count var byte [4]
Q_Count var word
Low_Count var word
L var bit 'flag Rotate Left
R var bit 'flag Rotate Right
P1 var word ' first pulse value
P2 var word ' second pulse value
Cnt var word ' quantity of pulses to generate
Reps var word ' counter to loop for pulses
Cursor var word 'if 0 then P1, if 1 then P2, if 2 then Cnt
Busy var bit
P1=500 'default pulse width
P2=0 'default no second pulse toggle
Cnt=1 'default count of 1 pulse
cflag=0 'default to One pulse repitition
' ---------------------- Set variable value @ startup ----------------------
Start:
btnflag=0
Cursor=0
low_count = 100
Busy=0
For Q_Old = 0 to 3
Read Q_Old,M_Count[Q_Old]
Read Q_Old + 4,P_Count[Q_Old]
Next Q_Old
Q_Count = 0
Q_New = 0
Q_Old = 0
Flag = 0
'IOCB.7=1 'enable INT on change RB7
'IOCB.6=1 'enable INT on change RB6
'IOCB.5=1 'enable INT on change RB5 rotary push button
ASM
INT_LIST macro ; IntSource, Label, Type, Resetflag?
INT_Handler IOC_INT, _Encoder, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM
low PortC.2 'initialize contact output
pause 1000
Lcdout $FE, 1 ' Clear LCD screen
Lcdout $FE,$80,"Pulse Generator" ' Display message
'serout2 slcd,16468,[$FE,$80,"Pulse Generator"]
'serout2 SLCD,16468,[$1b, $2a, $20]
pause 500
lcdout $FE,$C0+19,"<" 'initial pointer on P1
'serout2 slcd,16468,[$FE,$C0+19,"<"]
gosub disp1
gosub DisP2
gosub DisC
Pause 500 ' Wait .5 second
sound PortA.0,[90,5,100,5,110,5]
'===============================
'===========================================================
'======= Main Program Loop ==========================
'===========================================================
Main_Loop:
@ INT_ENABLE IOC_INT ; enable external (INT) interrupts
if PortB.4=0 then gosub pulseout ' "GO" button pushed so generate pulses
if PortC.3=0 then ' "Toggle" button pushed so invert output
Toggle PortC.2
sound PortA.0,[120,2]
do while PortC.3=0 : loop 'wait for button to be released
endif
if flag=0 then main_loop 'no activity from rotary encoder
'@ INT_DISABLE ; DISABLE external (INT) interrupts
if btnflag=1 then
if Cursor=0 then ' erase Cursor on Row 2
lcdout $FE,$C0+19," "
'serout2 slcd,16468,[$FE,$C0+19," "]
endif
if Cursor=1 then ' erase Cursor on Row 3
lcdout $FE,$94+19," "
'serout2 slcd,16468,[$FE,$94+19," "]
endif
if Cursor=2 then ' erase Cursor on Row 4
lcdout $FE,$D4+19," "
'serout2 slcd,16468,[$FE,$d4+19," "]
endif
Cursor=Cursor+1 ' now increment Cursor position
if (p2>0) and (Cursor=3) then Cursor=0
if (p2=0) and (Cursor=2) then 'skip moving cursor to 4th row
Cursor=0 'instead goto row 2
cnt=1
gosub DisC
endif
btnflag=0
if Cursor=0 then 'display cursor on row 2
lcdout $FE,$C0+19,"<"
'serout2 slcd,16468,[$FE,$C0+19,"<"]
endif
if Cursor=1 then 'display cursor on row 3
lcdout $FE,$94+19,"<"
'serout2 slcd,16468,[$FE,$94+19,"<"]
endif
if Cursor=2 then 'display cursor on row 4
lcdout $FE,$D4+19,"<"
'serout2 slcd,16468,[$fe,$d4+19,"<"]
endif
sound PortA.0,[100,2]
endif
if Cursor=1 then goto p2counter
if Cursor=2 then goto ccounter
'else fall through to P1Counter
'-------------------------------
' adjust value of P1
'-------------------------------
P1Counter:
if r =1 then
high grn 'rotation is Right so Incriment
if p1>999 then
p1=p1+100
elseif p1>99 then
P1=P1+10
else
p1=p1+1
endif
if p1>10000 then p1=0
gosub DisP1
r=0
endif
if l =1 then
High red 'rotation is Left so Decriment
if p1>1000 then
p1=p1-100
elseif p1>100 then
P1=P1-10
else
p1=p1-1
endif
if p1>65000 then p1=10000
gosub DisP1
l=0
endif
goto Main_Loop
'-------------------------------
' adjust value of P2
'-------------------------------
P2Counter:
if r=1 then
high grn 'rotation is Right so Incriment
if p2>999 then
p2=p2+100
elseif p2>99 then
P2=P2+10
else
p2=p2+1
endif
if p2>10000 then p2=0
gosub DisP2
r=0
endif
if l=1 then
High red 'rotation is Left so Decriment
if p2>1000 then
p2=p2-100
elseif p2>100 then
P2=P2-10
else
p2=p2-1
endif
if p2>65000 then p2=10000
gosub DisP2
l=0
endif
goto main_loop
'-------------------------------
' adjust value of Cnt
'-------------------------------
CCounter:
if r=1 then 'rotation is Right so Incriment
high grn
if cnt>999 then
cnt=cnt+100
elseif cnt>99 then
cnt=cnt+10
else
cnt=cnt+1
endif
if cnt>10000 then cnt=0
gosub DisC
r=0
endif
if l=1 then 'rotation is Left so Decriment
High red
if cnt>1000 then
cnt=cnt-100
elseif cnt>100 then
cnt=cnt-10
else
cnt=cnt-1
endif
if cnt>65000 then cnt=10000
gosub DisC
l=0
endif
goto main_loop
'-------------------------------
' Update LCD display
'-------------------------------
DisP1:
If P1>999 then P1Sec 'change to seconds instead of milliseconds
P1Ms:
lcdout $FE,$C0,"1st Pulse= ",dec3 P1," mS "
'serout2 slcd,16468,[$FE,$C0,"1st Pulse= ",dec3 p1," mS "]
goto donelcd
P1Sec:
if P1=10000 then
lcdout $FE,$C0,"1st Pulse= ",dec2 (P1/1000),".",dec1 (p1/100)," Sec"
'serout2 slcd,16468,[$FE,$C0,"1st Pulse= ",dec2 (P1/1000),".",dec1 (p1/100)," Sec"]
else
lcdout $FE,$C0,"1st Pulse= ",dec1 (P1/1000),".",dec1 (p1/100)," Sec "
'serout2 slcd,16468,[$FE,$C0,"1st Pulse= ",dec1 (P1/1000),".",dec1 (p1/100)," Sec "]
endif
goto DoneLCD
DisP2:
if P2>999 then P2Sec 'change to seconds instead of milliseconds
P2Ms:
lcdout $FE,$94,"2nd Pulse= ",dec3 P2," mS "
'serout2 slcd,16468,[$FE,$94,"2nd Pulse= ",dec3 P2," mS "]
goto donelcd
P2Sec:
If P2=10000 then
lcdout $FE,$94,"2nd Pulse= ",dec2 (P2/1000),".",dec1 (p2/100)," Sec"
'serout2 slcd,16468,[$FE,$94,"2nd Pulse= ",dec2 (P2/1000),".",dec1 (p2/100)," Sec"]
else
lcdout $FE,$94,"2nd Pulse= ",dec1 (P2/1000),".",dec1 (p2/100)," Sec "
'serout2 slcd,16468,[$FE,$94,"2nd Pulse= ",dec1 (P2/1000),".",dec1 (p2/100)," Sec "]
endif
goto DoneLCD
DisC:
if cnt = 10000 then
lcdout $FE,$d4,"Continuous Pulses "
goto DoneLCD
endif
if cnt <10 then
lcdout $FE,$d4,"Pulse Count= ",dec cnt," " 'need extra space char
else
lcdout $FE,$d4,"Pulse Count= ",dec cnt," "
'?? serout2 slcd,16468,[$FE,$d4,"Pulse Count= ",dec cnt," "]
endif
DoneLCD:
Flag = 0 ' reset flag after display updated
low red
low grn
return
'-------------------------------
' Generate desired Pulse
'-------------------------------
PulseOut:
'@ INT_DISABLE RABC_INT ; disable external (INT) interrupts
sound PortA.0,[75,2]
Busy=1
Continuous:
if cnt=10000 then 'do continuous pulses
Toggle PortC.2
pause P1
Toggle PortC.2
pause p2
goto Continuous 'do unitl Rotary button pushed
endif
for reps=1 to cnt
Toggle PortC.2
pause P1
Toggle PortC.2
pause p2
next reps
if (cnt=1) and(P2>0) then Toggle PortC.2 'on/off/on or off/on/off
sound PortA.0,[100,10,50,10]
pause 500
Busy=0
return 'to Main program loop
'================================================================
'======================================
'-- Rotary Encoder Interrupt Handler --
'======================================
Encoder: ' ISR
If PortB.5=0 then 'INT caused by encoder push button
btnflag=1
do while PortB.5=0 : loop
goto Exitint
endif
Q_New = PortB.7 + PortB.7 + PortB.6 ' get port status
'--------------------
' decriment -
'--------------------
If M_Count[Q_Old] = Q_New then ' if M_Count code satisfied then minus
Q_count = Q_Count - 1
r=1 ' Set Left Flag
goto Q_Skip
endif
'--------------------
' incriment -
'--------------------
If P_Count[Q_Old] = Q_New then ' if M_Count code satisfied then plus
Q_Count = Q_Count + 1
l=1 ' Set Right Flag
endif
Q_Skip:
Q_Old = Q_New ' update Q_Old Byte
ExitInt:
flag=1
@ INT_RETURN
Also a little unsure of EXACT syntax when using instant interrupts with regard to how many spaces, etc. when defining the interrupts.
Re: DT INTs which int to use??
I used to use a 16f690 (but haven't for ages....the more modern version 16f1828 is much nicer with respect to IOC...unless you are specifically tied to the 16f690 I heartily recommend getting/using a 16f1828 instead...it's pin for pin compatible to the 16f690) ), but here's an old thread where I was struggling with my 16f690 , Bruce sailed to the rescue...
http://www.picbasic.co.uk/forum/showthread.php?t=13558
there's an example IOC for a 16f690 zip file attached to the post (near the bottom of that page) ...that should show you how to approach IOC on a 16f690.
Re: DT INTs which int to use??
Thanks Spankey...
I followed that thread you referenced and could see that in that case with the 16f690 they used RABC_INT... and I used that in my latest code and it is working. Although I did have to un-comment the lines [CODE]['IOCB.7=1 'enable INT on change RB7
'IOCB.6=1 'enable INT on change RB6
'IOCB.5=1 'enable INT on change RB5 rotary push button/CODE]
So I guess they are not redundant with DT-INT's
What I am not understanding is how does one determine that RABC_INT is the correct one for 16f690 from the microchip documentation. I searched the .pdf for that PIC and it fails to even find "rabc".
I also would like clarification on the exact syntax of setting up DT-INT's. ie. where and how many spaces are required at the beginning and inside of each line of the code
Help me "mister wizard" er... Darrell
Re: DT INTs which int to use??
So, for clarification, here is what I have that is working...
Code:
IOCB=%11110000 'enable INT on change RB 7,6,5,4
ASM
INT_LIST macro ; IntSource, Label, Type, Resetflag?
INT_Handler RABC_INT, _Binthndlr, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM
Note that I changed the individual ...
Code:
'IOCB.7=1 'enable INT on change RB7
'IOCB.6=1 'enable INT on change RB6
'IOCB.5=1 'enable INT on change RB5 rotary push button
Into one statement...
Code:
IOCB=%11110000 'enable INT on change RB 7,6,5,4
(and added the additional bit that enables IOC on B.4)
But I still wonder which part of my code is actually enabling the INT on change. As I look over at darrel's web page where he gives examples I do not see anywhere that he has to manipulate the registers to enable the INT's.
So I am back to thinking that it is really my code that is making the INT's work and part of Darrel's code that tells the PIC where to jump to on INT. "Binthndler"
still confused
Re: DT INTs which int to use??
To know which Int to use, you need to be a bit of a sleuth, the same thread...
http://www.picbasic.co.uk/forum/show...2315#post92315 (checkout Bruce's post #30)
I think you need to open dts_int-14.bas, do a search within for RABC, you should see these entries...
Code:
#define RAC_INT INTCON,RAIF, INTCON,RAIE ;-- RA Port Change *
#define RBC_INT INTCON,RBIF, INTCON,RBIE ;-- RB Port Change
#define RABC_INT INTCON,RABIF, INTCON,RABIE ;-- RAB Port Change
....see which one of those bolded registers a 16f690 actually has & then use the associated DTS Int. (eg search the data sheet for RAIF...nothing, RBIF...nothing, RABIE ...bingo ...so use the RABC_INT)