Other Parts Discussed in Thread: TM4C1294NCPDT
Hi,
I am using eval board and CCS and written application to measure frequency on timer CCP0 (timer configured in capture edge time, count-up, detect positive edge).
Frequency is being generated using PWM of board with 50% duty cycle on pin PG0 and is physically connected to T0CCP0 pin (PD0).
Code is measuring frequency consistently for different PWM frequencies (>32Hz due to limitation of 24 bit timer).
However, for all measurement, i found that there is error of 65 count in each case. As such for lower frequency, error is small, but for higher frequency, error becomes considerable.
I am not sure if the source of this error of 65 count is PWM or timer. Please let me know what is that i am missing.
My code is as below:
#include <stdint.h>
#include <stdbool.h>
#include "inc/tm4c1294ncpdt.h"
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "driverlib/sysctl.h"
#include "driverlib/fpu.h"
#include "driverlib/gpio.h"
#include "driverlib/debug.h"
#include "driverlib/pwm.h"
#include "driverlib/pin_map.h"
#include "inc/hw_gpio.h"
#include "driverlib/interrupt.h"
#include "driverlib/timer.h"
#define PWM_FREQUENCY 50
static volatile uint32_t lastValue=0;
static volatile float frequency;
int main(void)
{
volatile uint32_t ui32Load; // PWM period
volatile uint32_t ui32PWMClock; // PWM clock frequency
volatile uint32_t ui32SysClkFreq; // Value returned by SysClockFreqSet()
ui32SysClkFreq = SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480), 120000000);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOG); //Port G enabled since PWM4 is on PG0.
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD); //Port D enabled since T0CCP0 is on PD0.
SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM0); //PWM module 0 enabled.
SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0); //Timer0 enabled.
SysCtlDelay(3); //delay of 3 cycle before accessing PWM registers.
PWMClockSet(PWM0_BASE,PWM_SYSCLK_DIV_64); //PWM cloack = sysclk/64
GPIOPinConfigure(GPIO_PG0_M0PWM4); //GPIO pin configuration for PWM
GPIOPinTypePWM(GPIO_PORTG_BASE, GPIO_PIN_0); //GPIO pin configuration for PWM
GPIOPinConfigure(GPIO_PD0_T0CCP0); //GPIO pin configuration for timer capture
GPIOPinTypeTimer(GPIO_PORTD_BASE, GPIO_PIN_0); //GPIO pin configuration for timer capture
TimerConfigure(TIMER0_BASE, (TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_CAP_TIME_UP)); //Config timer A of for capture mode in time-up
TimerControlEvent(TIMER0_BASE, TIMER_A, TIMER_EVENT_POS_EDGE); //Config timer A to capture positive edge
TimerControlStall(TIMER0_BASE, TIMER_A, true); //Timer stalls while CPU is in debug mode
TimerPrescaleSet(TIMER0_BASE, TIMER_A, 255); //Load timer pre-scaler with max value
TimerLoadSet(TIMER0_BASE, TIMER_A, 65535); //Load timer with max value
IntEnable(INT_TIMER0A);
TimerIntEnable(TIMER0_BASE, TIMER_CAPA_EVENT);
IntMasterEnable();
ui32PWMClock = ui32SysClkFreq / 64; // 120MHz/64
ui32Load = (ui32PWMClock / PWM_FREQUENCY) - 1; // 1875000/PWM_FREQUENCY
PWMGenConfigure(PWM0_BASE, PWM_GEN_2, PWM_GEN_MODE_DOWN);
PWMGenPeriodSet(PWM0_BASE, PWM_GEN_2, ui32Load);
PWMPulseWidthSet(PWM0_BASE, PWM_OUT_4, ui32Load/2);
PWMOutputState(PWM0_BASE, PWM_OUT_4_BIT, true);
PWMGenEnable(PWM0_BASE, PWM_GEN_2);
TimerEnable(TIMER0_BASE, TIMER_A); //Timer enable
while(1)
{
}
}
void Timer0IntHandler(void)
{
uint32_t newValue, period;
// Clear the timer interrupt
TimerIntClear(TIMER0_BASE, TIMER_CAPA_EVENT);
newValue = TimerValueGet(TIMER0_BASE, TIMER_A);
if(newValue <= lastValue)
period = (16777215-lastValue) + newValue;
else
period = newValue - lastValue;
frequency = 120000000.0f / (float)period ;
lastValue = newValue;
}