View previous topic :: View next topic |
Author |
Message |
teekaytk
Joined: 14 Jan 2005 Posts: 28
|
quick one about timer acuracy |
Posted: Fri Jan 14, 2005 5:19 am |
|
|
hi all,
I need timer accurate to micro (or even pico) second. I was looking through the PIC manul that says that you should add 2 to your timer value to compensate for 2 ticks loss while timer values are updates. I wanted to ask is the compiler would do it automatically for me or do i need to add the 2 my self.
Regads
teekay_tk |
|
|
Haplo
Joined: 06 Sep 2003 Posts: 659 Location: Sydney, Australia
|
|
Posted: Fri Jan 14, 2005 6:46 am |
|
|
You will have to do it yourself. |
|
|
teekaytk
Joined: 14 Jan 2005 Posts: 28
|
|
Posted: Fri Jan 14, 2005 7:14 am |
|
|
thanks,
one more questioin please, timer1 in PIC18f252 set to 65460 in CCS should give a 100 micro sec (at24MHz (6Mhz+pll)) but it gives me like 110micros, any say in this, if you wish i would post the code |
|
|
Haplo
Joined: 06 Sep 2003 Posts: 659 Location: Sydney, Australia
|
|
Posted: Fri Jan 14, 2005 7:26 am |
|
|
How are you measuring that 110us?
Yes posting the code always helps. Don't forget to use the 'Code' buttons. |
|
|
teekaytk
Joined: 14 Jan 2005 Posts: 28
|
|
Posted: Fri Jan 14, 2005 7:38 am |
|
|
i am measuring the 110 on digital oscilloscope (tektronix tds210)
the code is as follows . sorry for my crappy C. timer 0 is nested in timer 1 Code: |
#define timer0_val_tx 65460
#define timer0_val_rx 65520
#define timer1_val 65200
int1 pinstate;
int1 TOGGLE_SLOT;
int1 rx_timer_on_led;
#int_rtcc // This function is called every time
void timer0() { // the RTCC (timer0)
#ifdef TXR;
set_timer0(timer0_val_tx);
pinstate= !pinstate; //toggle
output_bit(LED1,pinstate); //toggle led
output_bit(TX_data,pinstate); //toggle TX_data
output_bit(RS232_CTRL_out,pinstate);
#else //if RXR
set_timer0 (timer0_val_rx);
pinstate=input(RX_data);
output_bit(LED2, pinstate);//show incomming data on PIN_B2
rx_timer_on_led=!rx_timer_on_led;
output_bit(LED1,rx_timer_on_led);
#endif
}
#int_timer1
void timer1(){
set_timer1(TIMER1_VAL);
output_low(led1);
#ifdef TXR
if (toggle_slot==1){
SET_TIMER0(TIMER1_VAL) ;
enable_interrupts (INT_TIMER0);
toggle_slot=0;
output_high(led1);
}
else
{
disable_interrupts (INT_TIMER0);
toggle_slot=1;
output_low(led1);
}
#else //IF RXR
SET_TIMER0(TIMER1_VAL) ;
enable_interrupts (INT_TIMER0);
toggle_slot=0;
output_high(led1);
#endif
}
void main() {
int loop;
#ifdef TXR
output_high (TX_ENABLE);
#else
output_high (RX_ENABLE);
#endif
pinstate=0;
TOGGLE_SLOT=1;
output_high(LED1);
output_high(LED2);
setup_adc_ports (NO_ANALOGS); // no analog (excpet A0)
setup_adc (ADC_OFF); // ADC is OFF
set_tris_a(0b00000000); // SET POT A TO ALL OUTPUTS NO INPUTS
set_tris_b(0b11000110);
set_tris_b(0b10000111);
output_high (RS232_ENABLE); // SWITCH ON RS232 DRIVER
SEt_Timer1(TIMER1_VAL);
setup_timer_0 (RTCC_DIV_8);
t1con=0b10111011;
// setup_timer_1 (T1_DIV_BY_4);
enable_interrupts (Global);
enable_interrupts (INT_TIMER1);
output_low(led2);
while (TRUE)
{
}
} |
|
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Fri Jan 14, 2005 7:46 am |
|
|
It is probably due to interrupt latency. It takes some time to process the interrupt. If you are setting the timer1 value inside the interrupt handler, that is your problem. You should add you value instead. The timer1 value should be at 0 when you are setting it. In reality, it is not. By adding your offset, you will compensate for the latency. I would use one of the ccp modules instead. Look up the compare feature. |
|
|
teekaytk
Joined: 14 Jan 2005 Posts: 28
|
|
Posted: Fri Jan 14, 2005 8:03 am |
|
|
thanks ali and mark. i could have done a ccp but i need to use this timer to later send data over the radio, not just 10101 pulses. un fortunately i have found out that this problem is shome how consistant with ccs , i used cc5x compiler that gave me quite accurate times as defined by formula , now i am porting the code to this compiler and seems that it is not consistant any more, there is a lag or lead of upto 8 cycles before presclaer. thanks anyway and i shall be grateful for a reply if any one has solved this problem |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Fri Jan 14, 2005 8:23 am |
|
|
I guess you didn't read the first part of my post
Quote: |
It is probably due to interrupt latency. It takes some time to process the interrupt. |
which after seeing you code I will change to
It is definitely due to interrupt latency. It takes some time to process the interrupt. You should add you value instead. |
|
|
teekaytk
Joined: 14 Jan 2005 Posts: 28
|
|
Posted: Fri Jan 14, 2005 8:26 am |
|
|
thanks mark,
i went to assembler and found that it took 4 instructions to write to the register of timer1. that is a good starting point
thanks |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Fri Jan 14, 2005 9:49 am |
|
|
You still aren't getting it! At the time of the interrupt, Timer1's value will be 0. The program branches to the interrupt vector. The compiler then saves its working registers and the status, w and so on. Now it must test which interrupt occurred. All this takes time. Probably about 10us from what you are seeing. When you finally get to setting timer1 its value isn't 0 as your code expects. You set timer1 to your count which loses the time already past! You need to add that value to timer1 instead of setting it. It will account for the latency if you do. |
|
|
teekay_tk Guest
|
|
Posted: Fri Jan 14, 2005 12:07 pm |
|
|
hmm..ok, may i ask you one more thing, is this delay variable or fixed? i seem to get a range of delays at different presaclars and different values of timers? also the delay is either negative or positive? |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Fri Jan 14, 2005 12:22 pm |
|
|
Since the delay is actually in machine cycles, then different prescalers will cause different delays. Is it variable or fixed? Yes If you are not currently servicing an interrupt and you do not disable interrupts (or the compiler is not disabling them) and the interrupt is first in the priority list, then the delay is pretty constant otherwise it could change a bit. However, by adding the timer preset value to the timer value, the average time should always be 100us unless the delay exceeds 100us in which case you would miss that int. |
|
|
|