CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

PIC18F2550 interrupt at 19kHZ

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
elyon



Joined: 21 Mar 2017
Posts: 9
Location: Italy

View user's profile Send private message Send e-mail

PIC18F2550 interrupt at 19kHZ
PostPosted: Tue Nov 21, 2017 11:01 am     Reply with quote

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
Code:

256*0.5=128 us

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? Crying or Very sad

I have 5.070 compiler version

Thanks
_________________
Think. Believe. Dream. Dare
- W. E. Disney -
Ttelmah



Joined: 11 Mar 2010
Posts: 19510

View user's profile Send private message

PostPosted: Tue Nov 21, 2017 12:14 pm     Reply with quote

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

View user's profile Send private message Send e-mail

PostPosted: Wed Nov 22, 2017 9:22 am     Reply with quote

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: 19510

View user's profile Send private message

PostPosted: Wed Nov 22, 2017 10:29 am     Reply with quote

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

View user's profile Send private message Send e-mail

PostPosted: Wed Nov 22, 2017 10:58 am     Reply with quote

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: 19510

View user's profile Send private message

PostPosted: Wed Nov 22, 2017 12:27 pm     Reply with quote

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

View user's profile Send private message Send e-mail

PostPosted: Tue Dec 05, 2017 4:09 am     Reply with quote

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 -
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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