I config the a WTIMER as two split timer for event capture. The two signal input are nearly same. But one of the two timers is always later to match the same match value. And the load value of the two timer is the same. All I've figured out is that one of the timer work normally while the other one went wrong when the value is close to the match value. And I wonder why. Here's the code. I am using lm4f120.
#include <stdint.h>
#include <stdbool.h>
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "driverlib/gpio.h"
#include "driverlib/sysctl.h"
#include "driverlib/pin_map.h"
#include "utils/uartstdio.h"
#include "driverlib/pwm.h"
#include "driverlib/timer.h"
#include "inc/hw_ints.h"
#include "driverlib/interrupt.h"
void right(void)
{
TimerIntClear(WTIMER1_BASE, TIMER_CAPA_MATCH);//clear the interrupt
GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_7, 0);
GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_6, 0);
UARTprintf("\nhello world, left\n");
}
void left(void)
{
TimerIntClear(WTIMER1_BASE, TIMER_CAPB_MATCH);//clear the interrupt
GPIOPinWrite(GPIO_PORTE_BASE, GPIO_PIN_5, 0);
GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_5, 0);
UARTprintf("\nhello world, right\n");
}
//*****************************************************************************
//To init the motor's pins, start to output after the func been called
//*****************************************************************************
void ACMotorInit(void)
{
//Set the GPIOs
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
GPIOPinTypeGPIOOutput(GPIO_PORTE_BASE, GPIO_PIN_5);
GPIOPinTypeGPIOOutput(GPIO_PORTA_BASE, GPIO_PIN_5);
GPIOPinTypeGPIOOutput(GPIO_PORTA_BASE, GPIO_PIN_6);
GPIOPinTypeGPIOOutput(GPIO_PORTA_BASE, GPIO_PIN_7);
//The pwm pin
//Config PB3 as T3CCP1
GPIOPinConfigure(GPIO_PB3_T3CCP1);
GPIOPinTypeTimer(GPIO_PORTB_BASE, GPIO_PIN_3);
//Config PB2 as T3CCP0
GPIOPinConfigure(GPIO_PB2_T3CCP0);
GPIOPinTypeTimer(GPIO_PORTB_BASE, GPIO_PIN_2);
//Config the timer
SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER3);
TimerConfigure(TIMER3_BASE, TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_PWM | TIMER_CFG_B_PWM);
TimerLoadSet(TIMER3_BASE, TIMER_B, 60000);
TimerMatchSet(TIMER3_BASE, TIMER_B, 30000);
TimerLoadSet(TIMER3_BASE, TIMER_A, 60000);
TimerMatchSet(TIMER3_BASE, TIMER_A, 30000);
TimerEnable(TIMER3_BASE, TIMER_B);
TimerEnable(TIMER3_BASE, TIMER_A);
//Timer counter
//WTIMER1 PC6 PC7
SysCtlPeripheralEnable(SYSCTL_PERIPH_WTIMER1);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);
//Config the timer
TimerConfigure(WTIMER1_BASE, TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_CAP_COUNT
| TIMER_CFG_B_CAP_COUNT);
//Config C6 as WT1CCP0
GPIOPinConfigure(GPIO_PC6_WT1CCP0);
GPIOPinTypeTimer(GPIO_PORTC_BASE, GPIO_PIN_6);
//Config C7 as WT1CCP1
GPIOPinConfigure(GPIO_PC7_WT1CCP1);
GPIOPinTypeTimer(GPIO_PORTC_BASE, GPIO_PIN_7);
//Event ctl
TimerControlEvent(WTIMER1_BASE, TIMER_A, TIMER_EVENT_POS_EDGE);
TimerControlEvent(WTIMER1_BASE, TIMER_B, TIMER_EVENT_POS_EDGE);
//Load set
//TimerLoadSet(WTIMER1_BASE, TIMER_A, 0);
//TimerLoadSet(WTIMER1_BASE, TIMER_B, 0);
//Match set
TimerMatchSet(WTIMER1_BASE, TIMER_A, 1000);
TimerMatchSet(WTIMER1_BASE, TIMER_B, 1000);
//Timer int enable
TimerIntRegister(WTIMER1_BASE, TIMER_A, right);
TimerIntRegister(WTIMER1_BASE, TIMER_B, left);
TimerIntEnable(WTIMER1_BASE, TIMER_CAPA_MATCH | TIMER_CAPB_MATCH);
IntEnable(INT_WTIMER1A);
IntEnable(INT_WTIMER1B);
IntMasterEnable();
//Timer enable
//TimerEnable(WTIMER1_BASE, TIMER_A);
//TimerEnable(WTIMER1_BASE, TIMER_B);
}
//*****************************************************************************
//The left wheel to rotate exact distance
//the uint of the distance is the number of pulse of the photogate
//dir=1 to go ahead
//TimerB->Left
//*****************************************************************************
void LeftRotate(uint8_t dir, uint32_t distance)
{
GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_7, dir?(~GPIO_PIN_7):GPIO_PIN_7);
GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_6, dir?GPIO_PIN_6:(~GPIO_PIN_6));
TimerLoadSet(WTIMER1_BASE, TIMER_B, distance+1000);
TimerEnable(WTIMER1_BASE, TIMER_B);
}
//*****************************************************************************
//The right wheel to rotate exact distance
//the uint of the distance is the number of pulse of the photogate
//dir=1 to go ahead
//TimerA->right
//*****************************************************************************
void RightRotate(uint8_t dir, uint32_t distance)
{
GPIOPinWrite(GPIO_PORTE_BASE, GPIO_PIN_5, dir?GPIO_PIN_5:~GPIO_PIN_5);
GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_5, dir?~GPIO_PIN_5:GPIO_PIN_5);
TimerLoadSet(WTIMER1_BASE, TIMER_A, distance+1000);
TimerEnable(WTIMER1_BASE, TIMER_A);
}
//*****************************************************************************
//To adjust the rotate speed
//the var speed ranges from 0 to 100
//*****************************************************************************
void SpeedAdj(uint32_t speed)
{
TimerMatchSet(TIMER3_BASE, TIMER_B, speed*100);
}