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

12f683 Timer2 problem

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



Joined: 25 May 2014
Posts: 1

View user's profile Send private message

12f683 Timer2 problem
PostPosted: Sun May 25, 2014 11:08 pm     Reply with quote

The code is not working. If the timer2 is not used in the code then the code works. Can anybody help me?
Code:

#include <12F683.h>

#FUSES INTRC_IO                 //Internal RC Osc, no CLKOUT
#FUSES NOMCLR                   //Master Clear pin used for I/O
#FUSES NOWDT                    //No Watch Dog Timer
#FUSES NOCPD                    //No EE protection
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NOPUT                    //No Power Up Timer
#FUSES NOBROWNOUT               //No brownout reset

#use delay(clock=4000000)

#use fast_io(a)                           
#zero_ram

#int_RTCC
void  RTCC_isr(void)
{
set_timer0(156);
}

#int_TIMER1
void  TIMER1_isr(void)
{
set_timer1(156);
output_toggle(pin_a0);
}

#int_TIMER2
void  TIMER2_isr(void)
{
set_timer2(0);
}

#int_RA
void  RA3_isr(void)
{
output_toggle(pin_a0);
}



void main()
{
delay_ms(1); 
   setup_adc_ports(NO_ANALOGS|VSS_VDD);
   setup_adc(ADC_OFF);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);
   setup_timer_2(T2_DIV_BY_16,0,1);
   setup_comparator(NC_NC);
   setup_vref(FALSE);
   enable_interrupts(INT_RTCC);
   enable_interrupts(INT_TIMER1);
   enable_interrupts(INT_TIMER2);
   enable_interrupts(INT_RA3);
   enable_interrupts(GLOBAL);
   setup_oscillator(OSC_4MHZ);
   
   set_tris_a(0b0011000);

   While(true)
        {
        output_high(pin_a1);
        }

}

If the timer2 option is removed as below then the code works.
Code:

#include <12F683.h>

#FUSES INTRC_IO                 //Internal RC Osc, no CLKOUT
#FUSES NOMCLR                   //Master Clear pin used for I/O
#FUSES NOWDT                    //No Watch Dog Timer
#FUSES NOCPD                    //No EE protection
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NOPUT                    //No Power Up Timer
#FUSES NOBROWNOUT               //No brownout reset

#use delay(clock=4000000)

#use fast_io(a)                           
#zero_ram

#int_RTCC
void  RTCC_isr(void)
{
set_timer0(156);
}

#int_TIMER1
void  TIMER1_isr(void)
{
set_timer1(156);
output_toggle(pin_a0);
}
/*
#int_TIMER2
void  TIMER2_isr(void)
{
set_timer2(0);
}
*/
#int_RA
void  RA3_isr(void)
{
output_toggle(pin_a0);
}



void main()
{
delay_ms(1); 
   setup_adc_ports(NO_ANALOGS|VSS_VDD);
   setup_adc(ADC_OFF);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);
   //setup_timer_2(T2_DIV_BY_16,0,1);
   setup_comparator(NC_NC);
   setup_vref(FALSE);
   enable_interrupts(INT_RTCC);
   enable_interrupts(INT_TIMER1);
  // enable_interrupts(INT_TIMER2);
   enable_interrupts(INT_RA3);
   enable_interrupts(GLOBAL);
   setup_oscillator(OSC_4MHZ);
   
   set_tris_a(0b0011000);

   While(true)
        {
        output_high(pin_a1);
        }

}

Please help me if you can.
Ttelmah



Joined: 11 Mar 2010
Posts: 19513

View user's profile Send private message

PostPosted: Mon May 26, 2014 1:14 am     Reply with quote

Time.....

Now on Timer2, it automatically resets to 0, when it reaches it's count, so the set to zero is just a waste of processor cycles....

You have timer0 running as an 8 bit timer, and counting effectively instructions (/1 divider). It takes about 28 instruction times to actually get into the interrupt handler (the interrupt bits have all to be polled to find which one has triggered, and the registers have to be saved). Then you have it toggling a pin (2 instructions), it then clears the interrupt (2 more), then exits (2 instruction times), then restores the registers and returns (another 20 instruction times). So when the first interrupt returns to the code, the chip has already counted from 156 to 182. So the interrupt will actually trigger about 28 instructions 'slower' than you expect (since the count has already reached about 28 when it gets to the point where you set the timer value), and is already using over half the total available clock cycles of the processor.....
The interrupt does nothing except waste time!. You are not doing anything in the handler, so why call it?.

Then you add another interrupt. This takes yet more time, and will result in the first timer becoming a little erratic whenever the second handler is called. However with a 16bit timer this is not too often. That actually toggles a pin.

Then you add a third. Does nothing much, except use more processor time. 8 bit timer /16, so every 4096 instructions nominally.

Then you have the fourth interrupt, responding to an incoming signal on RA3. This will actually hang the chip, since you don't read the pin in the interrupt. Read the data sheet, or search here.

Now interrupts are 'polled' in the order they are declared. When an interrupt triggers, the chip saved the registers, then tests each enabled interrupt in turn to see which one has triggered, and calls it's handler. Interrupts lower down the list will therefore run slower and slower as more interrupts are active above them in the list. Your code is spending most of it's time looping in the handlers. In fact the INT_RA interrupt will be permanently triggering (since you are never reading the input, so it'll never clear), but the code handles the timer interrupts 'first', so will only reach it on the rare occasions when one of these doesn't trigger. When you add another timer, it gets called even less.

Your code is fundamentally flawed in several ways:

First work on just the INT_RA interrupt and get the handler for this working. It isn't at present.
Then understand that interrupts are 'expensive' in terms of processor time. If you want two timer events that are multiples of one another, then declare a single interrupt at the fastest time, and have a simple counter inside this interrupt triggering the second event. This takes much less time than having a second interrupt handler.
Then understand that any event happening fast, will need a lot of processor time to handle. You have a relatively slow chip, and are asking it to perform four jobs, all at potentially quite fast rates.....
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