Page 1 of 1
QEI Interrupt Trouble
Posted: Fri Dec 07, 2012 4:25 pm
by garofolo
Hello All,
A while back I posted and got good advice about how to use the QEI hardware. I
am only using it to count encoder steps and it works well.
BUT, I have added so much to my program that polling the encoder is no longer
effective because my main loop is about 250mS. Now I want to have the encoder
movements handled by an interrupt routine, but I am not much luck. I keep
getting a "FaultISR 0xFFFFFFF1 SCB->CFSR=0x00020000" error when the event
occurs.
Does anyone know what this means or what I am doing wrong?
Below is my code.
'QEI Interrupt Test Program 12/6/12 by Dan Garofolo
'
#include "LPC17xx.bas"
INTERRUPT SUB QUADISR
PRINT "It works"
QEICLR = &H1FFF 'Clear pending interrupts
ENDSUB
SUB INIT
SCB_PCONP = SCB_PCONP or (1<<18) 'enable QEI bit in PCONP
PCB_PINSEL3 = PCB_PINSEL3 or (1<<8)'Set pin for PH A
PCB_PINSEL3 = PCB_PINSEL3 or (1<<14)'Set pin for PH B
QEIMAXPOS = 6 'Set max position
QEICON = QEICON or 1 'clear position
QUAD_ISR = ADDRESSOF QUADISR + 1 'Set Vector to the ISR
QEICLR = &H1FFF 'Clear pending interrupts
QEIIES = 1<<5 'Enable bit 5 (Encoder Clock)
VICIntEnable0 = 1<<31 'Enable QEI bit in NVIC
ENDSUB
MAIN:
INIT
MAINLOOP:
PRINT "main routine"
WAIT(1000)
GOTO MAINLOOP
END
Re: QEI Interrupt Trouble
Posted: Tue Dec 11, 2012 5:23 am
by GKDarin
Have you made any progress on this, I am working on the same issue with no success to date.
Re: QEI Interrupt Trouble
Posted: Tue Dec 11, 2012 7:42 pm
by GKDarin
Added the QEITIME and QEILOAD Variables to the example above and this code example now works.
Also added a routine with a timer so that if the Interrupt hasn't occcured in 100,000 microseconds that the RPM Value goes to Zero.
#include "LPC17xx.bas"
Dim CurrCount as Integer
Dim RPM as Single
Dim RPMUpdated as Integer
INTERRUPT SUB QUADISR
CurrCount=QEICAP
Dim NewRPM as Single
NewRPM = (25000000 * CurrCount * 60)/(QEILOAD * 256 * 2)
RPM=(RPM+NewRPM)/2
RPMUpdated=Timer
QEICLR = &H1FFF 'Clear pending interrupts
ENDSUB
SUB INIT
SCB_PCONP = SCB_PCONP or (1<<18) 'enable QEI bit in PCONP
PCB_PINSEL3 = PCB_PINSEL3 or (1<<8) 'Set pin for PH A
PCB_PINSEL3 = PCB_PINSEL3 or (1<<14) 'Set pin for PH B
QEITIME=2000000
QEILOAD=2000000
QEIMAXPOS = 256 'Set max position
QEICON = QEICON or 1 'clear position
QUAD_ISR = ADDRESSOF QUADISR + 1 'Set Vector to the ISR
QEICLR = &H1FFF 'Clear pending interrupts
QEIIES = 1<<5 'Enable bit 5 (Encoder Clock)
VICIntEnable0 = 1<<31 'Enable QEI bit in NVIC
RPMUpdated=Timer 'Set the RPMUdpated Timer to the Current Timer
ENDSUB
MAIN:
INIT
Do
If Timer-RPMUpdated>(100000) then RPM=0
PRINT RPM,QEIPOS
WAIT(100)
Loop
Re: QEI Interrupt Trouble
Posted: Tue Dec 11, 2012 9:32 pm
by garofolo
Hello GK,
Thanks for your post. I still have not been able to get this to work. I will try your code tonight.
I am cautiously optimistic. I don't care about RPMs in my application, and it seems that the stuff you added is all to do with Velocity capture and RPM calculation. Anyway, maybe it needs it, IDK. I just want to interrupt when the encoder moves, so that I can count on a quick reaction. My MAIN loop is too long.
I did notice that you are assigning a value to QEITIME = 2000000, and the NXP manual for the chip (page 549) says that QEITIME is read only.
Regards,
dan
Re: QEI Interrupt Trouble
Posted: Thu Feb 14, 2013 1:41 pm
by YahooArchive
A while back I posted and got good advice about how to use the QEI hardware. I
am only using it to count encoder steps and it works well.
BUT, I have added so much to my program that polling the encoder is no longer
effective because my main loop is about 250mS. Now I want to have the encoder
movements handled by an interrupt routine, but I am not much luck. I keep
getting a "FaultISR 0xFFFFFFF1 SCB->CFSR=0x00020000" error when the event
occurs.
Does anyone know what this means or what I am doing wrong?
Below is my code.
'QEI Interrupt Test Program 12/6/12 by Dan Garofolo
'
#include "LPC17xx.bas"
INTERRUPT SUB QUADISR
PRINT "It works"
QEICLR = &H1FFF 'Clear pending interrupts
ENDSUB
SUB INIT
SCB_PCONP = SCB_PCONP or (1<<18) 'enable QEI bit in PCONP
PCB_PINSEL3 = PCB_PINSEL3 or (1<<8)'Set pin for PH A
PCB_PINSEL3 = PCB_PINSEL3 or (1<<14)'Set pin for PH B
QEIMAXPOS = 6 'Set max position
QEICON = QEICON or 1 'clear position
QUAD_ISR = ADDRESSOF QUADISR + 1 'Set Vector to the ISR
QEICLR = &H1FFF 'Clear pending interrupts
QEIIES = 1<<5 'Enable bit 5 (Encoder Clock)
VICIntEnable0 = 1<<31 'Enable QEI bit in NVIC
ENDSUB
MAIN:
INIT
MAINLOOP:
PRINT "main routine"
WAIT(1000)
GOTO MAINLOOP
END
Re: QEI Interrupt Trouble
Posted: Thu Feb 14, 2013 1:42 pm
by YahooArchive
>I keep getting a "FaultISR 0xFFFFFFF1 SCB->CFSR=0x00020000" error when the
event occurs.
PRINT is not re-entrant so you really should not use it inside an interrupt
other than maybe to check to see that the interrupt occurs once. Once you see
that the interrupt actually happened, then remove it.
A better thing to do in an interrupt is to wiggle a pin, if you need
confirmation that it occurs.
Re: QEI Interrupt Trouble
Posted: Thu Feb 14, 2013 1:46 pm
by YahooArchive
Dan, I posted below your quadrature example with one that I made work. I
had been getting the fault messages as well.
On start up the line that defines what sub to call when an interrupt
happens. For the Quadrature it is this line.
QUAD_ISR = ADDRESSOF QUADISR + 1
And that will tell the compiler to call the Interrupt sub below:
INTERRUPT SUB QUADISR
CurrCount=QEICAP
Dim NewRPM as Single
NewRPM = (25000000 * CurrCount * 60)/(QEILOAD * 256 * 2)
RPM=(RPM+NewRPM)/2
RPMUpdated=Timer
QEICLR = &H1FFF 'Clear pending interrupts
ENDSUB
In my experience the Interrupts Sub needs to be written out above the
line that calls it.
If the compiler ran into the line with the QUAD_ISR = ADDRESSOF QUADISR
+ 1 , before it has run into the INTERRUPT SUB QUADISR itself, it would
fail.
Darin