-
Hey Darrel, I have a question about N-Bit math as it relates to DT_INTS ASM type interrupt.
Would the ASM part of the N-Bit Math qualify as an assembly interrupt? for instance, can I do math like this in the middle of an asm type interrupt handler, without having to worry? I am not really talking about this code (your degree conversion example) but doing math like this inside an assembly interrupt handler. Or since it is using an include file, I have to worry?
Code:
ASM
MOVE?WP _degree_Total, _Temp1 ; copy degrees to a PVAR
MOVE?CP 65535, _Temp2 ; put multiplier in a PVAR
MATH_MUL _Temp1, _Temp2, _Temp1 ; Temp1 = DEG * 65535
MOVE?CP 35999, _Temp2
MATH_DIV _Temp1, _Temp2, _Temp1 ; Temp1 = Temp1 / 35999 (16-bit result)
MOVE?PP _Temp1, _Temp2 ; copy result to Temp2
MATH_ROR _Temp2 ; rotate right 4 times
MATH_ROR _Temp2
MATH_ROR _Temp2
MATH_ROR _Temp2 ; Temp2 is now 12-bits
MOVE?PW _Temp1, _Decimal_value_16bit ; copy PVAR's to WORDs
MOVE?PW _Temp2, _Decimal_value_12bit
ENDASM
Thanks,
Walter
-
> Would the ASM part of the N-Bit Math qualify as an assembly interrupt?
Absolutely!
The math routines don't use any of PBP system variables.
But they do use an FSR, so that must be saved/restored at the beginning/end of the ISR.
There are two macro's included in N-Bit_Math that do the FSR save/restore ...
@ FSRSAVE
; -- math code here --
@ FSRREST
ADD: DT_INTS already saves/restores the FSR's, so if you're using DT_INTS, there's nothing to worry about.
hth,
-
That is awesome, just opened a ton of possibilities with the speed of ASM, and the ease of DT_INTS and N-Bit Math. Thanks Darrel!
-
Just a quickie, re IOC interrupts....how do I know which one to use? (previously I was using IOC with a 16f690 & used RABC_INT then, but the PIC I'm using now doesn't have a PORT B)
From DT's site...
Several new interrupt sources have been added in version 1.00. GPC_INT, IOC_INT, RAC_INT, RABC_INT and the original RBC_INT are all forms of Port Change Interrupts. The chip being programmed determines which one you need to use.
Where do I look to establish this info?
I'm using one of the newer 14 pin 16F1823 PICs.
-
The key is to look in the INTCON register.
For the 16F690, INTCON.0 is RABIF. So you would use RABC_INT.
With the 16F1823, INTCON.0 is IOCIF, so it's IOC_INT.
I could probably make it so IOC_INT works for all of them. :rolleyes:
They are all "Interrupt On Change".
-
Many thanks Darrel.
I have a problemetette - my program runs fine, but then when I press a switch (to generate an IOC), an interrupt *is* triggered, but it then seems to loop in my interrupt handler (it's actually becuase the INTCON.0 bit seems to be staying at 1, which keeps it jumping to the interrupt handler constantly)
Any ideas, why the IOC_FLAG = 0 entry towards the end of the interrupt handler doesn't appear to be taking affect?
Code:
IOC_FLAG VAR INTCON.0 ' Alias RABIF interrupt flag bit
debug_out var byte
SW1 VAR PORTA.5
on_status var byte
Green_LED VAR PortC.1
ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler IOC_INT, _Switch_Interrupt, PBP, YES
endm
INT_CREATE ; Creates the interrupt processor
ENDASM
Check:
'Check switches before enabling/re-enabling IOC
WHILE SW1 = 0 : WEND ' Wait until all switch inputs = 1
IOC_FLAG = 0 ' Clear the int-on-change flag bit
@ INT_ENABLE IOC_INT ; Enable 'Int On Change' interrupts
on_status = 0
Low GREEN_LED
'+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Switch_Interrupt:
hserout ["trap ", dec IOC_FLAG, 13, 10]
@ INT_DISABLE IOC_INT ; Disable further IOC interrupts
pause 10
IF sw1 = 0 THEN
if on_status = 1 then
on_status =0
Low GREEN_LED
else
High GREEN_LED
on_status =1
endif
endif
pause 20
WHILE SW1 = 0 : WEND
pause 25
IOC_FLAG = 0
@ INT_ENABLE IOC_INT
@ INT_RETURN
This is almost certainly something I'm doing wrong, but then again, it's pretty much a direct what was working fine my functioning 16F690 IOC routine?
-
On these Enhanced chips, the Interrupt On Change works much better than on the older chips.
You can specify wether you want Rising edges, Falling edges or both by enabling them in the IOCAP and IOCAN.
Then each Pin has it's own interrupt flag in IOCAF. And you need to clear those bits.
It's described better in section 13.0 in the datasheet.
http://ww1.microchip.com/downloads/e...Doc/41413A.pdf
-
Yet again, you've come up trumps - worse still I knew about the positive edge/falling edge for triggering an interrupt ...since I'm using weak internal pullups, I selected negative, but I never made the connection that I'd have to clear the flag you mentioned....I've now modified my code to clear IOCAF ..... & it works a treat.
You've made a happy man very old. :D
-
Re: Instant Interrupts - Revisited
I have a fair amount of experience with MPLab and PBP. I'm trying to hook up instant interrupts, and have run into an odd situation. I've pored through the ASM file, source file, compiler and assembler manuals, and the MPLab info, and searched on line, including here. I'm sure it's simple and I'll slap my own forehead when someone points it out, but ... well, if you can supply a pointer, I'd be grateful.
I'm trying to compile the instant interrupts "BlinkyLight" program, which is as follows:
Code:
' ================================
' this Blinky Light program will continue Blinking at the same rate, no
' matter what else you add to the Main: program loop.
LED1 VAR PORTB.1
INCLUDE "DT_INTS-14.bas" ' Base Interrupt System
INCLUDE "ReEnterPBP.bas" ' Include if using PBP interrupts
ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler TMR1_INT, _ToggleLED1, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM
T1CON = $31 ; Prescaler = 8, TMR1ON
@ INT_ENABLE TMR1_INT ; enable Timer 1 interrupts
Main:
PAUSE 1
GOTO Main
' ---[TMR1 - interrupt handler]--------------------------------------------------
ToggleLED1:
TOGGLE LED1
@ INT_RETURN
' ======================================
I'm running MPLab v8.60 with PBP 2.60a. I have used this setup to successfully compile to HEX other programs in PBP. MPASM is the assembler, and I'm using the 110 level of instant interrupts.
I get this odd error from the assembler that it cannot continue, as follows:
Code:
Executing: "C:\PBP\PBPMPLAB.BAT" -p16F628A -ampasmwin -k# "BlinkyLight1.bas"
Executing: "C:\PBP\PBPW.EXE" -p16F628A -ampasmwin -k# "BlinkyLight1.bas"
PICBASIC PRO(TM) Compiler 2.60A, (c) 1998, 2010 microEngineering Labs, Inc.
All Rights Reserved.
ERROR: Unable to execute mpasmwin.Error[101] E:\AVS\V2 DEVT\DUAL DELAY\BLINKYLIGHT1.ASM 231 : ERROR: (wsave variable not found,)
Error[101] E:\BLINKYLIGHT1.ASM 195 : ERROR: (" Add:" wsave VAR BYTE $70 SYSTEM)
Error[101] E:\BLINKYLIGHT1.ASM 252 : ERROR: (Chip has RAM in BANK1, but wsave1 was not found.)
Error[101] E:\BLINKYLIGHT1.ASM 202 : ERROR: (" Add:" wsave1 VAR BYTE $A0 SYSTEM, Or change to wsave BYTE $70 SYSTEM)
Error[101] E:\BLINKYLIGHT1.ASM 268 : ERROR: (Chip has RAM in BANK2, but wsave2 was not found.)
Error[101] E:\BLINKYLIGHT1.ASM 209 : ERROR: (" Add:" wsave2 VAR BYTE $120 SYSTEM, Or change to wsave BYTE $70 SYSTEM)
BUILD FAILED: Thu Mar 10 13:21:14 2011
It looks like the problem is in assembling the instant interrupts code - I think. I clearly have something set up wrong, but what?? Just point me in the direction and I'll go find it.
-
Re: Instant Interrupts - Revisited
Read the error message. It tells you what to do.
-
Re: Instant Interrupts - Revisited
You have error messages that tell you exactly what to do:
Add wsave etc...
Look into your DT-INT-14.bas file at the first section that says:
;-- Place a copy of these variables in your Main program -------------------
;-- The compiler will tell you which lines to un-comment --
;-- Do Not un-comment these lines --
and follow the instructions of the errors you get.
Ioannis
-
Re: Instant Interrupts - Revisited
Got it. Thanks very much. Somehow I missed that the error message was the cure.
I understand the issue now. It seems to work Now got to go burn chips... :)
-
Re: Instant Interrupts - Revisited
Darrel has changed the way DT-INTs work now.
It may surprise but is far better now.
Happy burning :)
Ioannis
-
Re: Instant Interrupts - Revisited
Quote:
Originally Posted by
Ioannis
Darrel has changed the way DT-INTs work now.
It may surprise but is far better now.
Just so I don't miss anything, can you direct me to more information on how they have changed? Is that on line?
-
Re: Instant Interrupts - Revisited
For the practical side, users just get a descriptive message as of what to do in the main program. This errors,that are instructions really, may scare a little. But they just tell you what to do.
Regarding the setup there is no change for the users.
Ioannis
-
Re: Instant Interrupts - Revisited
Thanks for taking the time to point this out for me.
Like many things, it seems obvious now that you say it, and I get to slap myself on the forehead again. :)
It's working fine.
-
Re: Instant Interrupts - Revisited
Hi Darrel,
i found a problem which is not clear to me:
I hava a 18(L)F25K22 and want to use SSP1_INT for my I2C handler, but after compiling the source, i get this error:
....test.asm 1052 : Symbol not priveiously defined (SSP1IF)
When defining SSP2_INT there is no error.
Regards,
Ralf
-
Re: Instant Interrupts - Revisited
Ralf,
What version of MPLAB are you using?
I don't get the error when compiling for SSP1_INT here.
When dealing with new chips like the 25K22, you should always keep up to date.
Current MPLAB version is 8.66.
http://www.microchip.com/stellent/id...&part=SW007002
-
Re: Instant Interrupts - Revisited
Hi Darrel,
yes you are right, i had 8.56, now 8.66 and it works.
BTW: For all I2C Slave progger:
To get the I2C Slave running on a 25K22, use SSP1_INT or SSP2_Int, and, very important, you must set ANSC4 & ANSC3 = 0 for SSP1 and ANSB1 & ANSB0 = 0.
Regards,
Ralf
-
Weird PortB change interrupt
Hey there,
I'm trying to code a portb change interrupt routine with DT's Inst Ints, but it does very weird stuff, and I can't find out why.
The setup:
PIC 16F876 @ 20 MHz
I have connected LEDs to the ports c0, c3, c4 and c5 to check what happens
The input switches are connected to ports b1-b4
The code looks something like this:
Code:
define OSC 20
INCLUDE "DT_INTS-14.bas" ' Base Interrupt System
INCLUDE "ReEnterPBP.bas" ' Include if using PBP interrupts
ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler RBC_INT, _PortBInterrupts, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM
@ INT_ENABLE RBC_INT ; enable PortB change interrupts
main:
toggle led ' Toggles a LED that indicates if the program still runs :-)
pause 250
low portc.0
low portc.3
low portc.4
low portc.5
goto main
PortBInterrupts:
if portb.1 = 1 then
high input1
endif
if portb.2 = 1 then
high input2
endif
if portb.3 = 1 then
high input3
endif
if portb.4 = 1 then
high input4
endif
@ INT_RETURN
What happenes is the following:
If I press any button except of b4, nothing happens.
If I press only button b4 nothing happens
If I press b1 just before b4 then the LED according to b4 lits.
If i press any other button along with b4, the right LEDs light up.
It seems that button b4 is the mainswitch for all other buttons within the interrupt routine. Without b4 nothing happens.
So to verify the code I wrote something like this without interrupts:
Code:
main:
if portb.1 = 1 then high portc.0
if portb.2 = 1 then high portc.3
if portb.3 = 1 then high portc.4
if portb.4 = 1 then high portc.5
pause 250
low portc.0
low portc.3
low portc.4
low portc.5
goto main
With this code everything works fine. Every input lits the according output LED. So it must be a interrupt handling issue that makes the errors...
any ideas?
Pls. Excuse my bad english, it's not my mother tongue...
-
The 16F876 only has "Interrupt On Change" on RB4-7.
-
Re: Instant Interrupts - Revisited
Hm, thanks Darryl. The datasheet isn't really clear in this case (written in the datasheet is only PORTB<7:4>). I always thought portb change is the whole portb as the name says.
I'll check this out tomorrow. Hope it works.
That complicates my circuit a little 'cause I wanted the rb7 and rb6 only for ICSP. Now I have to solder in some jumpers :-)
-
Re: Instant Interrupts - Revisited
A couple of resistors maybe are enough to isolate the ICSP from the rest of the circuit without need of any jumpers.
Ioannis
-
pbppi14e.lib errors
DT, you have given the PBP & PIC users a great gift with your instant interrupts!
My application can't wait for the current statement execution to complete for 'ON INTERRUPT' use.
I've implemented your latest creations after reading your website on DT_INTS-14.
Also, have studied many similar threads with similar problem & tried the posted solutions, but I still get compile errors:
(using PIC16F1826 / PBP2.60C / MPASM )
Error[113]c:\pbp\pbppi14e.lib 1182 : Symbol not previously defined (INT_ENTRY)
Error[113]c:\pbp\pbppi14e.lib 1182 : Symbol not previously defined (INT_ENTRY)
Error[113]c:\pbp\pbppi14e.lib 720 : Symbol not previously defined (INT_EXIT)
Error[113]c:\pbp\pbppi14e.lib 733 : Symbol not previously defined (INT_EXIT)
Error[113]c:\pbp\pbppi14e.lib 737 : Symbol not previously defined (INT_EXIT)
Warning[207]c:\microc~2\pi34cc~1.asm 720: Found label after column 1. (INT_Create)
complete code:
Code:
'******************************
OSCCON = $73 'or %01110011 is for use intosc of 8Mhz
'OSCCON = %11110000 '32Mhz intosc use
Define OSC 8 'define the timing for PBP timing such as pause & serout
'*********************************************
'
'Tris register 1=input(PORdefault) 0=output
'Ansel register 1=analoginput(PORdefault, digital reads are 0) 0=digitalinput
ANSELA = %00001100 '1 = Analog used / Vref+(A3) and Vref-(A2)
ANSELB = %00100000 '1 = Analog used / ADC in (B5 / AN7)
TRISA = %00111100 '0 is output ; 1 is an input(POR Default)
TRISB = %10111111 'Port B
'OPTION_REG.6 = 1 'INT interrupt acts on RISING EDGE
'CLKRCON = %11010000 'Turn on ref clock output BE SURE TO DISABLE "CLOCK OUT" IN MEPROGRAMMER
'
'
'*******Variables*************************
'HeadUnit Connections
HUdat var PORTB.0 'Headunit communications Input or Output
'Strain Gage Connections
GagePwr var PORTA.1 'PowertoStrainBride Output
ADCPin VAR PORTB.5 'StrainSample AN7 Input
'Hall Effect Sensor Connections
SpdDat var PORTB.3 'HallSensor Input
'Digital Pot Connections
PotCS var PORTA.0 'CS DigiPot Output
PotClk var PORTA.7 'SCK DigiPot Output
PotDat var PORTA.6 'SDI DigiPot Output
'Temperature Sensor Connections
TmpSDA var PORTB.4 'SDA Data TempSensor Input
TmpSCL var PORTB.6 'SCL Clock TempSensor Output
'**
wsave VAR BYTE $20 SYSTEM ' location for W if in bank0
'**
'****************************************
Y var byte
Neg var byte
Pos var byte
X var word '16bit variable for PULSIN, 0 to 65,535
SData1 var word 'Speed data
SData2 var word 'Speed data to be sent (Use prior pulse)
WiprPos var byte 'Digipot Command
WiprNeg var byte 'Digipot Command
Mark var byte
Space var byte
Strain var word 'Sampled Strain Value from WheatstoneBridge
'****************************************
wiprneg=%00100000 'Wiper0 v 0000 0000 (nv 0010 0000) write
wiprpos=%00110000 'Wiper1 v 0001 0000 (nv 0011 0000) write
mark=60
Y=0
neg=0
pos=0
x=0
input hudat 'start HUdat as an input pin
'*********************************************
'Interrupt system works on "INT" pin B.0 that is named "HUdat" in the above
include "DT_INTS-14.bas" ;Interrupt System
INCLUDE "ReEnterPBP.bas" ;to use with PBP Interrupt handlers
'*********************************************
ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag
INT_Handler INT_INT, _HandleInt, PBP, yes
endm
INT_Create ;create interrupt processor
endasm
@ INT_ENABLE INT_INT ;enables external interrupts
'*****************************************
Start:
'Set Digital Pots
pause 10
neg=240 '257 is ground
pos=60 '0 is full +V supply
low potcs 'Use Digital Pot's mode 0,0 and its MSB first & Clk idles low
shiftout potdat, potclk, 1, [wiprneg, neg] '8bit digi pot
high potcs
pause 50
low potcs 'Use Digital Pot's mode 0,0 and its MSB first & Clk idles low
shiftout potdat, potclk, 1, [wiprpos, pos] '8bit digi pot
high potcs
pause 10
'***********************
Main:
pauseus 10
pulsin spddat,1,sdata1
sdata2 = sdata1 'store speed data into another var as keep-safe vs. INT
'if hudat then
'' pauseus 2100
' output hudat
' serout2 hudat,16530,[strain.highbyte,strain.lowbyte]
'endif
goto Main
'********************************************
HandleInt:
output hudat 'make HUdat an output pin to send data
strain=24650 'test value
serout2 hudat,16530,[strain.highbyte,strain.lowbyte]
input hudat 'switch HUdat back to an input pin to receive interrupt
@ INT_RETURN
'* * * * * * * * * * * * * * * * * *
Your help would be greatly appreciated, since my application must have an 'instant interrupt'.
[ In this application I have a sensor-unit(code shown above) connected to a head-unit. HUdat pin is on the sensor-unit and awaits a simple signal from the head-unit to activate an interrupt and send data on the same connection. ]
You guys are the best & thanks in advance!
-ray
-
Re: Instant Interrupts - Revisited
:o
My code had
INT_Create
instead of
INT_CREATE
I suppose I should wear my glasses more often.
DTaylor's instant interrupt works great now in my application.
thanks for your patience,
-
Re: Instant Interrupts - Revisited
Sorry if I'm in the wrong thread but this is the only one that came up when I searched for PWPS.
This question is for Darrel, but if anyone else can answer I would appreciate the response just as much.
The PWPS servo code is almost ideal for what I need........I only want 0.5us resolution instead of 1us. Am I able to get 0.5us resolution by simply defining my code to use an 8 MHz OSC and then changing the 4 value in the code snippet below to 8?
GetOsc: ' Retreive defined OSC value on Reset
asm
ifdef OSC
MOVE?CB OSC, _PicOSC
else
MOVE?CB 4, _PicOSC
endif
endasm
Sorry if my terminology isn't 100% correct....I'm a bit of a NOOB to picbasic.
-
Re: Instant Interrupts - Revisited
DEFINE OSC 8 will do but also alter everything based on timing such as HSEROUT/HSERIN/PAUSE etc etc.
OSC is always defined anyways, even if you don't type the DEFINE OSC line. If you don't type the DEFINE OSC, PBP assume 4MHz.
-
Yes, use DEFINE OSC 8 just like you always should.
But if you change PicOSC, it will change all parts of PWPS including the 50Hz pulse frequency.
If you only want to change the resolution, you can modify one line in the .inc file ...
; W1 = TicksPeruSx100 * Position ; original line
W1 = TicksPeruSx100 * Position / 2
Then instead of 0-900, the position variable will be 0 - 1800
1uS resolution (0.1 degrees) was already better than the maximum performance of hobby servo motors.
A resolution of 0.5uS will not have any affect if that's what you are doing.
-
Re: Instant Interrupts - Revisited
Thank you for the quick reply.
I'm actually working with an ESC that has 11 bit resolution so that is why I was looking for 0.5us steps. I'm not sure how much difference it will make but I wanted to try it out anyway.
I really appreciate the help!
-
Re: Instant Interrupts - Revisited
Really? Who makes the ESC? On the other hand, I doubt you will notice a difference, but hey go for it!! :)
-
Re: Instant Interrupts - Revisited
Quote:
Originally Posted by
cncmachineguy
Really? Who makes the ESC? On the other hand, I doubt you will notice a difference, but hey go for it!! :)
It is a Castle Creations ESC........when I spoke to one of their engineers they said all of their ESCs have 2048+ speed steps. I know I can get away with the 8 bit resolution of a standard ESC......but as an engineer I need to get the best (i.e. overkill!) solution!
-
Re: Instant Interrupts - Revisited
The part I can't get through my thick head is this, how small of a change can we cause to happen in 20mS to a spinning mass? So if the motor were actually spinning 20,000, then thats 9.75 rpm per bit at 11 bit resolution. On the other hand, getting the extra bit from the PIC may cause less time available to do other things. Mind you I have never looked at PWPS.
-
Re: Instant Interrupts - Revisited
Hi. I am trying to make this Rotary Encoder work with DT-INTS on a 16F1827 device.
It gets once in the interrupt routine and never seem to exit.
Here is the code so far driving me crazy.
Code:
ASM
__config _CONFIG1, _FOSC_INTOSC & _WDTE_OFF & _PWRTE_ON & _MCLRE_ON & _CP_ON & _CPD_OFF & _BOREN_ON & _CLKOUTEN_OFF & _IESO_OFF & _FCMEN_OFF
__config _CONFIG2, _WRT_OFF & _PLLEN_ON & _LVP_OFF & _STVREN_OFF & _BORV_25
ENDASM
DEFINE OSC 32
OSCCON= %11110000 'PLL enabled, Internal RC-8MHz
' Set LCD Data port
DEFINE LCD_DREG PORTA
' Set starting Data bit (0 or 4) if 4-bit bus
DEFINE LCD_DBIT 0
' Set LCD Register Select port
DEFINE LCD_RSREG PORTA
' Set LCD Register Select bit
DEFINE LCD_RSBIT 4
' Set LCD Enable port
DEFINE LCD_EREG PORTB
' Set LCD Enable bit
DEFINE LCD_EBIT 3
' Set LCD bus size (4 or 8 bits)
DEFINE LCD_BITS 4
' Set number of lines on LCD
DEFINE LCD_LINES 2
' Set command delay time in us
DEFINE LCD_COMMANDUS 1500
' Set data delay time in us
DEFINE LCD_DATAUS 44
INCLUDE "DT_INTS-14.bas" ' Base Interrupt System
INCLUDE "ReEnterPBP.bas" ' Include if using PBP interrupts
'Initializing Registers
PORTB = 0:PORTA = 0
TRISB = $33
TRISA = 0
ADCON0 = 0
ADCON1 = 0
ANSELA = 0
ANSELB = 0
INTCON = $88 ' Binary 10001000
IOCBP=$30
IOCBN=$30
OPTION_REG = 0
WPUB=$33
eeprom 0,[2,0,3,1,1,3,0,2]
led var portb.4
Flag var bit
wsave VAR BYTE $70 SYSTEM ' alternate save location for W
Q_New var Byte
Q_Old var byte
M_Count var byte [4]
P_Count var byte [4]
Q_Count var word
temp var byte
clear
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
ASM
INT_LIST macro ; IntSource, Label, Type, Resetflag?
INT_Handler IOC_INT, _Encoder, pbp, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM
@ INT_ENABLE IOC_INT ; enable external (INT) interrupts
'---------------------------- Initialize LCD ----------------------------
Lcdout $fe, 1 ' Clear LCD screen
Lcdout "System Ready" ' Display message
Pause 500 ' Wait .5 second
Q_Count=50
Goto Main_Loop
Encoder: ' ISR
Q_New = PortB.5 + PortB.5 + PortB.4 ' get port status
If M_Count[Q_Old] = Q_New then ' if M_Count code satisfied then minus
temp=temp+1
if temp=4 then
temp=0
Q_Count = Q_Count - 1
Flag = 1 ' set flag to true to update display
endif
goto Q_Skip
endif
If P_Count[Q_Old] = Q_New then ' if M_Count code satisfied then plus
temp=temp+1
if temp=4 then
temp=0
Q_Count = Q_Count + 1
Flag = 1
endif ' set flag to true to update display
endif
Q_Skip:
Q_Old = Q_New
toggle portb.6 ' update Q_Old Byte
@ INT_RETURN
Main_Loop:
if Flag = 1 then
Lcdout $fe, 1 ' Clear LCD screen
Lcdout dec Q_Count ' Display encoder position (counts)
Flag = 0 ' reset flag to false, display updated
endif
pause 100
goto Main_Loop
Thanks,
Ioannis
-
Re: Instant Interrupts - Revisited
Ioannis,
On those chips, the IOCIF bit is read-only and only gets cleared when ALL of the IOCBF flags are clear.
So you can set the INT_Handler's ResetFlag option to NO.
Then be sure the IOCBF flags are cleared before exiting the ISR.
Also, take a look at section 13.4 in the datasheet regarding clearing the flags.
-
Re: Instant Interrupts - Revisited
Excellent! Works terrific now.
These chips are a little pain in setting them.
Thanks Darrel.
Ioannis
-
Re: Instant Interrupts - Revisited
Use the code in post#27, (new approch to rotary encoder) is more efficient and you can achieve even higher frequency.
Cheers
Al.
-
Re: Instant Interrupts - Revisited
Hi Al. I am using the #27 ISR.
The thing that I added was the check for the 4 counts before Q_Count variable is incremented or decremented.
Thats because the encoder I use produces 4 pulses on every step I turn the knob. Thanks Henrik for noting this.
Ioannis
-
Re: Instant Interrupts - Revisited
The code was written to read quadrature count. Any rotary encoder with two channels will generate quadrature count.
Al.
-
Re: Instant Interrupts - Revisited
Yes that is correct. So the Q_count variable is incrementing by 4.
Ioannis
-
Re: Instant Interrupts - Revisited
If this topic was previously mentioned, I apologize for not finding it.
I'm using a 16F877A with a 4 MHz crystal and two 22pf caps with a LED hooked up to portb.1 and the code from example 2 of DT_ints-14.bas on DTs site. I'm using a oscope to look at the timing of the LED flashes and they are occuring around 950msec apart.
My question is, is there a way to tune the oscillator or modify DT interrupts to get it closer to a true 1 second pulse time? I know it's not far off but I was trying to learn something and maybe make it more accurate at the same time. Your help would be appreciated.
Yes I did read the datasheet but I couldn't find anything like OSC tune that I've seen for the 12F683.