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

PIC12F629_Timer 0 issue

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



Joined: 07 May 2010
Posts: 4
Location: New Jersey

View user's profile Send private message Visit poster's website MSN Messenger

PIC12F629_Timer 0 issue
PostPosted: Fri May 07, 2010 10:38 am     Reply with quote

Hi guys

I'm pretty much new with micro controllers.
I'm trying to implement a TIMER0 with 33us, which is going to be 30.3Khz and toggle pin A4.
When I see the Stopwatch in MPLAB and I define a breakpoint inside the interruption I see 68us.

This is my code so far.
Could anybody help me with?
Code:

#include <12F629.h>
#fuses INTRC_IO,NOWDT,NOPROTECT,NOMCLR
#use delay(clock=4M) // fosc/4 --> 4MHz/4 = 1000000Hz =>1us

#define      TMR0_COUNT      224
/////////////////////////////////    DEFINES  A PORT   //////////////////////////////////////
#define      PGD               PIN_A0  //  output
#define      LED                    PIN_A1  //  output
#define      RECEIVER             PIN_A2   //  input
#define      MODE                PIN_A3   //  input
#define      TRANSMITTER            PIN_A4   //  output
#define      RELAY               PIN_A5   //   output

/////////////////////////////////    FUNCTION DECLARATIONS     //////////////////////////////
void Initialize(void);
void Sensor_Check(void);
void Timer1(void);
void Timer2(void);
void Timer3(void);

/////////////////////////////////    GLOBAL VARIABLES DECLARATION     ///////////////////////
BYTE alarm_flag=0;
BYTE time=0;

/////////////////////////////////  MAIN FUNCTION ///////////////////////////////////////////
void main()
{

   Initialize();
//   RESTART_WDT();         // kick the dog

   while(1)
   {
      Sensor_check();
   }
}
/////////////////////////////////  SENSOR CHECK  ///////////////////////////////////////////               
void Sensor_check()
{
   if(input(RECEIVER)== FALSE)
   {
      output_high(RELAY);
   }
   else
   {
      output_low(RELAY);
   }
}
/////////////////////////////////  INITIALIZE  /////////////////////////////////////////////
void Initialize()
{
   #use FAST_IO(A)
   SET_TRIS_A( 0b00001100 ); // 1 = input // 0 = output
//   PGD                  PIN_A0     //  output
//   LED                    PIN_A1     //  output
//   RECEIVER                     PIN_A2   //  input
//   MODE                    PIN_A3   //  input
//   TRANSMITTER            PIN_A4   //  output
//   RELAY               PIN_A5   //   output

   PORT_A_PULLUPS(TRUE);   //   turn pull up on SET BUTTOM
                        
   SETUP_TIMER_0(RTCC_INTERNAL);
   SETUP_TIMER_0(RTCC_DIV_2);
      SET_TIMER0(TMR0_COUNT);   
   SETUP_COMPARATOR(FALSE);
        SETUP_VREF(FALSE);

      ENABLE_INTERRUPTS(INT_TIMER0);
        ENABLE_INTERRUPTS(GLOBAL);
    
/////////////////////// initialize ports ////////////////////////////
   output_A(0x00);            // turn off all outputs PORT A   
}

/////////////////////////////////    INTERRUPT BY TIMER 0    //////////////////////////////////////////

#INT_TIMER0                        // interrupt each 33us
void timer0interrupt()
{
   SET_TIMER0(TMR0_COUNT);            // preset timer 33us
/////////////////////TRANSMITTER TOGGLE 30KHz/////////////////////////////////////
   output_toggle(TRANSMITTER);    // Set LED to oscilate in 30 Khz.
}
Ttelmah



Joined: 11 Mar 2010
Posts: 19553

View user's profile Send private message

PostPosted: Fri May 07, 2010 12:09 pm     Reply with quote

Do a search here for 'interrupt overhead' (look for both words). You will find what is going on....

Best Wishes
lfnickel



Joined: 07 May 2010
Posts: 4
Location: New Jersey

View user's profile Send private message Visit poster's website MSN Messenger

PostPosted: Fri May 07, 2010 12:35 pm     Reply with quote

No luck so Far.

I tried many things and it didn't work.
I'm using internal oscillator.

Let's go from begging.
Should ? use 20Mhz or 4MHz here

#use delay(clock=4M)

?

Thanks.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri May 07, 2010 12:46 pm     Reply with quote

This thread explains the interrupt overhead issue:
http://www.ccsinfo.com/forum/viewtopic.php?t=42222


The internal oscillator on the 12F629 only supports 4 MHz operation.
The data sheet says:
Quote:

9.2.5 INTERNAL 4 MHZ OSCILLATOR

When calibrated, the internal oscillator provides
a fixed 4 MHz (nominal) system clock.


Yes, if you use a 20 MHz crystal, the PIC will run 5x faster, and this
will reduce the interrupt overhead time by a factor of 5.
lfnickel



Joined: 07 May 2010
Posts: 4
Location: New Jersey

View user's profile Send private message Visit poster's website MSN Messenger

PostPosted: Fri May 07, 2010 1:36 pm     Reply with quote

I understood the overhead problem that I'm having now, and i know that i could use the preescale and divide, but then my frequency will lower.

I didn't want to use external parts for OSC.

How could i handle that in the code?

Thanks.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri May 07, 2010 1:45 pm     Reply with quote

You could reduce the interrupt overhead by using #int_global.
See Ttelmah's example at the end of this thread:
http://www.ccsinfo.com/forum/viewtopic.php?t=39309
Ttelmah



Joined: 11 Mar 2010
Posts: 19553

View user's profile Send private message

PostPosted: Fri May 07, 2010 2:38 pm     Reply with quote

Except on the 12F629 being used here, there is no RETFIE 1, so the useage would instead have to be based on something like EX_GLINT.C.
Seriously, even with this, you will have problems.

An interrupt is responded to at the start of the 'next' instruction after it happens. So 1 or 2 instruction times delay. Then the code to save and restore the minimum registers will take about 10 instruction times, the return, a couple more, the toggling of the pin at least a couple more (more unless fast_io is used), and then clearing the interrupt another instruction time. So the processor is going to be spending over 50% of it's time just generating the pulse, at the very 'best'... :(

It is much simpler, to not actually use the interrupts. Multiple solutions:
1) Simply toggle pin, wait.
2) Use the interrupt flag, but not the interrupt. When the flag goes true, toggle the pin, clear the flag. Total time less than half a dozen instructions...
3) For speeds like this, the 'real' solution, is to change chips, and use a PWM, which generates the pulse for you...

Best Wishes
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri May 07, 2010 2:52 pm     Reply with quote

The 12F683 is an 8-pin 12F-series PIC that has hardware PWM.
lfnickel



Joined: 07 May 2010
Posts: 4
Location: New Jersey

View user's profile Send private message Visit poster's website MSN Messenger

PostPosted: Fri May 07, 2010 2:54 pm     Reply with quote

Hi Ttelmah,

I used your function as INT_GLOBAL, but even with that after certain time the micro gets lost and now i understand better why.

Yes I'm going to use toggle pin for this case. Faster and less time consuming.

Thanks. I learned a lot!

I'll keep going and i keep posting my doubts.

Regards.
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