|
|
View previous topic :: View next topic |
Author |
Message |
elyon
Joined: 21 Mar 2017 Posts: 9 Location: Italy
|
PIC18F2550 interrupt at 19kHZ |
Posted: Tue Nov 21, 2017 11:01 am |
|
|
Hello mates!
I need to write an interrupt so that the pic could toggle a pin with a frequency of 19kHz using the internal pic18f2550 oscillator.
this is the main.h file
Code: | #include <18F2550.h>
#device ADC=10
#fuses INTRC_IO,NOWDT,NOPROTECT,NOLVP,NODEBUG,VREGEN,PUT
#use delay(internal=8M)
|
this is the main.c
Code: |
#include <main.h>
#INT_TIMER0
void TIMER0_isr(void)
{
output_toggle(PIN_B7);
set_timer0(0x97);
}
void main()
{
setup_timer_0(T0_INTERNAL|T0_8_BIT);
set_timer0(0x97);
enable_interrupts(INT_TIMER0);
enable_interrupts(GLOBAL);
while(TRUE)
{
//TODO: User Code
}
} |
these are my considerations:
With a 8MHz clock frequency, the instruction cycle is
Code: |
1/(Fosc/4) = 1/2 = 0.5 us
|
So, TIMER0 Overflow will be after
but to have a frequency of 19kHz it means that the time will be 52.5 us (that's right?)
So I preload
Code: |
T0 Overflow = instruction cycle * (256-preload) => 52.5=0.5*(256-x) => x=151=0x97
|
using set_timer0(0x97) inside and outside the interrupt routine.
But when I connect my oscilloscope to the pin, it measures 500 Hz and 2 ms (more or less).
Why?
What's wrong?
I have 5.070 compiler version
Thanks _________________ Think. Believe. Dream. Dare
- W. E. Disney - |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19511
|
|
Posted: Tue Nov 21, 2017 12:14 pm |
|
|
Honestly forget it. Use a PWM.
Big problem is you are running just 2MIPS. Now entering and exiting an interrupt takes typically about 60 instructions. Add the code to load the register and do the toggle, and you have perhaps another 10 instructions, so you have 'negative equity' on time. A signal at 19KHz, requires the edge to change at 38000 times per second, so just 52 to 53 instructions between edges.
You can't handle interrupt events at this sort of frequency.
You can do it by polling the interrupt flag, but you might as well just use a software delay.
Code: |
while(TRUE)
{
delay_us(25);
output_toggle(PIN_B7);
}
|
Would give you close to 19KHz.
There is a separate problem, in that your timer will be using a prescaler. T0_DIV_1 would turn this off. |
|
|
elyon
Joined: 21 Mar 2017 Posts: 9 Location: Italy
|
|
Posted: Wed Nov 22, 2017 9:22 am |
|
|
Ttelmah wrote: | Honestly forget it. Use a PWM.
Big problem is you are running just 2MIPS. Now entering and exiting an interrupt takes typically about 60 instructions. Add the code to load the register and do the toggle, and you have perhaps another 10 instructions, so you have 'negative equity' on time. A signal at 19KHz, requires the edge to change at 38000 times per second, so just 52 to 53 instructions between edges.
You can't handle interrupt events at this sort of frequency.
You can do it by polling the interrupt flag, but you might as well just use a software delay.
Code: |
while(TRUE)
{
delay_us(25);
output_toggle(PIN_B7);
}
|
Would give you close to 19KHz.
|
Thanks Ttelmah for your help.
I need to do this necessarily with an interrupt for my project, if it's possible.
So, do you think that with an external oscillator (i. e. 20MHz) I would to toggle the pin at 19kHZ?
Maybe, with it, I could bypass the problem.
Ttelmah wrote: | There is a separate problem, in that your timer will be using a prescaler. T0_DIV_1 would turn this off. |
I thought that not write "T0_DIV_n" in the code it was like write T0_DIV_1. Was I wrong? _________________ Think. Believe. Dream. Dare
- W. E. Disney - |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19511
|
|
Posted: Wed Nov 22, 2017 10:29 am |
|
|
You were wrong on the divider. On many of the setups the default is 1, but on this one it's not. If you look at the bit patterns versus dividers the /1, is not the 'end' pattern in either direction. Can't remember what is but I think it was /2.
First, do you mean Hz?. As already said, a 19KHz signal needs edges at 38000 times per second... If you want to trigger an interrupt 19000 times per second, then you really do need to be clocking the processor faster. The PIC is a very poor processor for fast interrupt responses. Remember you can trigger an interrupt from Timer2, at an exact division (without needing to reload the timer).
Do you 'have' to use the 2550?. The only 'plus' of this chip is the USB, and you can't use this with the internal oscillator.... A chip like the PIC18F26K20, can clock to 64MHz on the internal oscillator. With this running at 64Mhz, and timer2 setup as:
SETUP_TIMER_2(T2_DIV_BY_4,209,1);
You will get 19000 interrupts per second, and have some time to do things at this rate!... |
|
|
elyon
Joined: 21 Mar 2017 Posts: 9 Location: Italy
|
|
Posted: Wed Nov 22, 2017 10:58 am |
|
|
Ttelmah wrote: | You were wrong on the divider. On many of the setups the default is 1, but on this one it's not. If you look at the bit patterns versus dividers the /1, is not the 'end' pattern in either direction. Can't remember what is but I think it was /2. |
oh I see. Thanks.
Ttelmah wrote: |
First, do you mean Hz? |
I can use an external Quartz oscillator of 20MHz to try to obtain a frequency of 19kHz.
Ttelmah wrote: | Do you 'have' to use the 2550? |
Unfortunately yes :( _________________ Think. Believe. Dream. Dare
- W. E. Disney - |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19511
|
|
Posted: Wed Nov 22, 2017 12:27 pm |
|
|
If you have to use the 2550, then if you add a crystal oscillator, running at a multiple of 4MHz (8MHz, 12MHz etc..), then you can raise your operating frequency to 48MHz. With this you can program Timer2 to interrupt at just off 19KHz (with PR2 set to 157 -> 18987.3Hz).
You'd then have 632 instructions between interrupts. |
|
|
elyon
Joined: 21 Mar 2017 Posts: 9 Location: Italy
|
|
Posted: Tue Dec 05, 2017 4:09 am |
|
|
hi Ttelmah.
Sorry for my late answer.
Thank you very much! With your advice I have obtained the oscillation frequency I need :-) _________________ Think. Believe. Dream. Dare
- W. E. Disney - |
|
|
|
|
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
|