|
|
View previous topic :: View next topic |
Author |
Message |
enam04eee
Joined: 25 May 2014 Posts: 1
|
12f683 Timer2 problem |
Posted: Sun May 25, 2014 11:08 pm |
|
|
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: 19504
|
|
Posted: Mon May 26, 2014 1:14 am |
|
|
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..... |
|
|
|
|
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
|