Вы находитесь на странице: 1из 5

#include <stdint.

h>
#include <stdio.h>
#include <stdbool.h>
#include <stdint.h>
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include

"inc/hw_memmap.h"
"inc/hw_gpio.h"
"inc/hw_pwm.h"
"inc/hw_sysctl.h"
"inc/hw_types.h"
"inc/hw_timer.h"
"inc/hw_nvic.h"
"bitdefs.h"
"driverlib/sysctl.h"
"driverlib/gpio.h"
"driverlib/interrupt.h"
"utils/uartstdio.h"
"ES_Port.h"
"termio.h"
"DriveMotorService.h"

#include
#include
#include
#include
#include

"ES_Configure.h"
"ES_Timers.h"
"ES_Framework.h"
"ES_Types.h"
"ES_Events.h"

#define
#define
#define
#define

PERIOD_TOLLERANCE .4
RPM_TOLERANCE 60
UpdateTime 100
MAX_RPM 75

// Filtering parameter
// Filtering parameter
// Time is MS for when wheels are stopped
// MAX_RPM parater for filtering

static uint32_t PeriodToRPM = 24000000;


counts/rev)
static uint32_t EnPeriodL;
edges
static uint32_t EnPeriodR;
edges
static uint32_t LastCaptureL;
static uint32_t LastCaptureR;
static int RPMLeft;
Wheel
static int RPMRight;
static int LeftEnCounts = 0;
Ticks
static int RightEnCounts = 0;
Ticks

// (60 s/min)*(40000000 Hz) / (100


// Saves time between
// Saves time between
// Saves time of last edge
// Saves time of last edge
// RPM for Left
// RPM for Right Wheel
// Count for Left Wheel Encoder
// Count for Right Wheel Encoder

static uint8_t MyPriority;


//Need to initialize another timer and port for right encoder
bool InitInputCaptureEncoders ( uint8_t Priority ){
MyPriority = Priority;
// start by enabling the clock to the timer (Wide Timer 0)
HWREG(SYSCTL_RCGCWTIMER) |= SYSCTL_RCGCWTIMER_R0;
// enable the clock to Port C
HWREG(SYSCTL_RCGCGPIO) |= SYSCTL_RCGCGPIO_R2;
// since we added this Port C clock init, we can immediately start
// into configuring the timer, no need for further delay
// make sure that timer (Timer A&B) is disabled before configuring
HWREG(WTIMER0_BASE+TIMER_O_CTL) &= ~TIMER_CTL_TAEN;

HWREG(WTIMER0_BASE+TIMER_O_CTL) &= ~TIMER_CTL_TBEN;


// set it up in 32bit wide (individual, not concatenated) mode
// the constant name derives from the 16/32 bit timer, but this is a 32/64
// bit timer so we are setting the 32bit mode
HWREG(WTIMER0_BASE+TIMER_O_CFG) = TIMER_CFG_16_BIT;
// we want to use the full 32 bit count, so initialize the Interval Load
// register to 0xffff.ffff (its default value :-)
HWREG(WTIMER0_BASE+TIMER_O_TAILR) = 0xffffffff;
HWREG(WTIMER0_BASE+TIMER_O_TBILR) = 0xffffffff;
// set up timer A in capture mode (TAMR=3, TAAMS = 0),
// for edge time (TACMR = 1) and up-counting (TACDIR = 1)
HWREG(WTIMER0_BASE+TIMER_O_TAMR) =
(HWREG(WTIMER0_BASE+TIMER_O_TAMR) & ~TIMER_TAMR_TAAMS) |
(TIMER_TAMR_TACDIR | TIMER_TAMR_TACMR | TIMER_TAMR_TAMR_CAP);
// set up timer B in capture mode (TAMR=3, TAAMS = 0),
// for edge time (TACMR = 1) and up-counting (TACDIR = 1)
HWREG(WTIMER0_BASE+TIMER_O_TBMR) =
(HWREG(WTIMER0_BASE+TIMER_O_TBMR) & ~TIMER_TBMR_TBAMS) |
(TIMER_TBMR_TBCDIR | TIMER_TBMR_TBCMR | TIMER_TBMR_TBMR_CAP);
// To set the event to rising edge, we need to modify the TAEVENT/TBEVENT

bits

// in GPTMCTL. Rising edge = 00, so we clear the TAEVENT/TBEVENT bits


HWREG(WTIMER0_BASE+TIMER_O_CTL) &= ~TIMER_CTL_TAEVENT_M;
HWREG(WTIMER0_BASE+TIMER_O_CTL) &= ~TIMER_CTL_TBEVENT_M;
// Now Set up the port to do the capture (clock was enabled earlier)
// start by setting the alternate function for Port C bit 4 (WT0CCP0) for
Timer 0A
// and set the alternate function for Port C bit 5 (WT0CCP1) for Timer 1A
HWREG(GPIO_PORTC_BASE+GPIO_O_AFSEL) |= (BIT4HI | BIT5HI);
// Then, map bit 4's alternate function to WT0CCP0
// 7 is the mux value to select WT0CCP0, 16 to shift it over to the
// right nibble for bit 4 (4 bits/nibble * 4 bits)
HWREG(GPIO_PORTC_BASE+GPIO_O_PCTL) =
(HWREG(GPIO_PORTC_BASE+GPIO_O_PCTL) & 0xfff0ffff) + (7<<16);
// Then, map bit 5's alternate function to WT0CCP0
// 7 is the mux value to select WT0CCP1, 20 to shift it over to the
// right nibble for bit 5 (4 bits/nibble * 5 bits)
HWREG(GPIO_PORTC_BASE+GPIO_O_PCTL) =
(HWREG(GPIO_PORTC_BASE+GPIO_O_PCTL) & 0xff0fffff) + (7<<20);
// Enable pin on Port C for digital I/O
HWREG(GPIO_PORTC_BASE+GPIO_O_DEN) |= (BIT4HI | BIT5HI);
// make pin 4&5 on Port C into an input
HWREG(GPIO_PORTC_BASE+GPIO_O_DIR) &= ~(BIT4HI | BIT5HI);
HWREG(GPIO_PORTC_BASE+GPIO_O_PUR) |= (BIT4HI |BIT5HI);
// back to the timer to enable a local capture interrupt
HWREG(WTIMER0_BASE+TIMER_O_IMR) |= TIMER_IMR_CAEIM;
HWREG(WTIMER0_BASE+TIMER_O_IMR) |= TIMER_IMR_CBEIM;
// enable the Timer A&B in Wide Timer 0 interrupt in the NVIC
// it is interrupt number 94&95 so appears in EN2 at bit 30 & 31
HWREG(NVIC_EN2) |= (BIT30HI | BIT31HI);
// make sure interrupts are enabled globally

__enable_irq();
// now kick the timer off by enabling it and enabling the timer to
// stall while stopped by the debugger
HWREG(WTIMER0_BASE+TIMER_O_CTL) |= (TIMER_CTL_TAEN| TIMER_CTL_TASTALL);
HWREG(WTIMER0_BASE+TIMER_O_CTL) |= (TIMER_CTL_TBEN| TIMER_CTL_TBSTALL);
// Start Interrupt Timers to timeout when wheels are stopped
ES_Timer_InitTimer(InterruptTimerLeft,UpdateTime);
ES_Timer_InitTimer(InterruptTimerRight,UpdateTime);
// Start RPM at 0
RPMLeft = 0;
RPMRight = 0;
return true;

// used only for wheel stopping case


bool PostInputCapture( ES_Event ThisEvent )
{
return ES_PostToService( MyPriority, ThisEvent);
}
/*
RunInputCapture
Uses framework timers to set RPMs to 0 if encoder edges stop coming in
*/
ES_Event RunInputCapture( ES_Event ThisEvent )
{
ES_Event ReturnEvent;
ReturnEvent.EventType = ES_NO_EVENT; // assume no errors
// timeout for left wheel
if (ThisEvent.EventType == ES_TIMEOUT && ThisEvent.EventParam
==InterruptTimerLeft)
{
RPMLeft = 0;
// Wheel is stopped if no
encoder edges come in
}
// timeout for right wheel
if (ThisEvent.EventType == ES_TIMEOUT && ThisEvent.EventParam
==InterruptTimerRight)
{
RPMRight = 0;
// Wheel is stopped if no
encoder edges come in
}
return ReturnEvent;
}
//--------------------------------------Interrupt stuff,
Encoders-------------------------------------/*Interrupt Service Routine for input capture*/
void InputCaptureResponseLeft (void)
{
uint32_t ThisCapture;
static uint32_t LastRPMLeft = 0;
// start by clearing the source of the interrupt, the input capture event
HWREG(WTIMER0_BASE+TIMER_O_ICR) = TIMER_ICR_CAECINT;
// now grab the captured value and calculate the period
ThisCapture = HWREG(WTIMER0_BASE+TIMER_O_TAR);
EnPeriodL = ThisCapture - LastCaptureL;
// update LastCapture to prepare for the next edge

LastCaptureL = ThisCapture;
RPMLeft = (PeriodToRPM/EnPeriodL);
// Reject Speeds above RPM_TOLERANCE
// Note: This is here because of noise on the Slot Sensor Output lines
if(RPMLeft > RPM_TOLERANCE) {
RPMLeft = LastRPMLeft;
LeftEnCounts--;
}
LastRPMLeft = RPMLeft;
// Keep RPM Constant from last
edge
LeftEnCounts++;

// increment

counts

// restart timer for wheel stopped cases


ES_Timer_InitTimer(InterruptTimerLeft,UpdateTime);

//Change timers and other details for right encoder**


void InputCaptureResponseRight (void)
{
uint32_t ThisCapture;
static uint32_t LastRPMRight = 0;
// start by clearing the source of the interrupt, the input capture event
HWREG(WTIMER0_BASE+TIMER_O_ICR) = TIMER_ICR_CBECINT;
// now grab the captured value and calculate the period
ThisCapture = HWREG(WTIMER0_BASE+TIMER_O_TBR);
EnPeriodR = ThisCapture - LastCaptureR;
// update LastCapture to prepare for the next edge
LastCaptureR = ThisCapture;
RPMRight = (PeriodToRPM/EnPeriodR);

edge

// Reject Speeds above RPM_TOLERANCE


// Note: This is here because of noise on the Slot Sensor Output lines
if(RPMRight > RPM_TOLERANCE) {
RPMRight = LastRPMRight;
RightEnCounts--;
}
LastRPMRight = RPMRight;
// Keep RPM Constant from last
RightEnCounts++;

// increment counts

// restart timer for wheel stopped cases


ES_Timer_InitTimer(InterruptTimerRight,UpdateTime);

//--------------------------------------RPM, speed, period


stuff-------------------------------------/*Function to return encoder period value*/
uint32_t GetPeriodLeft( void ){
return EnPeriodL; //returns encoder period
}
uint32_t GetPeriodRight( void ){
return EnPeriodR; //returns encoder period
}
/*Function to return RPM value*/
int GetRPMLeft(void) {

return RPMLeft;
}
int GetRPMRight(void) {
return RPMRight;
}
//--------------------------------------Encoder
stuff-------------------------------------// Functions to return Encoder Counts
int GetLeftEnCounts(void) {
return LeftEnCounts;
}
int GetRightEnCounts(void) {
return RightEnCounts;
}
// Function to reset Encoder Counts to 0
void ResetEnCounts(void) {
LeftEnCounts = 0;
RightEnCounts = 0;
}

Вам также может понравиться