timer_32 capture edge

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

timer_32 capture edge

1,591 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by dennisdd on Mon Jul 01 03:42:13 MST 2013
Hi guys,

I steal some code somewhere from the forum.

The things is I am not getting consistent count from PWM with different timing.

( timing measured from one rising edge to another rising edge)
For 10.10ms = 31161counts, 1ms = 3085.24 counts
For 20.40ms = 62408counts, 1ms = 3059.21 counts
For 16.30ms = 63016counts, 1ms = 3866.012 counts
For 18.30ms = 29944count

Both is using the same setting.only changing on PWM.

Question:
1. Do I need to use pre scaler? Because the example I followed doesn't but isn't it we need to decide the timer resolution? I set init_timer32(10UL);

2. Why the value I am getting varies? Is this overflow happened?

void TIMER32_0_IRQHandler(void)
{
  if ( LPC_CT32B0->IR & (0x1<<4) )
  {  
LPC_CT32B0->IR = 0x1<<4;        // clear interrupt flag

// Capturing  Rising edge to another rising edge
if(start_flag == 1)
{// This is where the 1st rising edge
LPC_CT32B0->TC = 0;    // Reset counter
start_flag = 2;
}
else if(start_flag == 2)
{// This is the 2nd rising edge
                // CR0 is loaded with the value of TC when there
// is an event on the CT32B1_CAP0 input.
                // only update with new data id timerValue sent and clear.

if(!timerValue)
timerValue = LPC_CT32B0->CR0;
 
start_flag = 1;
LPC_CT32B0->TC = 0;    // Reset counter
}
  }
}

void init_timer32( U32 timer )
{
    NVIC_DisableIRQ(TIMER_32_0_IRQn);
    NDrv_Timer32_Reset(Timer32_0);

    LPC_CT32B0->PR = timer;

    LPC_SYSCON->SYSAHBCLKCTRL |= BIT9;
    LPC_IOCON->PIO0_17 = (1<<1)|(2<<3);//CT32B0_CAP0;
    LPC_CT32B0->CTCR |= 0;//CAP0|CAP_MODE_BOTH_EDGE;// Timer mode 
    LPC_CT32B0->CCR |= 5;//CAP0FE|CAP0RE;// Capture 0 on rising edge, interrupt enable.
    //LPC_CT32B0->MCR |= MR0I; // Interrupt on MR0
    LPC_CT32B0->TCR |= 1;// Start counting

    NVIC_EnableIRQ(TIMER_32_0_IRQn); // Enable the TIMER0 Interrupt
}
0 Kudos
Reply
7 Replies

1,551 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by dennisdd on Tue Jul 02 02:47:33 MST 2013

Quote: R2D2
And my second guess is that your prescaler isn't running because you tried to write to a peripheral register before the peripheral clock is running:
LPC_CT32B0->PR = timer;        
[COLOR=Red]LPC_SYSCON->SYSAHBCLKCTRL |= BIT9;[/COLOR]
So your prescaler is still 0.



oh, you save my day! this is the real cause of prescaler not working.
0 Kudos
Reply

1,551 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by dennisdd on Tue Jul 02 02:43:46 MST 2013

void nsAPI_System_Init(void)
{
U8 i;

LPC_SYSCON->PDRUNCFG &= ~BIT5;/*Power-up System Osc*/
LPC_SYSCON->SYSOSCCTRL = SYSOSCCTRL_Val;
for (i = 0; i < 200; i++) __NOP();

LPC_SYSCON->SYSPLLCLKSEL = SYSPLLCLKSEL_Val;/*Select PLL Input*/
LPC_SYSCON->SYSPLLCLKUEN = 0x01;/*Update Clock Source*/
LPC_SYSCON->SYSPLLCLKUEN = 0x00;/*Toggle Update Register*/
LPC_SYSCON->SYSPLLCLKUEN = 0x01;
while(!(LPC_SYSCON->SYSPLLCLKUEN & BIT0)){}/*Wait Until Updated*/

LPC_SYSCON->SYSPLLCTRL = SYSPLLCTRL_Val;/*Main Clock is PLL Out*/
LPC_SYSCON->PDRUNCFG &= ~BIT7;/*Power-up SYSPLL*/
while(!(LPC_SYSCON->SYSPLLSTAT & BIT0)){}/*Wait Until PLL Locked*/

LPC_SYSCON->MAINCLKSEL = MAINCLKSEL_Val;/*Select PLL Clock Output*/
LPC_SYSCON->MAINCLKUEN = 0x01;/*Update MCLK Clock Source*/
LPC_SYSCON->MAINCLKUEN = 0x00;/*Toggle Update Register*/
LPC_SYSCON->MAINCLKUEN = 0x01;
while (!(LPC_SYSCON->MAINCLKUEN & BIT0)){}/*Wait Until Updated*/

LPC_SYSCON->SYSAHBCLKDIV  = SYSAHBCLKDIV_Val;

LPC_SYSCON->PDRUNCFG &= ~BIT10;/* Power-up USB PHY*/

LPC_SYSCON->PDRUNCFG &= ~BIT8;/* Power-up USB PLL*/
LPC_SYSCON->USBPLLCLKSEL = USBPLLCLKSEL_Val;/* Select PLL Input*/
LPC_SYSCON->USBPLLCLKUEN = 0x01;/*Update Clock Source*/
LPC_SYSCON->USBPLLCLKUEN = 0x00;/*Toggle Update Register*/
LPC_SYSCON->USBPLLCLKUEN = 0x01;

while (!(LPC_SYSCON->USBPLLCLKUEN & BIT0)){}/*Wait Until Updated*/
LPC_SYSCON->USBPLLCTRL = USBPLLCTRL_Val;

while (!(LPC_SYSCON->USBPLLSTAT & BIT0)){}/*Wait Until PLL Locked*/
LPC_SYSCON->USBCLKSEL = 0x00;/*Select USB PLL*/

LPC_SYSCON->USBCLKSEL = USBCLKSEL_Val;/* Select USB Clock */
LPC_SYSCON->USBCLKDIV = USBCLKDIV_Val;/* Set USB clock divider */

/* System clock to the IOCON needs to be enabled or
most of the I/O related peripherals won't work. */
LPC_SYSCON->SYSAHBCLKCTRL |= BIT16;

SystemCoreClock = (__SYS_OSC_CLK * ((LPC_SYSCON->SYSPLLCTRL & 0x01F) + 1));
SystemCoreClock /= LPC_SYSCON->SYSAHBCLKDIV;

nsAPI_UART_Init(BR);
nsAPI_I2C_Init();
nsAPI_GPIO_Init();
nsAPI_USB_Init();/* USB Initialization */
nsAPI_Timer16_Init(Timer16_0,9/*ms*/);
init_timer32(48000UL);

nsAPI_SysTick_Init();
nsAPI_SSP_Init();

}



my init code
0 Kudos
Reply

1,551 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by dennisdd on Tue Jul 02 02:34:53 MST 2013
I found the mistakes lies on my timerValue(U16). After I change it to U32 the value make sense.

<rising edge to another rising edge> Prescale set at 48000UL
2.08ms = 97,873 counts(average)   1ms =  47054.32 counts
10.2ms = 489,873 counts(average)  1ms =  48026.76 counts
12.2ms = 587,873 counts(average)  1ms =  48186.31 counts
14.24ms = 685,873 counts(average) 1ms =  48165.24 counts
16.30ms = 783,872 counts(average) 1ms =  48090.31 counts
18.40ms = 881,873 counts(average) 1ms =  47927.88 counts

I think if according the prescaler setup I suppose 1ms = 48000 counts? Is the value  different due to the delay or something?

Is it safe for me to take 1ms = 48000? How should I go by this one?
0 Kudos
Reply

1,551 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by R2D2 on Tue Jul 02 01:41:54 MST 2013
And my second guess is that your prescaler isn't running because you tried to write to a peripheral register before the peripheral clock is running:
LPC_CT32B0->PR = timer;        
[COLOR=Red]LPC_SYSCON->SYSAHBCLKCTRL |= BIT9;[/COLOR]
So your prescaler is still 0.
0 Kudos
Reply

1,551 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by R2D2 on Tue Jul 02 00:46:05 MST 2013
Your problem is not an inconsistent timing or an overflow. Your problem is that your timing is wrong at all.

What caused this problem isn't visible in this code snippet. So please post the complete project.

With prescaler = 10 your timer should prescale by 11. With a 48MHz main clock it should count about 4360 times/ms.

That's far away from your values. Either something is slowing down your code or your setup is wrong.

My first guess would be a forgotten volatile. Are all flags volatile? Is timerValue 32bit?
0 Kudos
Reply

1,551 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by dennisdd on Mon Jul 01 19:00:16 MST 2013

Quote: R2D2
Answers:

1. No, but it's nearly always useful. Note: PR=10 means prescaling by 11.

2. Don't know that. Could be useful to give us a hint which chip and which clock you are using.



-> Lpc11u24.
-> System clock 48MHz(last check).
0 Kudos
Reply

1,551 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by R2D2 on Mon Jul 01 04:24:27 MST 2013

Quote: dennisdd

Question:
1. Do I need to use pre scaler? Because the example I followed doesn't but isn't it we need to decide the timer resolution? I set init_timer32(10UL);

2. Why the value I am getting varies? Is this overflow happened?



Answers:

1. No, but it's nearly always useful. Note: PR=10 means prescaling by 11.

2. Don't know that. Could be useful to give us a hint which chip and which clock you are using.
0 Kudos
Reply