I want to capture time of negative edges on clock signal, and look at the period for multiple clock cycles. At moment I have a 68kHz clock with even mark space generated via PWM on PB0, this works fine, However I want to measure the period of say twenty clock cycles, in order to generate a synchronous sub clock. Using timer0A as capture, but can't get it to work. Project started off as a variant of the timer example, coupled with the LED drive at 1Hz via timer1, which works if I comment out the timer0 code. If I don't the code compiles and runs, but appears to constantly run into the timer0 interrupt. I did not set a value for the timer0A overflow as I left it to default 0xFFFF, which should be adequate given the clock speed. Can someone advise what I am doing wrong or missing. I am new to the Tiva C series, but much more familiar with the MSP430 timers, with which I have coded some complex quite functionality.
Code:
// include file references
#include <stdint.h>
#include <stdbool.h>
#include "inc/hw_ints.h"
#include "inc/hw_memmap.h"
//#include "inc/hw_types.h"
//#include "driverlib/debug.h"
#include "driverlib/gpio.h"
#include "driverlib/interrupt.h"
#include "driverlib/pin_map.h"
#include "driverlib/rom.h"
#include "driverlib/sysctl.h"
#include "driverlib/timer.h"
// constant defines
#define RED_LED GPIO_PIN_1
#define BLUE_LED GPIO_PIN_2
#define GREEN_LED GPIO_PIN_3
// variable defines
unsigned char toggleRED_LED = 0x00; // value for RED LED toggle
unsigned char toggleBLUE_LED = 0x04; // value for BLUE LED toggle
unsigned long timer1APeriod = 0; // value for timer 1A period
unsigned short timer2APeriod = 0;
unsigned short timer2AHalfPeriod = 0;
unsigned short currentClockCapture = 0; // value at negative edge
unsigned short lastClockCapture = 0; // value at last negative edge
//*****************************************************************************
//
// The interrupt handler for the first timer interrupt.
//
//*****************************************************************************
void Timer0IntHandler(void)
{
ROM_TimerIntClear(TIMER0_BASE, TIMER_CAPA_EVENT); // clear the timer interrupt
currentClockCapture = ROM_TimerValueGet(TIMER0_BASE, TIMER_A);
lastClockCapture = currentClockCapture;
}
//*****************************************************************************
//
// The interrupt handler for the second timer interrupt.
//
//*****************************************************************************
void Timer1IntHandler(void)
{
ROM_TimerIntClear(TIMER1_BASE, TIMER_TIMA_TIMEOUT); // clear the timer interrupt
toggleBLUE_LED ^= 0x04;
ROM_GPIOPinWrite(GPIO_PORTF_BASE, BLUE_LED, toggleBLUE_LED);
toggleRED_LED ^= 0x02;
ROM_GPIOPinWrite(GPIO_PORTF_BASE, RED_LED, toggleRED_LED);
}
//*****************************************************************************
//
// This example application demonstrates the use of the timers to generate
// periodic interrupts and drive LEDs
//
//*****************************************************************************
int main(void)
{
ROM_SysCtlClockSet(SYSCTL_SYSDIV_2_5|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHZ|SYSCTL_OSC_MAIN);// sys clock to run at 80 Mhz from PLL with 16MHz crystal
timer1APeriod = SysCtlClockGet() - 1; // 1 Hz - SysCtlClockGet() divided by x, gives count for x Hz period
timer2APeriod = (SysCtlClockGet()/68000) - 1; // 68 kHz
timer2AHalfPeriod = (SysCtlClockGet()/136000) - 1; // 68/2 kHz
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB); // enable GPIO port B
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF); // enable GPIO port F
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0); // enable timer peripheral
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER1); // enable timer peripheral
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER2); // enable timer peripheral
ROM_GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, RED_LED|BLUE_LED|GREEN_LED);// enable the GPIO pins as output for the tri colour LED
ROM_GPIOPinConfigure(GPIO_PB0_T2CCP0 | GPIO_PB6_T0CCP0);// configure for peripherals
ROM_GPIOPinTypeTimer(GPIO_PORTB_BASE, GPIO_PIN_0 | GPIO_PIN_6);// enable the GPIO pins for timer
ROM_TimerConfigure(TIMER0_BASE, (TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_CAP_TIME));// timer0A configured 16 bit time capture
ROM_TimerControlEvent(TIMER0_BASE, TIMER_A, TIMER_EVENT_NEG_EDGE);
ROM_IntEnable(INT_TIMER0A); // interrupt enabled for the timer0A
ROM_TimerIntEnable(TIMER0_BASE, TIMER_CAPA_EVENT); // interrupt setup for the timer0 capture events
ROM_TimerConfigure(TIMER1_BASE, TIMER_CFG_PERIODIC); // timer1A configured 32 bit periodic
ROM_TimerLoadSet(TIMER1_BASE, TIMER_A, timer1APeriod);
ROM_IntEnable(INT_TIMER1A); // interrupt enabled for the timer0A
ROM_TimerIntEnable(TIMER1_BASE, TIMER_TIMA_TIMEOUT); // interrupt setup for the timer0A timeouts
ROM_TimerConfigure(TIMER2_BASE, TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_PWM);// timer2A configured 16 bit PWM
ROM_TimerLoadSet(TIMER2_BASE, TIMER_A, timer2APeriod);
ROM_TimerMatchSet(TIMER2_BASE, TIMER_A, timer2AHalfPeriod);
ROM_IntMasterEnable(); // enable processor interrupts
ROM_TimerIntClear(TIMER0_BASE, TIMER_CAPA_EVENT);
ROM_TimerEnable(TIMER0_BASE, TIMER_A); // enable the timer0A
ROM_TimerEnable(TIMER1_BASE, TIMER_A); // enable the timer1A
ROM_TimerEnable(TIMER2_BASE, TIMER_A); // enable the timer2A
while(1); // loop forever while the timers run
}
OK comments everywhere, just helps me resolve code issues when switching from one project to another, micro to another, and long periods in between sorting hardware out
dBell