LPC1114 Capture input please help

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

LPC1114 Capture input please help

991 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by exgreyfox on Tue May 21 07:42:00 MST 2013
Hello,

Basically what I want to do is feed a square wave of varying frequency over time into the CT16B1_CAP0 input of my LPC1114 and have it be read. I have written some code to do this but I do not understand what I am seeing in the CR0 register when debugging. I am using a function generator to stick a 100Hz 3.3volt square wave into the CT16B1_CAP0 input and am monitoring the CR0 register as I am stepping through debugging. As soon as I remove the square wave from the CAP0 input I can see the CR0 register stopping to update. So I know its capturing my input, however, I cannot make any sense of what values are being written to the CR0 register. Here is my code:

In main.c

#include "driver_config.h"
#include "target_config.h"

#include "gpio.h"
#include "timer16.h"
#include "timer32.h"

int main (void) {

/* Init the system */
SystemInit();
/* Init the GPIO */
GPIOInit();
//initialize 16-bit COUNTER/TIMER 0 
init_timer16(1, TIME_INTERVAL);
enable_timer16(1);

  while (1)
  { 
     }

  return 0;
}


In timer16.c I have modified TIMER16_1_IRQHandler and init_timer16 to look like this:

void TIMER16_1_IRQHandler(void)
{
  if ( LPC_TMR16B1->IR & 0x1 )
  {  
  LPC_TMR16B1->IR = 1;        // clear interrupt flag
  timer16_1_counter++;
  }
  if ( LPC_TMR16B1->IR & (0x1<<4) )
  {
LPC_TMR16B1->TC = 0;//reset timer
timer16_1_capture = LPC_TMR16B1->CR0;//read period
LPC_TMR16B1->IR = 0x1<<4;/* clear interrupt flag */
  }
  return;
}


void init_timer16(uint8_t timer_num, uint16_t TimerInterval)
{
  if ( timer_num == 0 )
  {
    /* Some of the I/O pins need to be clearfully planned if
    you use below module because JTAG and TIMER CAP/MAT pins are muxed. */
    LPC_SYSCON->SYSAHBCLKCTRL |= (1<<7);
    LPC_IOCON->PIO0_2           &= ~0x07;/*  Timer0_16 I/O config */
    LPC_IOCON->PIO0_2           |= 0x02;/* Timer0_16 CAP0 */
    LPC_IOCON->PIO0_8           &= ~0x07;
    LPC_IOCON->PIO0_8           |= 0x02;/* Timer0_16 MAT0 */
    LPC_IOCON->PIO0_9           &= ~0x07;
    LPC_IOCON->PIO0_9           |= 0x02;/* Timer0_16 MAT1 */
#ifdef __JTAG_DISABLED
    LPC_IOCON->JTAG_TCK_PIO0_10 &= ~0x07;
    LPC_IOCON->JTAG_TCK_PIO0_10 |= 0x03;/* Timer0_16 MAT2 */
#endif

    timer16_0_counter = 0;
timer16_0_capture = 0;

    LPC_TMR16B0->PR  = MHZ_PRESCALE; /* set prescaler to get 1 M counts/sec */
    LPC_TMR16B0->MR0 = TIME_INTERVALmS * 10; /* Set up 10 mS interval */
#if TIMER_MATCH
LPC_TMR16B0->EMR &= ~(0xFF<<4);
LPC_TMR16B0->EMR |= ((0x3<<4)|(0x3<<6));
#else
/* Capture 0 on rising edge, interrupt enable. */
LPC_TMR16B0->CCR = (0x1<<0)|(0x1<<2);
#endif
    LPC_TMR16B0->MCR = 3;/* Interrupt and Reset on MR0 and MR1 */

    /* Enable the TIMER0 Interrupt */
    NVIC_EnableIRQ(TIMER_16_0_IRQn);
  }
  else if ( timer_num == 1 )
  {
    /* Some of the I/O pins need to be clearfully planned if
    you use below module because JTAG and TIMER CAP/MAT pins are muxed. */
    LPC_SYSCON->SYSAHBCLKCTRL |= (1<<8);
    LPC_IOCON->PIO1_8           &= ~0x2F;/*  Timer1_16 I/O config */
    LPC_IOCON->PIO1_8           |= 0x01;/* Timer1_16 CAP0 */
    LPC_IOCON->PIO1_9           &= ~0x07;
    LPC_IOCON->PIO1_9           |= 0x01;/* Timer1_16 MAT0 */
    LPC_IOCON->PIO1_10          &= ~0x07;
    LPC_IOCON->PIO1_10          |= 0x02;/* Timer1_16 MAT1 */

    timer16_1_counter = 0;
    timer16_1_capture = 0;
    LPC_TMR16B1->PR  = MHZ_PRESCALE; /* set prescaler to get 1 M counts/sec */
    LPC_TMR16B1->MR0 = TIME_INTERVALmS * 10; /* Set up 10 mS interval */
#if TIMER_MATCH
    LPC_TMR16B1->EMR &= ~(0xFF<<4);
    LPC_TMR16B1->EMR |= ((0x3<<4)|(0x3<<6));
#else
    LPC_TMR16B1->CTCR = 0;                           //use timer mode

    /* Capture 0 on rising edge, interrupt enable. */
    LPC_TMR16B1->CCR = (0x1<<0)|(0x1<<2);
#endif
    LPC_TMR16B1->MCR = 3;/* Interrupt and Reset on MR0 and MR1 */

    /* Enable the TIMER1 Interrupt */
    NVIC_EnableIRQ(TIMER_16_1_IRQn);
  }
  return;
}



I am not sure how the pre-scale value works so maybe that is what is confusing me. Here is a sample of the hex values I'm seeing in the CR0 register with a 100Hz 3.3 volt square wave on the CT16B1_CAP0 input.

0x184
0x2288
0xc7
0xe04
0x17bc


Any help is greatly appreciated
0 Kudos
18 Replies

795 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by R2D2 on Tue May 21 15:00:24 MST 2013

Quote: ExGreyFox
How would I achieve a 3us resolution?



Come on, if
#define MHZ_PRESCALE    (TIMER_CLOCKFREQ/1000000)-1  // = 48-1
is prescaler for 1us that's not too difficult to guess
0 Kudos

795 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by exgreyfox on Tue May 21 13:19:18 MST 2013

Quote: R2D2
And 3us resolution isn't accurate enough?



How would I achieve a 3us resolution?
0 Kudos

795 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by R2D2 on Tue May 21 12:00:18 MST 2013

Quote: ExGreyFox
Aha, I see how that works. the 32-bit timer would def be more beneficial. I need to measure frequencies from 7.2Hz up yo 260Hz and I start losing precision as I get into the higher frequencies. Unfortunately the 32-bit timer pins are being used up in my design to interface hardware such as a DAC and using the 32-bit timer to make a PWM.


And 3us resolution isn't accurate enough?
0 Kudos

795 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by exgreyfox on Tue May 21 11:33:51 MST 2013

Quote: R2D2
Increase your presaler to
(TIMER_CLOCKFREQ/100000)-1  =479
and count with 10µs
or
(TIMER_CLOCKFREQ/10000)-1   =4799
and count with 100us.

Or you just use 32bit timer :eek:



Aha, I see how that works. the 32-bit timer would def be more beneficial. I need to measure frequencies from 7.2Hz up yo 260Hz and I start losing precision as I get into the higher frequencies. Unfortunately the 32-bit timer pins are being used up in my design to interface hardware such as a DAC and using the 32-bit timer to make a PWM.
0 Kudos

795 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by R2D2 on Tue May 21 10:47:05 MST 2013

Quote: ExGreyFox
It seems that I cannot measure anything under 100Hz since everything works in the Mega range 10^6. How can I accurately measure frequencies under 100Hz?



Increase your presaler to
(TIMER_CLOCKFREQ/100000)-1  =479
and count with 10µs
or
(TIMER_CLOCKFREQ/10000)-1   =4799
and count with 100us.

Or you just use 32bit timer :eek:
0 Kudos

795 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by exgreyfox on Tue May 21 10:37:42 MST 2013
Ah ok I can change that with the MHZ_PRESCALE
0 Kudos

795 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by exgreyfox on Tue May 21 10:33:16 MST 2013

Quote: R2D2
If you change:
#define MHZ_PRESCALE    (TIMER_CLOCKFREQ/1000000)
to
#define MHZ_PRESCALE    (TIMER_CLOCKFREQ/1000000)-1
you're getting correct values also



It seems that I cannot measure anything under 100Hz since everything works in the Mega range 10^6. How can I accurately measure frequencies under 100Hz?
0 Kudos

795 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by R2D2 on Tue May 21 10:11:54 MST 2013

Quote: ExGreyFox
I see it now, the values are in microseconds, I was just not using the software right. THANK YOU MY GOOD SIR!



If you change:
#define MHZ_PRESCALE    (TIMER_CLOCKFREQ/1000000)
to
#define MHZ_PRESCALE    (TIMER_CLOCKFREQ/1000000)-1
you're getting correct values also
0 Kudos

795 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by R2D2 on Tue May 21 10:11:17 MST 2013

Quote: ExGreyFox
So when I do this, I should be able to see the period of a 100Hz square wave in the CR0 register right?



I would strongly recommend to read timer16_1_capture, that's by far safer while debugging.
0 Kudos

795 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by exgreyfox on Tue May 21 09:53:39 MST 2013

Quote: R2D2
That's problem #1 :)

Run your program, pause it and then read timer16_1_capture. Or add an array to store a few values. Don't step while feeding it with 100Hz.



I see it now, the values are in microseconds, I was just not using the software right. THANK YOU MY GOOD SIR!
0 Kudos

795 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by R2D2 on Tue May 21 09:46:29 MST 2013

Quote: ExGreyFox
As I said in my original post, I do this while I am stepping through the code in debug.


That's problem #1 :)

Run your program, pause it and then read timer16_1_capture. Or add an array to store a few values. Don't step while feeding it with 100Hz.
0 Kudos

795 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by exgreyfox on Tue May 21 09:39:07 MST 2013

Quote: R2D2
:confused:

While the chip is running? You're kidding :)



As I said in my original post, I do this while I am stepping through the code in debug.
0 Kudos

795 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by R2D2 on Tue May 21 09:31:50 MST 2013

Quote: ExGreyFox
Using the peripheral register view.



:confused:

While the chip is running? You're kidding :)
0 Kudos

795 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by exgreyfox on Tue May 21 09:28:14 MST 2013

Quote: R2D2
How are you 'seeing' this values?



Using the peripheral register view.
0 Kudos

795 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by R2D2 on Tue May 21 09:16:32 MST 2013

Quote: ExGreyFox
Here is a sample of the hex values I'm seeing in the CR0 register with a 100Hz 3.3 volt square wave on the CT16B1_CAP0 input.



How are you 'seeing' this values?
0 Kudos

795 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by exgreyfox on Tue May 21 08:52:12 MST 2013
Project file is attached.
0 Kudos

795 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by exgreyfox on Tue May 21 08:22:13 MST 2013

Quote: R2D2
What's confusing me are things like TIMER_MATCH or MHZ_PRESCALE in your code.
So I would suggest to post the project or to start old_fashioned with a working example like #4 of http://knowledgebase.nxp.com/showthread.php?t=2815



That is the same thread I used to formulate my code. Things like MHZ_PRESCALE and TIMER_MATCH are variables that are already part of the timer16.c driver. Nothing I came up with.
0 Kudos

795 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by R2D2 on Tue May 21 08:08:02 MST 2013

Quote: ExGreyFox

I am not sure how the pre-scale value works so maybe that is what is confusing me.



What's confusing me are things like TIMER_MATCH or MHZ_PRESCALE in your code.
So I would suggest to post the project or to start old_fashioned with a working example like #4 of http://knowledgebase.nxp.com/showthread.php?t=2815
0 Kudos