|
|
View previous topic :: View next topic |
Author |
Message |
simoes
Joined: 10 Jun 2009 Posts: 7 Location: Cuernavaca, México
|
Velocity problem |
Posted: Wed Jun 17, 2009 1:41 pm |
|
|
Hi.
I wrote some days ago this post:
http://www.ccsinfo.com/forum/viewtopic.php?t=39199
I had have some problems in setting the maximum velocity of my microcontroller (PIC18F2620).
Now, I know that it's working at maximum velocity (32Mhz).
I want to read data from a encoder with 1000 ticks per revolution that is connected to a motor with maximum speed of 6000 rpms.
I tried several ways and nothing.
The microcontroller don't seems to have time to answer to all interruptions.
At maximum speed, I need to attend 400.000 interruptions per second.
The last code that I have created, I only change the state of a output if an interrupt occurs.
If i see the microcontroller output in a oscilloscope I can see that the microcontroller don't have time to change the state of the output.
This microcontroller is working at 32Mhz, shouldn't it be speed enough??
This is the interrupt routine code:
Code: |
#int_EXT
void EXT_isr(void)
{
if (input_state(PIN_B0))
{
ext_int_edge(0,H_TO_L);
output_high(PIN_B1);
// we have falling edge on B0
}
else
{
ext_int_edge(0,L_TO_H);
output_low(PIN_B1);
}
}
|
Assembly:
Code: |
.................... #include "external_interrupt.h"
.................... //int0
....................
00338: BCF F9E.5
0033A: GOTO 0074
.................... #int_EXT
.................... void EXT_isr(void)
.................... {
.................... if (input_state(PIN_B0))
0033E: BTFSS F81.0
00340: BRA 0348
.................... {
.................... ext_int_edge(0,H_TO_L);
00342: BCF FF1.6
.................... output_high(PIN_B1);
00344: BSF F8A.1
.................... // we have falling edge on B0
.................... }
.................... else
00346: BRA 034C
.................... {
.................... ext_int_edge(0,L_TO_H);
00348: BSF FF1.6
.................... output_low(PIN_B1);
0034A: BCF F8A.1
.................... }
.................... }
|
I used other microcontroller (PIC18F4550) and the same result. A little bit better but isn't enough.
I don't know what is the problem.
If the microcontroller is running at 32Mhz it only need (1/32M)seconds for execute a instruction.
This piece of code only have nine instructions that are not always executed.
In the worst case we have the "else" statement and it take seven instructions.
If it take 10 system clocks to execute this code we will have (10/32M)=312.5e-9 seconds for an interrupt.
Now, the maximum number of interrupts will be 1/312.5e-9= 3.2M
I not sure that this microcontroller have a RISC architecture, but the numbers speak for itself. If it have a RISC architecture I can expect 32MIPS.
I need to execute code for 400e3 interruptions, and theoretically I can execute 3.2e6 interruptions per second.
What am I doing wrong? _________________ Faculdade de Engenharia da Universidade do Porto.
Instituto Tecnológico y de Estudios Superiores de Monterrey.
Visita-me em: asimoes.myweblive.net |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Jun 17, 2009 1:56 pm |
|
|
Quote: | PIC18F2620.
Now, I know that it's working at maximum velocity (32Mhz).
If it have a RISC architecture I can expect 32MIPS. |
No. The instruction clock runs at 1/4 of the main oscillator frequency.
You will get 8 MIPs.
See the diagrams on page 57 of the 18F2620 data sheet. (Page 59
in the Acrobat reader):
http://ww1.microchip.com/downloads/en/DeviceDoc/39626e.pdf |
|
|
simoes
Joined: 10 Jun 2009 Posts: 7 Location: Cuernavaca, México
|
|
Posted: Wed Jun 17, 2009 2:13 pm |
|
|
You are right. The last micro thas i use are a dsPic. . . A little diferent.
Now, with a 8MIPS system, if i want to execute 400.000 interruptions per second, i have (8M/400.000)=20 instructions free.
Should be enough for execute my code. . .
The microcontroller isn't doing nothing more.
I had also created a little program in MPLab and is the same thing. _________________ Faculdade de Engenharia da Universidade do Porto.
Instituto Tecnológico y de Estudios Superiores de Monterrey.
Visita-me em: asimoes.myweblive.net |
|
|
Guest
|
|
Posted: Wed Jun 17, 2009 2:35 pm |
|
|
Just a suggestion.
Why not use a 8bit counter and make a preload as (0x100-0x0A) then your int is only served every 10 count from the encoder. |
|
|
simoes
Joined: 10 Jun 2009 Posts: 7 Location: Cuernavaca, México
|
|
Posted: Wed Jun 17, 2009 2:54 pm |
|
|
Yes, i had think in that.
I suppose that is the only way. . . or change the encoder for one with less ticks.
With the counter it's possible to lose some ticks. _________________ Faculdade de Engenharia da Universidade do Porto.
Instituto Tecnológico y de Estudios Superiores de Monterrey.
Visita-me em: asimoes.myweblive.net |
|
|
Ttelmah Guest
|
|
Posted: Wed Jun 17, 2009 3:16 pm |
|
|
Key thing to understand, is that if you use the 'INT_EXT' declaration, the compiler adds a very significant overhead to your code. Typically about 60 instructions are used, saving the registers, checking which interrupt triggered, calling the handler, clearing the interrupt, and restoring the registers. This occurs _before_ the actual interrupt code....
A while ago, I posted quadrature decoder code, showing how to work round this, with INT_RB. For your simpler needs, something like:
Code: |
#int_global
void myint(void) {
if (input_state(PIN_B0))
{
ext_int_edge(0,H_TO_L);
output_high(PIN_B1);
// we have falling edge on B0
}
else
{
ext_int_edge(0,L_TO_H);
output_low(PIN_B1);
}
clear_interrupt(INT_EXT);
#asm
RETFIE 1
nop
#endasm
}
|
This assumes no other interrupt is enabled, and replaces the main interrupt handler. I see you are already using fast_io. The extra 'nop' at the end, assures this will work on chips that have a hardware bug, where a nop is needed after the RETFIE instruction. The compiler, on 'modern' versions, ought already to be using the RETFIE 1, but I make 'sure', by hard coding it.
This should bring your operation up to the sort of speed you expect/need.
Best Wishes |
|
|
bsturm
Joined: 23 Feb 2009 Posts: 29
|
|
Posted: Thu Jun 18, 2009 11:43 am |
|
|
You are wise to dedicate a PIC to this function. Have you tried a busy loop instead of an interrupt. A tight loop that tests the status of an input might be faster and simpler than an interrupt driven program. |
|
|
simoes
Joined: 10 Jun 2009 Posts: 7 Location: Cuernavaca, México
|
|
Posted: Fri Jun 19, 2009 10:53 am |
|
|
Ttelmah you are right.
In fact, i tried a version of your code and it work nice.
Now the problem is that i have interrupts of rs-232, i2c and possible of a timer.
I hope that this microcontroller can handle it.
Thank you for your help. _________________ Faculdade de Engenharia da Universidade do Porto.
Instituto Tecnológico y de Estudios Superiores de Monterrey.
Visita-me em: asimoes.myweblive.net |
|
|
|
|
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
|