![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
Ttelmah
Joined: 11 Mar 2010 Posts: 19369
|
|
Posted: Wed Jan 19, 2011 3:38 am |
|
|
Do you need to use any other interrupts?.
If not, then you need to consider going the 'int_global' route:
Code: |
signed int32 position;
int save_w;
#locate save_w=0x7f
int save_status;
#locate save_status=0x20
#byte status = 3
//This is the decoder for a change in the quadrature inputs. Called on
//port B change interrupt, with encoder connected to B4, and B5.
void quad(void) {
static int old;
static int new;
static int value;
//Here I have an edge on one of the quadrature inputs
new=portb;
//Now I have to decode the quadrature changes. There are four possibilities:
//I can have a rising or falling edge, on each of the two inputs. I have to
//look at the state of the other bit, and increment/decrement according to
//this.
value=new^old;
//'value', now has the bit set, which has changed
if (value & 0x10) {
//Here the low bit has changed
if (new & 0x10) {
//Here a rising edge on A
if (new & 0x20) --position;
else ++position;
}
else {
//Here a falling edge on A
if (new & 0x20) ++position;
else --position;
}
}
else {
//Here the high bit (B) must have changed
if (new & 0x20) {
//Here a rising edge on B
if (new & 0x10) ++position;
else --position;
}
else {
//Here a falling edge on B
if (new & 0x10) --position;
else ++position;
}
}
old=new;
bchanged=0;
}
#INT_GLOBAL
void isr() {
#asm
//store current state of processor
MOVWF save_w
SWAPF status,W
BCF status,5
BCF status,6
MOVWF save_status
#ASM
//Here for maximum speed, I test the RB interrupt - since it is always
//enabled, I don't have to test the enable bit
BTFSS INTCON,RBIF
GOTO FEXIT //Add other handlers here if needed
#endasm
quad(); //Quadrature handler.
#asm
BCF RBIF
FEXIT:
// restore processor and return from interrupt
SWAPF save_status,W
MOVWF status
SWAPF save_w,F
SWAPF save_w,W
#endasm
}
|
Will need the register defines for PORTB, RBIF etc., added.
Not an exact match for your code, but close (position, rather than counter etc..).
The decoder, is slightly more efficient than your code, but the key saving, is that it only saves the bare minimum registers needed. Should double the response speed with care.
You may find that adding pull up resistors helps a little. The internal pullups are quite low powered, and as pulse rates rise, you may find these are not good enough to give fast edges. Worth studying the waveform.
Best Wishes |
|
![](templates/subSilver/images/spacer.gif) |
asdf85
Joined: 03 Jan 2011 Posts: 34
|
|
Posted: Wed Jan 19, 2011 3:56 am |
|
|
actually, the 1st code does check for all 4 steps. Im shifting the bits on each state change and checking to see if it matches the intended waveform pattern(doing this with pata and patb variables).
Initially i could only find a 4mhz crystal lying around. but i just ran out and got my self a 20mhz crystal.
With the 20mhz crystal, the 2nd code works. but the first still does not.
However, as you pointed out, the 2nd code just checks one of the 4 steps, so im afraid the results may be innacurate. Because I noticed when using the 4mhz crystal, it started decreasing(its shud be increasing) the count once i rotated it at a faster speed.
Ttelmah, i need to use RDA and timer interrupts too. |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19369
|
|
Posted: Wed Jan 19, 2011 4:07 am |
|
|
You _will_ have problems then.
You can add handlers for other interrupts, but what happens, if you have just started handling one of these, and a RB edge arrives?. The code has to do all the operations associated with the second interrupt, restore the registers this needs, then be called a second time for the RB interrupt. Ouch....
Choices:
Go for a faster CPU clock
Add an external change detector, and feed the CCP channels off this.
Add a full external quadrature counter.
Switch to a 18 PIC, and make the RB interrupt 'high priority'.
Best Wishes |
|
![](templates/subSilver/images/spacer.gif) |
bkamen
Joined: 07 Jan 2004 Posts: 1611 Location: Central Illinois, USA
|
|
Posted: Wed Jan 19, 2011 9:43 am |
|
|
Ttelmah wrote: |
Choices:
Go for a faster CPU clock
Add an external change detector, and feed the CCP channels off this.
Add a full external quadrature counter.
Switch to a 18 PIC, and make the RB interrupt 'high priority'.
|
Or use a PIC with a Quadrature decoder like the 18Fxx31.
http://ww1.microchip.com/downloads/en/DeviceDoc/39616d.pdf
-Ben _________________ Dazed and confused? I don't think so. Just "plain lost" will do. :D |
|
![](templates/subSilver/images/spacer.gif) |
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Wed Jan 19, 2011 10:02 am |
|
|
Quote: | i need to use RDA and timer interrupts too |
This changes everything.
Quote: | the 1st code does check for all 4 steps. |
I don't see, how. It checks for a signal pattern, that occurs only once per 4 steps (hopefully).
The code presented by Ttelmah does a state-of-the-art quadrature encoding. It can be possibly speeded up by using a state table. |
|
![](templates/subSilver/images/spacer.gif) |
scottc
Joined: 16 Aug 2010 Posts: 95
|
|
Posted: Wed Jan 19, 2011 10:22 am |
|
|
Is the encoder one of the Mechanical types that has 3 pins
gnd, A - B
Thanks Scott |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19369
|
|
Posted: Wed Jan 19, 2011 11:23 am |
|
|
FvM wrote: | Quote: | i need to use RDA and timer interrupts too |
This changes everything.
Quote: | the 1st code does check for all 4 steps. |
I don't see, how. It checks for a signal pattern, that occurs only once per 4 steps (hopefully).
The code presented by Ttelmah does a state-of-the-art quadrature encoding. It can be possibly speeded up by using a state table. |
A state table, works out slower. I tried it...
If you run through the possible 'routes', it only takes a handful of instructions to go through each possibility. With the table, the total timing is about 'neck and neck', _but_ you then have to also save the registers used to access the table, which makes it worse (in the given example, with minimum register saves).
I have to say though, that assuming the code outside, is looping quickly doing whatever it does, one has to remember, that you don't need an interrupt handler to service serial (just ensure you are polling the receive interrupt at least as frequently as a character time), and the same applies to timer interrupts.
If you only need to do some very small operation with the timer, then add a test for this interrupt flag in the global code, and do this operation. However otherwise, just poll the interrupt flag in the main code. You are using interrupt flags, but not interrupt handlers. Then the only interrupt using the hardware handlers becomes the quadrature system, and you can get the required speed.
I just compiled my code (a few bugs), but with these fixed, it takes a total of 36 instruction times 'worst case' to handle any quadrature state (including the interrupt call/return). Potentially means this can handle 30000 edges per second.
Best Wishes |
|
![](templates/subSilver/images/spacer.gif) |
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Thu Jan 20, 2011 6:05 am |
|
|
Quote: | A state table, works out slower. I tried it... | Yes, I believe. It's however faster on a 8051, that has a fast MOVC ROM lookup instruction.
Quote: | Potentially means this can handle 30000 edges per second. | Good! |
|
![](templates/subSilver/images/spacer.gif) |
asdf85
Joined: 03 Jan 2011 Posts: 34
|
|
Posted: Thu Jan 20, 2011 6:55 pm |
|
|
Sorry, I'm actually not from an electronics background. What exactly is handlers for interrupts?
scott, the encoder has 6 pins, its Koyo TRD-J 1000 RZW. |
|
![](templates/subSilver/images/spacer.gif) |
gpsmikey
Joined: 16 Nov 2010 Posts: 588 Location: Kirkland, WA
|
|
Posted: Thu Jan 20, 2011 7:00 pm |
|
|
Interrupt Handler = ISR = Interrupt Service Routine -- the code that gets control any time an interrupt goes off. If you are using interrupts, you MUST have a handler to take control when that interrupt goes off or it will wander off into never never land.
mikey _________________ mikey
-- you can't have too many gadgets or too much disk space !
old engineering saying: 1+1 = 3 for sufficiently large values of 1 or small values of 3 |
|
![](templates/subSilver/images/spacer.gif) |
asdf85
Joined: 03 Jan 2011 Posts: 34
|
|
Posted: Thu Jan 20, 2011 11:29 pm |
|
|
oh okay, its the same thing as isr |
|
![](templates/subSilver/images/spacer.gif) |
asdf85
Joined: 03 Jan 2011 Posts: 34
|
|
Posted: Fri Jan 21, 2011 3:00 am |
|
|
May i also know if its OKAY to be enabling and disabling interrupts in an interrupt service routine? Thanks |
|
![](templates/subSilver/images/spacer.gif) |
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Fri Jan 21, 2011 4:09 am |
|
|
Unless working with priority, all interrupts are disabled during ISR execution automatically. In some applications, individual IE bits are manipulated in ISR, e.g. a TX send interrupt will be disbled, when the last circular buffer character has been sent out. In your application, I don't see a purpose for it. Encoder interrupts must be expected at any time, there's no reason to delay other interrupts. |
|
![](templates/subSilver/images/spacer.gif) |
mbradley
Joined: 11 Jul 2009 Posts: 118 Location: California, USA
|
|
![](templates/subSilver/images/spacer.gif) |
sseidman
Joined: 14 Mar 2005 Posts: 159
|
|
Posted: Mon Feb 14, 2011 9:15 am |
|
|
Ditto for going with one of the motor control 18Fxx31. It will make your life easier |
|
![](templates/subSilver/images/spacer.gif) |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|