EmbeddedRelated.com
Forums

LPC2106 - Problem with accuracy of timer

Started by voltz56 April 13, 2010
When I configure the prescaler for a 1ms tick, it is off by 84ns when
checked in the keil debugger, this much inaccuracy I can live with.
, but when I have it configured for 1us it is off by approximately
940ns, this is a major problem for me.

Regards,
J
//delay = us * no_loops
void delay_us(unsigned int no_loops)
{
unsigned int i;
for(i = 0; i < no_loops; i++)
{
//pclk = cclk = 48MHz

T0_PR = 0x30; //Load Prescaler register for
usec tick, formula --> toHex(interval/(1/pclk))
T0_TCR = 0x00000003; //Reset counter and prescaler
T0_TCR = 0x00000001; //enable timer
while ( T0_TC < 1);
T0_TCR &= ~(1<<0); // Stop timer
}/*end for*/

}/*end delay*/

An Engineer's Guide to the LPC2100 Series

Hi

The algorithm used accumulates the inaccuracy that you see.
Each loop of 1ms is detecting the timer's interrupt flag after 1ms but then it has to execute several instructions in the loop to start the next 1ms interval. These several instructions result in the (presumably +84ns) inaccuracy per loop.

Since the loop has to be executed 1000x more when the timer is set to us the inaccuracy is also multiplied by 1000.

The simple method is to set the timer with the delay that you need (eg. T0_PR = (0x30 x no_loops) and then there will be just one wait for the timer and no accumulated errors. The loop should be removed (just one wait) to get the most out of the timer.

Regards

Mark

http://www.uTasker.com

--- In l..., "voltz56" wrote:
>
> When I configure the prescaler for a 1ms tick, it is off by 84ns when
> checked in the keil debugger, this much inaccuracy I can live with.
> , but when I have it configured for 1us it is off by approximately
> 940ns, this is a major problem for me.
>
> Regards,
> J
> //delay = us * no_loops
> void delay_us(unsigned int no_loops)
> {
> unsigned int i;
> for(i = 0; i < no_loops; i++)
> {
> //pclk = cclk = 48MHz
>
> T0_PR = 0x30; //Load Prescaler register for
> usec tick, formula --> toHex(interval/(1/pclk))
> T0_TCR = 0x00000003; //Reset counter and prescaler
> T0_TCR = 0x00000001; //enable timer
> while ( T0_TC < 1);
> T0_TCR &= ~(1<<0); // Stop timer
> }/*end for*/
>
> }/*end delay*/
>

--- In l..., "Mark" wrote:
>
> Hi
>
> The algorithm used accumulates the inaccuracy that you see.
> Each loop of 1ms is detecting the timer's interrupt flag after 1ms but then it has to execute several instructions in the loop to start the next 1ms interval. These several instructions result in the (presumably +84ns) inaccuracy per loop.
>
> Since the loop has to be executed 1000x more when the timer is set to us the inaccuracy is also multiplied by 1000.
>
> The simple method is to set the timer with the delay that you need (eg. T0_PR = (0x30 x no_loops) and then there will be just one wait for the timer and no accumulated errors. The loop should be removed (just one wait) to get the most out of the timer.
>
> Regards
>
> Mark
>
> http://www.uTasker.com
>
> --- In l..., "voltz56" wrote:
> >
> > When I configure the prescaler for a 1ms tick, it is off by 84ns when
> > checked in the keil debugger, this much inaccuracy I can live with.
> > , but when I have it configured for 1us it is off by approximately
> > 940ns, this is a major problem for me.
> >
> > Regards,
> > J
> >
> >
> > //delay = us * no_loops
> > void delay_us(unsigned int no_loops)
> > {
> > unsigned int i;
> > for(i = 0; i < no_loops; i++)
> > {
> > //pclk = cclk = 48MHz
> >
> > T0_PR = 0x30; //Load Prescaler register for
> > usec tick, formula --> toHex(interval/(1/pclk))
> > T0_TCR = 0x00000003; //Reset counter and prescaler
> > T0_TCR = 0x00000001; //enable timer
> > while ( T0_TC < 1);
> > T0_TCR &= ~(1<<0); // Stop timer
> > }/*end for*/
> >
> > }/*end delay*/
>

Actually I only ever tested with 1 as the argument, I tested for different delay lengths by actually changing the prescaler.

Also there is more in accuracy at 1us(+940ns) then 1ms (+84ns).

I did remove the loop though and this reduced the inaccuracy to +660ns @1us but still far from acceptable.

Regards,
J

Il 13/04/2010 22.27, voltz56 ha scritto:
If you need precision timing you have to use a timer generating an
interrupt for the required delay and when will expire it will call a
specific function. This solution will not consume cpu time so will be
more efficient but of course you have to design your program to work
without waiting the timer to elapse.
>
>
> --- In l... ,
> "Mark" wrote:
> >
> > Hi
> >
> > The algorithm used accumulates the inaccuracy that you see.
> > Each loop of 1ms is detecting the timer's interrupt flag after 1ms
> but then it has to execute several instructions in the loop to start
> the next 1ms interval. These several instructions result in the
> (presumably +84ns) inaccuracy per loop.
> >
> > Since the loop has to be executed 1000x more when the timer is set
> to us the inaccuracy is also multiplied by 1000.
> >
> > The simple method is to set the timer with the delay that you need
> (eg. T0_PR = (0x30 x no_loops) and then there will be just one wait
> for the timer and no accumulated errors. The loop should be removed
> (just one wait) to get the most out of the timer.
> >
> > Regards
> >
> > Mark
> >
> > http://www.uTasker.com
> >
> >
> >
> > --- In l... ,
> "voltz56" wrote:
> > >
> > > When I configure the prescaler for a 1ms tick, it is off by 84ns when
> > > checked in the keil debugger, this much inaccuracy I can live with.
> > > , but when I have it configured for 1us it is off by approximately
> > > 940ns, this is a major problem for me.
> > >
> > > Regards,
> > > J
> > >
> > >
> > > //delay = us * no_loops
> > > void delay_us(unsigned int no_loops)
> > > {
> > > unsigned int i;
> > > for(i = 0; i < no_loops; i++)
> > > {
> > > //pclk = cclk = 48MHz
> > >
> > > T0_PR = 0x30; //Load Prescaler register for
> > > usec tick, formula --> toHex(interval/(1/pclk))
> > > T0_TCR = 0x00000003; //Reset counter and prescaler
> > > T0_TCR = 0x00000001; //enable timer
> > > while ( T0_TC < 1);
> > > T0_TCR &= ~(1<<0); // Stop timer
> > > }/*end for*/
> > >
> > > }/*end delay*/
> > >
> > Actually I only ever tested with 1 as the argument, I tested for
> different delay lengths by actually changing the prescaler.
>
> Also there is more in accuracy at 1us(+940ns) then 1ms (+84ns).
>
> I did remove the loop though and this reduced the inaccuracy to +660ns
> @1us but still far from acceptable.
>
> Regards,
> J
Hmmm, I still thought it would be possible to generate accurate delays down a usec without using interrupts especially in a test environment that is running no other code (just the delay routine). Iv achieved this on an 8051 I didnt think it would be a problem on....

I guess Ill have look at the user manual and give timer interrupts a shot.

Thanks,
J

--- In l..., "M. Manca" wrote:
>
> Il 13/04/2010 22.27, voltz56 ha scritto:
> If you need precision timing you have to use a timer generating an
> interrupt for the required delay and when will expire it will call a
> specific function. This solution will not consume cpu time so will be
> more efficient but of course you have to design your program to work
> without waiting the timer to elapse.
> >
> >
> >
> >
> > --- In l... ,
> > "Mark" wrote:
> > >
> > > Hi
> > >
> > > The algorithm used accumulates the inaccuracy that you see.
> > > Each loop of 1ms is detecting the timer's interrupt flag after 1ms
> > but then it has to execute several instructions in the loop to start
> > the next 1ms interval. These several instructions result in the
> > (presumably +84ns) inaccuracy per loop.
> > >
> > > Since the loop has to be executed 1000x more when the timer is set
> > to us the inaccuracy is also multiplied by 1000.
> > >
> > > The simple method is to set the timer with the delay that you need
> > (eg. T0_PR = (0x30 x no_loops) and then there will be just one wait
> > for the timer and no accumulated errors. The loop should be removed
> > (just one wait) to get the most out of the timer.
> > >
> > > Regards
> > >
> > > Mark
> > >
> > > http://www.uTasker.com
> > >
> > >
> > >
> > > --- In l... ,
> > "voltz56" wrote:
> > > >
> > > > When I configure the prescaler for a 1ms tick, it is off by 84ns when
> > > > checked in the keil debugger, this much inaccuracy I can live with.
> > > > , but when I have it configured for 1us it is off by approximately
> > > > 940ns, this is a major problem for me.
> > > >
> > > > Regards,
> > > > J
> > > >
> > > >
> > > > //delay = us * no_loops
> > > > void delay_us(unsigned int no_loops)
> > > > {
> > > > unsigned int i;
> > > > for(i = 0; i < no_loops; i++)
> > > > {
> > > > //pclk = cclk = 48MHz
> > > >
> > > > T0_PR = 0x30; //Load Prescaler register for
> > > > usec tick, formula --> toHex(interval/(1/pclk))
> > > > T0_TCR = 0x00000003; //Reset counter and prescaler
> > > > T0_TCR = 0x00000001; //enable timer
> > > > while ( T0_TC < 1);
> > > > T0_TCR &= ~(1<<0); // Stop timer
> > > > }/*end for*/
> > > >
> > > > }/*end delay*/
> > > >
> > >
> >
> > Actually I only ever tested with 1 as the argument, I tested for
> > different delay lengths by actually changing the prescaler.
> >
> > Also there is more in accuracy at 1us(+940ns) then 1ms (+84ns).
> >
> > I did remove the loop though and this reduced the inaccuracy to +660ns
> > @1us but still far from acceptable.
> >
> > Regards,
> > J
> >
>

On Tuesday 13 April 2010 05:34:29 pm voltz56 wrote:
> Hmmm, I still thought it would be possible to generate accurate delays down
> a usec without using interrupts especially in a test environment that is
> running no other code (just the delay routine). Iv achieved this on an
> 8051 I didnt think it would be a problem on....

It's not difficult doing this, especially with the LPC's "set pin on change"
functionality that is built into the timers. I am using them to essentially
"self time" the SSI peripheral since the datastream coming in is 32 bits, but
the SSI can only accept up to 16 bits.

-A.
--- In l..., "M. Manca" wrote:
>
> Il 13/04/2010 22.27, voltz56 ha scritto:
> If you need precision timing you have to use a timer generating an
> interrupt for the required delay and when will expire it will call a
> specific function. This solution will not consume cpu time so will be
> more efficient but of course you have to design your program to work
> without waiting the timer to elapse.
> >
> >
> >
> >
> > --- In l... ,
> > "Mark" M_J_Butcher@ wrote:
> > >
> > > Hi
> > >
> > > The algorithm used accumulates the inaccuracy that you see.
> > > Each loop of 1ms is detecting the timer's interrupt flag after 1ms
> > but then it has to execute several instructions in the loop to start
> > the next 1ms interval. These several instructions result in the
> > (presumably +84ns) inaccuracy per loop.
> > >
> > > Since the loop has to be executed 1000x more when the timer is set
> > to us the inaccuracy is also multiplied by 1000.
> > >
> > > The simple method is to set the timer with the delay that you need
> > (eg. T0_PR = (0x30 x no_loops) and then there will be just one wait
> > for the timer and no accumulated errors. The loop should be removed
> > (just one wait) to get the most out of the timer.
> > >
> > > Regards
> > >
> > > Mark
> > >
> > > http://www.uTasker.com
> > >
> > >
> > >
> > > --- In l... ,
> > "voltz56" wrote:
> > > >
> > > > When I configure the prescaler for a 1ms tick, it is off by 84ns
when
> > > > checked in the keil debugger, this much inaccuracy I can live
with.
> > > > , but when I have it configured for 1us it is off by
approximately
> > > > 940ns, this is a major problem for me.
> > > >
> > > > Regards,
> > > > J
> > > >
> > > >
> > > > //delay = us * no_loops
> > > > void delay_us(unsigned int no_loops)
> > > > {
> > > > unsigned int i;
> > > > for(i = 0; i < no_loops; i++)
> > > > {
> > > > //pclk = cclk = 48MHz
> > > >
> > > > T0_PR = 0x30; //Load Prescaler register for
> > > > usec tick, formula --> toHex(interval/(1/pclk))
> > > > T0_TCR = 0x00000003; //Reset counter and prescaler
> > > > T0_TCR = 0x00000001; //enable timer
> > > > while ( T0_TC < 1);
> > > > T0_TCR &= ~(1<<0); // Stop timer
> > > > }/*end for*/
> > > >
> > > > }/*end delay*/
> > > >
> > >
> >
> > Actually I only ever tested with 1 as the argument, I tested for
> > different delay lengths by actually changing the prescaler.
> >
> > Also there is more in accuracy at 1us(+940ns) then 1ms (+84ns).
> >
> > I did remove the loop though and this reduced the inaccuracy to
+660ns
> > @1us but still far from acceptable.
> >
> > Regards,
> > J
> >
>
For some reason my timer interrupt code is not running the isr, from
looking at the peripheral windows in the debugger everything "seems" to
running fine so Im sure its just something small that Im missing.

void timer0_isr() __attribute__ ((interrupt("IRQ")));

int main()
{

T0_TCR = 0x03; //Reset counter and
prescaler
T0_PR = 0x30; //Load Prescaler register
for 1usec tick, formula --> toHex(1msec/(1/pclk))
T0_IR = 0x01; //Reset timer0 interrupt
T0_MCR = 0x0003; //interrupt and reset on MR0
T0_MR0 = 0x01; //match to 1 TC iteration
VICVectCntl0 = 0x00000024; //use it for Timer 0
Interrupt
VICVectAddr0 = (unsigned)timer0_isr; //set interrupt vector 0
VICIntEnable = 0x00000010; //enable TIMER0 interrupt
T0_TCR = 0x01; //enable Timer0

GPIO0_IODIR = 0x0F;
GPIO0_IOCLR = 0x0F;
while(1);
}

void timer0_isr()
{

GPIO0_IOSET = 0x0f;
T0_IR = 0x01; //clear interrupt
VICVectAddr = 0; //end of interrupt - dummy write
}

voltz56 wrote:
> --- In l..., "M. Manca" wrote:
>> Il 13/04/2010 22.27, voltz56 ha scritto:
>> If you need precision timing you have to use a timer generating an
>> interrupt for the required delay and when will expire it will call a
>> specific function. This solution will not consume cpu time so will be
>> more efficient but of course you have to design your program to work
>> without waiting the timer to elapse.
>>>
>>>
>>>
>>> --- In l... ,
>>> "Mark" M_J_Butcher@ wrote:
>>>> Hi
>>>>
>>>> The algorithm used accumulates the inaccuracy that you see.
>>>> Each loop of 1ms is detecting the timer's interrupt flag after 1ms
>>> but then it has to execute several instructions in the loop to start
>>> the next 1ms interval. These several instructions result in the
>>> (presumably +84ns) inaccuracy per loop.
>>>> Since the loop has to be executed 1000x more when the timer is set
>>> to us the inaccuracy is also multiplied by 1000.
>>>> The simple method is to set the timer with the delay that you need
>>> (eg. T0_PR = (0x30 x no_loops) and then there will be just one wait
>>> for the timer and no accumulated errors. The loop should be removed
>>> (just one wait) to get the most out of the timer.
>>>> Regards
>>>>
>>>> Mark
>>>>
>>>> http://www.uTasker.com
>>>>
>>>>
>>>>
>>>> --- In l... ,
>>> "voltz56" wrote:
>>>>> When I configure the prescaler for a 1ms tick, it is off by 84ns
> when
>>>>> checked in the keil debugger, this much inaccuracy I can live
> with.
>>>>> , but when I have it configured for 1us it is off by
> approximately
>>>>> 940ns, this is a major problem for me.
>>>>>
>>>>> Regards,
>>>>> J
>>>>>
>>>>>
>>>>> //delay = us * no_loops
>>>>> void delay_us(unsigned int no_loops)
>>>>> {
>>>>> unsigned int i;
>>>>> for(i = 0; i < no_loops; i++)
>>>>> {
>>>>> //pclk = cclk = 48MHz
>>>>>
>>>>> T0_PR = 0x30; //Load Prescaler register for
>>>>> usec tick, formula --> toHex(interval/(1/pclk))
>>>>> T0_TCR = 0x00000003; //Reset counter and prescaler
>>>>> T0_TCR = 0x00000001; //enable timer
>>>>> while ( T0_TC < 1);
>>>>> T0_TCR &= ~(1<<0); // Stop timer
>>>>> }/*end for*/
>>>>>
>>>>> }/*end delay*/
>>>>>
>>> Actually I only ever tested with 1 as the argument, I tested for
>>> different delay lengths by actually changing the prescaler.
>>>
>>> Also there is more in accuracy at 1us(+940ns) then 1ms (+84ns).
>>>
>>> I did remove the loop though and this reduced the inaccuracy to
> +660ns
>>> @1us but still far from acceptable.
>>>
>>> Regards,
>>> J
>>>
>>> For some reason my timer interrupt code is not running the isr, from
> looking at the peripheral windows in the debugger everything "seems" to
> running fine so Im sure its just something small that Im missing.
>
> void timer0_isr() __attribute__ ((interrupt("IRQ")));
>
> int main()
> {
>
> T0_TCR = 0x03; //Reset counter and
> prescaler
> T0_PR = 0x30; //Load Prescaler register
> for 1usec tick, formula --> toHex(1msec/(1/pclk))
> T0_IR = 0x01; //Reset timer0 interrupt
> T0_MCR = 0x0003; //interrupt and reset on MR0
> T0_MR0 = 0x01; //match to 1 TC iteration
> VICVectCntl0 = 0x00000024; //use it for Timer 0
> Interrupt
> VICVectAddr0 = (unsigned)timer0_isr; //set interrupt vector 0
> VICIntEnable = 0x00000010; //enable TIMER0 interrupt
> T0_TCR = 0x01; //enable Timer0
>
> GPIO0_IODIR = 0x0F;
> GPIO0_IOCLR = 0x0F;
> while(1);
> }
>
> void timer0_isr()
> {
>
> GPIO0_IOSET = 0x0f;
> T0_IR = 0x01; //clear interrupt
> VICVectAddr = 0; //end of interrupt - dummy write
> }
I do not see any code turning on the power for the timers.

regards,
Charles
--- In l..., "Charles R. Grenz"
wrote:
>
> voltz56 wrote:
> > --- In l..., "M. Manca" m.manca@ wrote:
> >> Il 13/04/2010 22.27, voltz56 ha scritto:
> >> If you need precision timing you have to use a timer generating an
> >> interrupt for the required delay and when will expire it will call
a
> >> specific function. This solution will not consume cpu time so will
be
> >> more efficient but of course you have to design your program to
work
> >> without waiting the timer to elapse.
> >>>
> >>>
> >>>
> >>> --- In l... ,
> >>> "Mark" M_J_Butcher@ wrote:
> >>>> Hi
> >>>>
> >>>> The algorithm used accumulates the inaccuracy that you see.
> >>>> Each loop of 1ms is detecting the timer's interrupt flag after
1ms
> >>> but then it has to execute several instructions in the loop to
start
> >>> the next 1ms interval. These several instructions result in the
> >>> (presumably +84ns) inaccuracy per loop.
> >>>> Since the loop has to be executed 1000x more when the timer is
set
> >>> to us the inaccuracy is also multiplied by 1000.
> >>>> The simple method is to set the timer with the delay that you
need
> >>> (eg. T0_PR = (0x30 x no_loops) and then there will be just one
wait
> >>> for the timer and no accumulated errors. The loop should be
removed
> >>> (just one wait) to get the most out of the timer.
> >>>> Regards
> >>>>
> >>>> Mark
> >>>>
> >>>> http://www.uTasker.com
> >>>>
> >>>>
> >>>>
> >>>> --- In l...
,
> >>> "voltz56" wrote:
> >>>>> When I configure the prescaler for a 1ms tick, it is off by 84ns
> > when
> >>>>> checked in the keil debugger, this much inaccuracy I can live
> > with.
> >>>>> , but when I have it configured for 1us it is off by
> > approximately
> >>>>> 940ns, this is a major problem for me.
> >>>>>
> >>>>> Regards,
> >>>>> J
> >>>>>
> >>>>>
> >>>>> //delay = us * no_loops
> >>>>> void delay_us(unsigned int no_loops)
> >>>>> {
> >>>>> unsigned int i;
> >>>>> for(i = 0; i < no_loops; i++)
> >>>>> {
> >>>>> //pclk = cclk = 48MHz
> >>>>>
> >>>>> T0_PR = 0x30; //Load Prescaler register for
> >>>>> usec tick, formula --> toHex(interval/(1/pclk))
> >>>>> T0_TCR = 0x00000003; //Reset counter and prescaler
> >>>>> T0_TCR = 0x00000001; //enable timer
> >>>>> while ( T0_TC < 1);
> >>>>> T0_TCR &= ~(1<<0); // Stop timer
> >>>>> }/*end for*/
> >>>>>
> >>>>> }/*end delay*/
> >>>>>
> >>> Actually I only ever tested with 1 as the argument, I tested for
> >>> different delay lengths by actually changing the prescaler.
> >>>
> >>> Also there is more in accuracy at 1us(+940ns) then 1ms (+84ns).
> >>>
> >>> I did remove the loop though and this reduced the inaccuracy to
> > +660ns
> >>> @1us but still far from acceptable.
> >>>
> >>> Regards,
> >>> J
> >>>
> >>>
> >
> > For some reason my timer interrupt code is not running the isr, from
> > looking at the peripheral windows in the debugger everything "seems"
to
> > running fine so Im sure its just something small that Im missing.
> >
> > void timer0_isr() __attribute__ ((interrupt("IRQ")));
> >
> > int main()
> > {
> >
> > T0_TCR = 0x03; //Reset counter and
> > prescaler
> > T0_PR = 0x30; //Load Prescaler
register
> > for 1usec tick, formula --> toHex(1msec/(1/pclk))
> > T0_IR = 0x01; //Reset timer0
interrupt
> > T0_MCR = 0x0003; //interrupt and reset on
MR0
> > T0_MR0 = 0x01; //match to 1 TC
iteration
> > VICVectCntl0 = 0x00000024; //use it for Timer 0
> > Interrupt
> > VICVectAddr0 = (unsigned)timer0_isr; //set interrupt vector 0
> > VICIntEnable = 0x00000010; //enable TIMER0
interrupt
> > T0_TCR = 0x01; //enable Timer0
> >
> > GPIO0_IODIR = 0x0F;
> > GPIO0_IOCLR = 0x0F;
> > while(1);
> > }
> >
> > void timer0_isr()
> > {
> >
> > GPIO0_IOSET = 0x0f;
> > T0_IR = 0x01; //clear interrupt
> > VICVectAddr = 0; //end of interrupt - dummy write
> > }
> >
> >
> I do not see any code turning on the power for the timers.
>
> regards,
> Charles
>

Your joking right?

I think the problem is with my startup file, -there doesnt appear to be
any code to enable/config interrupts, but Im unsure how to do this.

http://pastebin.com/cDB2j3Sb

Regards,
J
voltz56 wrote:
>
> --- In l..., "Charles R. Grenz"
> wrote:
> >
> > voltz56 wrote:
> > > --- In l..., "M. Manca" m.manca@ wrote:
> > >> Il 13/04/2010 22.27, voltz56 ha scritto:
> > >> If you need precision timing you have to use a timer generating an
> > >> interrupt for the required delay and when will expire it will call a
> > >> specific function. This solution will not consume cpu time so will be
> > >> more efficient but of course you have to design your program to work
> > >> without waiting the timer to elapse.
> > >>>
> > >>>
> > >>>
> > >>> --- In l... ,
> > >>> "Mark" M_J_Butcher@ wrote:
> > >>>> Hi
> > >>>>
> > >>>> The algorithm used accumulates the inaccuracy that you see.
> > >>>> Each loop of 1ms is detecting the timer's interrupt flag after 1ms
> > >>> but then it has to execute several instructions in the loop to start
> > >>> the next 1ms interval. These several instructions result in the
> > >>> (presumably +84ns) inaccuracy per loop.
> > >>>> Since the loop has to be executed 1000x more when the timer is set
> > >>> to us the inaccuracy is also multiplied by 1000.
> > >>>> The simple method is to set the timer with the delay that you need
> > >>> (eg. T0_PR = (0x30 x no_loops) and then there will be just one wait
> > >>> for the timer and no accumulated errors. The loop should be removed
> > >>> (just one wait) to get the most out of the timer.
> > >>>> Regards
> > >>>>
> > >>>> Mark
> > >>>>
> > >>>> http://www.uTasker.com
> > >>>>
> > >>>>
> > >>>>
> > >>>> --- In l... ,
> > >>> "voltz56" wrote:
> > >>>>> When I configure the prescaler for a 1ms tick, it is off by 84ns
> > > when
> > >>>>> checked in the keil debugger, this much inaccuracy I can live
> > > with.
> > >>>>> , but when I have it configured for 1us it is off by
> > > approximately
> > >>>>> 940ns, this is a major problem for me.
> > >>>>>
> > >>>>> Regards,
> > >>>>> J
> > >>>>>
> > >>>>>
> > >>>>> //delay = us * no_loops
> > >>>>> void delay_us(unsigned int no_loops)
> > >>>>> {
> > >>>>> unsigned int i;
> > >>>>> for(i = 0; i < no_loops; i++)
> > >>>>> {
> > >>>>> //pclk = cclk = 48MHz
> > >>>>>
> > >>>>> T0_PR = 0x30; //Load Prescaler register for
> > >>>>> usec tick, formula --> toHex(interval/(1/pclk))
> > >>>>> T0_TCR = 0x00000003; //Reset counter and prescaler
> > >>>>> T0_TCR = 0x00000001; //enable timer
> > >>>>> while ( T0_TC < 1);
> > >>>>> T0_TCR &= ~(1<<0); // Stop timer
> > >>>>> }/*end for*/
> > >>>>>
> > >>>>> }/*end delay*/
> > >>>>>
> > >>> Actually I only ever tested with 1 as the argument, I tested for
> > >>> different delay lengths by actually changing the prescaler.
> > >>>
> > >>> Also there is more in accuracy at 1us(+940ns) then 1ms (+84ns).
> > >>>
> > >>> I did remove the loop though and this reduced the inaccuracy to
> > > +660ns
> > >>> @1us but still far from acceptable.
> > >>>
> > >>> Regards,
> > >>> J
> > >>>
> > >>>
> > >
> > > For some reason my timer interrupt code is not running the isr, from
> > > looking at the peripheral windows in the debugger everything "seems" to
> > > running fine so Im sure its just something small that Im missing.
> > >
> > > void timer0_isr() __attribute__ ((interrupt("IRQ")));
> > >
> > > int main()
> > > {
> > >
> > > T0_TCR = 0x03; //Reset counter and
> > > prescaler
> > > T0_PR = 0x30; //Load Prescaler register
> > > for 1usec tick, formula --> toHex(1msec/(1/pclk))
> > > T0_IR = 0x01; //Reset timer0 interrupt
> > > T0_MCR = 0x0003; //interrupt and reset on MR0
> > > T0_MR0 = 0x01; //match to 1 TC iteration
> > > VICVectCntl0 = 0x00000024; //use it for Timer 0
> > > Interrupt
> > > VICVectAddr0 = (unsigned)timer0_isr; //set interrupt vector 0
> > > VICIntEnable = 0x00000010; //enable TIMER0 interrupt
> > > T0_TCR = 0x01; //enable Timer0
> > >
> > > GPIO0_IODIR = 0x0F;
> > > GPIO0_IOCLR = 0x0F;
> > > while(1);
> > > }
> > >
> > > void timer0_isr()
> > > {
> > >
> > > GPIO0_IOSET = 0x0f;
> > > T0_IR = 0x01; //clear interrupt
> > > VICVectAddr = 0; //end of interrupt - dummy write
> > > }
> > >
> > >
> >
> >
> > I do not see any code turning on the power for the timers.
> >
> > regards,
> > Charles
> > Your joking right?
>
> I think the problem is with my startup file, -there doesnt appear to be
> any code to enable/config interrupts, but Im unsure how to do this.
>
> http://pastebin.com/cDB2j3Sb
>
> Regards,
> J

No I'm not. You need to wrote to the PCOMP register to enable the
timer you want to use!

In terms of enabling and disabling interrupts, yes you need to do that
as well but I am unsure how to do it with your compiler only IAR.

regards,
Charles