Part Number:EK-TM4C1294XL
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.
Any help would be appreciated.
#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); //ROM emsa7
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 which can be used to find the inductance --> Math section //
//***********************************************************************************************************************//
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 //
// Note: Any changes to the SysCtlPWMClockSet(SYSCTL_PWMDIV_1); will require changes in the above math section!!!!!!!!! //
//***********************************************************************************************************************//
void
configurePWM(void)
{
uint32_t Ticks;
Ticks = 50; //Number_Ticks_Freq();
//
// Enable the GPIO Peripheral used by PWM (PF0, and eventually 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);
}
}