LPC2148 Capture Time 0 incorrect value is captured

Started by "rav...@yahoo.in [lpc2000]" May 26, 2014
Hi everyone i am new to embedded world and i have problem regarding capture timer value :
uC: LPC2148
CClk: 60 MHz.
Pclk : 60 MHz.
Compiler : Keil uvision 4
I have connected Pin 0.03 (Match 0.0 (Timer 0)) to Pin P0.10 (Capture 1.0 (Timer 1)).

From program code given below :

timer 0 toggling Pin 0.03 on MR0 and same is captured at P0.10 . But the value of capture is not correct. Capture value = 5198 usec is received on terminal program on windows 8.
Note : the value of capture is sent through UART 1 @ baud rate 9600, 8 bit no parity mode.

Peripherals used :
Timer 0 to toggle pin P0.03 on Match (100u Sec).
Timer 1 to Capture the time value on CAP Pin P0.10 (Capture 1.0 (Timer 1))
UART 1 to transmit Capture value via serial port

The following is the code :

/********************************************************************************************************
Project : Timer 0 used to make pin 0.03 toggle on match

CCLK : 60MHz
PCLK : 60MHz

*********************************************************************************************************/
#include

#define prescale 6000 //prescale value tick timer at 100uS
#define delay 2 // 200 uSec delay

void __irq ISR_TIMER0(void); //protoype funtion for ISR of TIMER 0

//function to initialise the timer 0

void INIT_TIMER0(void)
{
T0CTCR = 0x00; //TIMER mode
T0PR = prescale - 1 ; //storing prescale reg with prescale value
T0MR0 = delay-1;
T0MCR = 0x03; // MATCH CONTROL REG SET TO INTERRUPT ON MATCH AND RESET ON MATCH
T0EMR = 0x00000030; // Toogle external MATCH PINS MATx.0
VICIntEnable = 0X00000030; // ENABLE TIMER 0 INTERRUPT
VICIntSelect = 0X00000000; // SETTING ALL THE PERIPHERALS INTERRUPTS AS IRQ
VICVectAddr0 = (unsigned) ISR_TIMER0;
VICVectCntl0 = 0X20 | 4;
T0TCR = 0X01; // start TIMER
}

void __irq ISR_TIMER0(void)
{
unsigned int TIR_REG;
TIR_REG = T0IR;
T0IR = TIR_REG;
VICVectAddr = 0x0;
}
// ***************************end of timer 0.c

/************************************************************************************************************************

TIMER1 USED FOR CAPTURING VALUE

PCLK = 60MHz
CCLK = 60MHz
************************************************************************************************************************/
#include
#include
#include "uart1.h"
//#include "timer1.h"
#define prescale 60 // prescale value to accuracy of 1uSec delay
unsigned char buffer[40]; // buffer for sending data serially using SPRINTF
void __irq ISR_TIMER1(void);

void INIT_TIMER1(void) // function to initialise the timer 1
{

T1CTCR = 0X00; // TIMER mode
T1PR = prescale - 1; // storing prescale reg with prescale value
T1CCR = 0x00000007; // TIMER 1 Ch 0 capture & Interrupt on both edge
VICIntEnable = 0X00000030; // ENABLE TIMER 1 & 0 INTERRUPT
VICIntSelect = 0X00000000; // SETTING ALL THE PERIPHERALS INTERRUPTS AS IRQ
VICVectAddr1 = (unsigned) ISR_TIMER1;
VICVectCntl1 = 0X20 | 5;

T1TCR = 0X02; // RESET TIMER
T1TCR = 0X01; // START TIMER
}

void __irq ISR_TIMER1(void)
{
unsigned int TIR_REG;
unsigned int capture =0 ;

TIR_REG = T1IR;
T1TC = 0; //INITIALISE TIMER REGISTER
IO1SET = (1<<16); //Indication for isr for timer 1
capture = T1CR0;
sprintf(buffer,"n%d",(unsigned int)capture); //sending data serially to uart
UART1_SendStr(buffer);

IO1CLR=(1<<16) ;
T1IR = TIR_REG; //clear all interrupts
VICVectAddr = 0x0; //write dummy to VIC to end interrupt
}
// end of timer1.c file

**************************************************************************************************************************/
#include
//#include "uart1.h"

//***************************************uart clock setup************************************************************************
#define Fosc 12000000
#define Fcclk (Fosc * 5)
#define Fcco (Fcclk * 4)
#define Fpclk (Fcclk / 1) * 1 //CCLK=PCLK
#define UART_BPS 9600 //Set Baud Rate here
void Init_UART1(void) //This function setups UART1
{
unsigned int Baud16;
U1LCR = 0x83; // DLAB = 1
Baud16 = (Fpclk / 16) / UART_BPS;
U1DLM = Baud16 / 256;
U1DLL = Baud16 % 256;
U1LCR = 0x03;
}

void UART1_SendByte(unsigned char data) //A function to send a byte on UART1
{
U1THR = data; // add 48 to print ascii character
while( (U1LSR&0x40)==0 );

}
void UART1_SendStr(const unsigned char *str) //A function to send a string on UART1
{
while(1)
{
if( *str == ' ' ) break;
UART1_SendByte(*str++);
}
}

/************************************************************************************************************************

MAIN.c

To check the accuracy of the capture of timer 1. The MAT x.0 pin is toggled at every match on MR0 of timer 0.
And send captured value to UART 1

PCLK = 60MHz
CCLK = 60MHz
************************************************************************************************************************/
#include
#include
#include "uart1.h"
#include "timer0.h"
#include "timer1.h"
const unsigned char SEND_STRING[] = "n LPC 2148 IR timing values";
volatile unsigned int period = 0;
volatile unsigned int duty = 0;

int main()
{
//select pin functions, ALL PINS AS GPIO
PINSEL0=0x00250080; //SELECTING P0.3 as MAT0.0 , P0.10 as CAP1.0 & UART 1 Rx and Tx pins
PINSEL1=0x00000000;
PINSEL2=0x00000000;

//PIN DIRECTIONS OF GPIO PINS
IO1DIR = ( (1<<16) | (1<<17) | (1<<18) | (1<<19)); //PINS P1.16 TO P1.19 AS OUTPUTS

Init_UART1(); //Function to initialize UART 1
UART1_SendStr(SEND_STRING);

INIT_TIMER0(); //Function to initialize TIMER 0
INIT_TIMER1(); //Function to initialize TIMER 1

while(1)
{
}

}
// end of main.c

Posted by: r...@yahoo.in


An Engineer's Guide to the LPC2100 Series

Hello Ravi,

You are measuring the time it takes to send a string.
You use sprintf and send the string one character at a time inside the isr
and that takes much longer than the next interrupt to arrive. When the isr
finishes sending and runs again 5 thousand usec have passed.
You need to store the value in a global variable or buffer or whatever and
send it thru the uart outside the isr, in your main loop. You can also set
the uart for a higher baud rate.

Regards,
Bernardo Marques
Em 26/05/2014 21:10, "r...@yahoo.in [lpc2000]" <
l...> escreveu:

> Hi everyone i am new to embedded world and i have problem regarding
> capture timer value :
> uC: LPC2148
> CClk: 60 MHz.
> Pclk : 60 MHz.
> Compiler : Keil uvision 4
> I have connected Pin 0.03 (Match 0.0 (Timer 0)) to Pin P0.10 (Capture 1.0
> (Timer 1)).
>
> From program code given below :
>
> timer 0 toggling Pin 0.03 on MR0 and same is captured at P0.10 . But the
> value of capture is not correct. Capture value = 5198 usec is received on
> terminal program on windows 8.
> Note : the value of capture is sent through UART 1 @ baud rate 9600, 8 bit
> no parity mode.
>
> Peripherals used :
> Timer 0 to toggle pin P0.03 on Match (100u Sec).
> Timer 1 to Capture the time value on CAP Pin P0.10 (Capture 1.0 (Timer 1))
> UART 1 to transmit Capture value via serial port
>
> The following is the code :
> /********************************************************************************************************
> Project : Timer 0 used to make pin 0.03 toggle on match
>
> CCLK : 60MHz
> PCLK : 60MHz
> *********************************************************************************************************/
> #include #define prescale 6000 //prescale value tick timer at 100uS
> #define delay 2 // 200 uSec delay
>
> void __irq ISR_TIMER0(void); //protoype funtion for ISR of TIMER 0
>
> //function to initialise the timer 0
>
> void INIT_TIMER0(void)
> {
> T0CTCR = 0x00; //TIMER mode
> T0PR = prescale - 1 ; //storing prescale reg with prescale value
> T0MR0 = delay-1;
> T0MCR = 0x03; // MATCH CONTROL REG SET TO INTERRUPT ON MATCH AND RESET ON
> MATCH
> T0EMR = 0x00000030; // Toogle external MATCH PINS MATx.0
> VICIntEnable = 0X00000030; // ENABLE TIMER 0 INTERRUPT
> VICIntSelect = 0X00000000; // SETTING ALL THE PERIPHERALS INTERRUPTS AS IRQ
> VICVectAddr0 = (unsigned) ISR_TIMER0;
> VICVectCntl0 = 0X20 | 4;
> T0TCR = 0X01; // start TIMER
> }
>
> void __irq ISR_TIMER0(void)
> {
> unsigned int TIR_REG;
> TIR_REG = T0IR;
> T0IR = TIR_REG;
> VICVectAddr = 0x0;
> }
> // ***************************end of timer 0.c
> /************************************************************************************************************************
>
> TIMER1 USED FOR CAPTURING VALUE
>
> PCLK = 60MHz
> CCLK = 60MHz
> ************************************************************************************************************************/
> #include
> #include
> #include "uart1.h"
> //#include "timer1.h"
> #define prescale 60 // prescale value to accuracy of 1uSec delay
> unsigned char buffer[40]; // buffer for sending data serially using SPRINTF
> void __irq ISR_TIMER1(void);
>
> void INIT_TIMER1(void) // function to initialise the timer 1
> {
>
> T1CTCR = 0X00; // TIMER mode
> T1PR = prescale - 1; // storing prescale reg with prescale value
> T1CCR = 0x00000007; // TIMER 1 Ch 0 capture & Interrupt on both edge
> VICIntEnable = 0X00000030; // ENABLE TIMER 1 & 0 INTERRUPT
> VICIntSelect = 0X00000000; // SETTING ALL THE PERIPHERALS INTERRUPTS AS IRQ
> VICVectAddr1 = (unsigned) ISR_TIMER1;
> VICVectCntl1 = 0X20 | 5;
>
> T1TCR = 0X02; // RESET TIMER
> T1TCR = 0X01; // START TIMER
> }
>
> void __irq ISR_TIMER1(void)
> {
> unsigned int TIR_REG;
> unsigned int capture =0 ;
>
> TIR_REG = T1IR;
> T1TC = 0; //INITIALISE TIMER REGISTER
> IO1SET = (1<<16); //Indication for isr for timer 1
> capture = T1CR0;
> sprintf(buffer,"n%d",(unsigned int)capture); //sending data serially to
> uart
> UART1_SendStr(buffer);
>
> IO1CLR=(1<<16) ;
> T1IR = TIR_REG; //clear all interrupts
> VICVectAddr = 0x0; //write dummy to VIC to end interrupt
> }
> // end of timer1.c file
> **************************************************************************************************************************/
> #include
> //#include "uart1.h"
>
> //***************************************uart clock
> setup************************************************************************
> #define Fosc 12000000
> #define Fcclk (Fosc * 5)
> #define Fcco (Fcclk * 4)
> #define Fpclk (Fcclk / 1) * 1 //CCLK=PCLK
> #define UART_BPS 9600 //Set Baud Rate here
>
> void Init_UART1(void) //This function setups UART1
> {
> unsigned int Baud16;
> U1LCR = 0x83; // DLAB = 1
> Baud16 = (Fpclk / 16) / UART_BPS;
> U1DLM = Baud16 / 256;
> U1DLL = Baud16 % 256;
> U1LCR = 0x03;
> }
> void UART1_SendByte(unsigned char data) //A function to send a byte on
> UART1
> {
> U1THR = data; // add 48 to print ascii character
> while( (U1LSR&0x40)==0 );
>
> }
>
> void UART1_SendStr(const unsigned char *str) //A function to send a string
> on UART1
> {
> while(1)
> {
> if( *str == ' ' ) break;
> UART1_SendByte(*str++);
> }
> }
> /************************************************************************************************************************
>
> MAIN.c
>
> To check the accuracy of the capture of timer 1. The MAT x.0 pin is
> toggled at every match on MR0 of timer 0.
> And send captured value to UART 1
>
> PCLK = 60MHz
> CCLK = 60MHz
>
> ************************************************************************************************************************/
> #include
> #include
> #include "uart1.h"
> #include "timer0.h"
> #include "timer1.h"
>
> const unsigned char SEND_STRING[] = "n LPC 2148 IR timing values";
> volatile unsigned int period = 0;
> volatile unsigned int duty = 0;
>
> int main()
> {
> //select pin functions, ALL PINS AS GPIO
> PINSEL0=0x00250080; //SELECTING P0.3 as MAT0.0 , P0.10 as CAP1.0 & UART 1
> Rx and Tx pins
> PINSEL1=0x00000000;
> PINSEL2=0x00000000;
>
> //PIN DIRECTIONS OF GPIO PINS
> IO1DIR = ( (1<<16) | (1<<17) | (1<<18) | (1<<19)); //PINS P1.16 TO P1.19
> AS OUTPUTS
> Init_UART1(); //Function to initialize UART 1
> UART1_SendStr(SEND_STRING);
>
> INIT_TIMER0(); //Function to initialize TIMER 0
> INIT_TIMER1(); //Function to initialize TIMER 1
> while(1)
> {
> }
>
> }
> // end of main.c
>
>
Thanks Bernardo

It solved my problem.

Regards
Ravi

Posted by: r...@yahoo.in