Hi,
I am trying to read the length of a pulse I providing to TM4C. I am having a lot of trouble and I am not sure how to proceed, suggestions would be very helpful. I think I might have a couple issues, If I am connected to ground there is no problem and will print out end = 0, start = zero and length = zero as expected. However, when I connect to my PWM (not the one in the code but one generated by another source) I get random values. I am not sure what is going on or how to fix it. The frequency of the signal I will eventually want to measure is anywhere from 3kHz to 5 kHz. Additionally, I think there might be a problem the order of how its reading my pulses - meaning it might be reading falling and then the rising edge, which inst a problem now as I am using a 50% PWM as my test signal but will be a problem in the future - so if anyone has any suggestions. I was trying to figure out a way to have my clock start at a rising edge but I am having trouble trying to figure out how to do that.
I think that I might be using my interrupts incorrectly, I am confused as how exactly to use them, what I attempted to do was tie PD0 and PD1 together with my incoming pulse, then when a rising edge is detected, timer a will call an interrupt which saves that value to start, then when the negative edge is reached timer b will call an interrupt which saves timer value to end.
Any help would be appreciated. - I kept all code which controls peripherals on the board in the code I post because I am not sure if there may be any interference or something along those lines.
#include <stdint.h> #include <stdbool.h> #include <math.h> #include "inc/hw_ints.h" #include "inc/hw_memmap.h" #include "inc/hw_types.h" #include "inc/hw_gpio.h" #include "inc/hw_pwm.h" #include "driverlib/debug.h" #include "driverlib/fpu.h" #include "driverlib/gpio.h" #include "driverlib/pwm.h" #include "driverlib/interrupt.h" #include "driverlib/pin_map.h" #include "driverlib/rom.h" #include "driverlib/rom_map.h" #include "driverlib/sysctl.h" #include "driverlib/timer.h" #include "driverlib/uart.h" #include "utils/uartstdio.h" // Global variable declaration for clock uint32_t g_ui32SysClock; // Global variable for Pulse uint32_t start = 0, end = 0, length = 0; // Function Prototypes void configureUART (void); void Pulse_Length (void); void DummyDelay(uint32_t Count); void configurePWM(void); void FallingEdge (void); void RisingEdge (void); //***********************************************************************************************************************// // This section contains UART communication dependencies - this is used as a check for the code written but will most // // be commented out of the final code - it is going to remain as a comment and not deleted to allow editor of program to // // utilize UART to provide checks of values and functions // //***********************************************************************************************************************// void configureUART(void) { // // Enable GPIO and UART 0 // SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA); SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0); // // Configure UART Pins for UART MODE // GPIOPinConfigure(GPIO_PA0_U0RX); GPIOPinConfigure(GPIO_PA1_U0TX); GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1); //UARTClockSourceSet(UART0_BASE, UART_CLOCK_SYSTEM); // // Initialize the UART for console I/O. // UARTStdioConfig(0, 115200, g_ui32SysClock); } //***********************************************************************************************************************// // This section will set up the timer to measure the length of the pulse into the controller. I will attempt to achieve // // by setting PD0 and PD1 as timer pins. These pins will both be connected to the comparator. PD0 will "look for" the // // rising-edge while PD1 will "look for" the falling-edge. Each will capture the timer value to start and end variables // // the difference between the two will be the pulse length. //***********************************************************************************************************************// void Pulse_Length (void) { // // Enable GPIO and Timer 0 // SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD); SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0); // //Configure GPIO Timer Pins in // GPIOPinConfigure(GPIO_PD0_T0CCP0); GPIOPinConfigure(GPIO_PD1_T0CCP1); GPIOPinTypeTimer(GPIO_PORTD_BASE, GPIO_PIN_0 | GPIO_PIN_1); // // Initialize timer A and B to count up in edge time mode // TimerConfigure(TIMER0_BASE, (TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_CAP_TIME_UP | TIMER_CFG_B_CAP_TIME_UP)); // //Timer Load Value // TimerLoadSet(TIMER0_BASE, TIMER_BOTH, g_ui32SysClock); // //Synchronize both timers // TimerSynchronize(TIMER0_BASE, TIMER_0A_SYNC | TIMER_0B_SYNC); // // Timer A records positive edge time and Timer B records negative edge time // TimerControlEvent(TIMER0_BASE, TIMER_A, TIMER_EVENT_POS_EDGE); TimerControlEvent(TIMER0_BASE, TIMER_B, TIMER_EVENT_NEG_EDGE); // Registers a interrupt function to be called when timer as hits positive edge trig int IntRegister(INT_TIMER0A, RisingEdge); // Makes sure the interrupt is cleared TimerIntClear(TIMER0_BASE, TIMER_CAPA_EVENT); // Enable the indicated timer interrupt source. TimerIntEnable(TIMER0_BASE, TIMER_CAPA_EVENT); // The specified interrupt is enabled in the interrupt controller. IntEnable(INT_TIMER0A); // Registers a interrupt function to be called when timer as hits neg edge trig int IntRegister(INT_TIMER0B, FallingEdge); // Makes sure the interrupt is cleared TimerIntClear(TIMER0_BASE, TIMER_CAPB_EVENT); // Enable the indicated timer interrupt source. TimerIntEnable(TIMER0_BASE, TIMER_CAPB_EVENT); // The specified interrupt is enabled in the interrupt controller. IntEnable(INT_TIMER0B); } void RisingEdge (void) { TimerIntClear(TIMER0_BASE, TIMER_CAPA_EVENT); start = TimerValueGet(TIMER0_BASE, TIMER_A); } void FallingEdge (void) { TimerIntClear(TIMER0_BASE, TIMER_CAPB_EVENT); end = TimerValueGet(TIMER0_BASE, TIMER_B); } //***********************************************************************************************************************// //***********************************************************************************************************************// //***********************************************************************************************************************// // DummyDelay() will only be used when debugging void DummyDelay(uint32_t Count) { volatile uint32_t x; for (x = 0;x<Count;x++) { x = x | 0; } } //***********************************************************************************************************************// // This section contains the PWM function needed create the PWM function // //***********************************************************************************************************************// void configurePWM(void) { uint32_t Ticks; Ticks = 50; //Number_Ticks_Freq(); // // Enable the GPIO Peripheral used by PWM (PF0, PF1) // SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF); // // Enable PWM0 // SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM0); // //Dividing the clock for PWM use - Will use one for now // SysCtlPWMClockSet(SYSCTL_PWMDIV_1); // //Unlocking the pins // HWREG(GPIO_PORTF_BASE + GPIO_O_LOCK) = GPIO_LOCK_KEY; HWREG(GPIO_PORTF_BASE + GPIO_O_CR) = 0x01; // // Configure GPIO pin for PWM // GPIOPinConfigure(GPIO_PF0_M0PWM0); GPIOPinConfigure(GPIO_PF1_M0PWM1); GPIOPinTypePWM(GPIO_PORTF_BASE, GPIO_PIN_0 | GPIO_PIN_1); // // Configure PWM // PWMGenConfigure(PWM0_BASE, PWM_GEN_0, PWM_GEN_MODE_DOWN | PWM_GEN_MODE_NO_SYNC); // //Setting PWM Period // PWMGenPeriodSet(PWM0_BASE, PWM_GEN_0, ceil(Ticks)); // //Setting duty cycle // PWMPulseWidthSet(PWM0_BASE, PWM_OUT_0 , ceil(Ticks/2)); PWMPulseWidthSet(PWM0_BASE, PWM_OUT_1 , ceil(Ticks/2)); // // Enable PWM // PWMGenEnable(PWM0_BASE, PWM_GEN_0); PWMOutputInvert(PWM0_BASE, PWM_OUT_1_BIT, true); PWMOutputState(PWM0_BASE, PWM_OUT_0_BIT | PWM_OUT_1_BIT, true); } int main(void) { g_ui32SysClock = MAP_SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480), 120000000); configurePWM(); configureUART(); IntMasterEnable(); // Enable the processor to respond to interrupts. Pulse_Length(); TimerEnable(TIMER0_BASE, TIMER_BOTH); while(1) { length = end - start; UARTprintf("\nSTART = %d\n", start); UARTprintf("\nEND = %d\n", end); UARTprintf("\nLENGTH = %d\n", length); } }