Sunteți pe pagina 1din 7

//#define testShootEncoder

//#define testInterupt
#include <stdint.h>
#include
#include
#include
#include
#include
#include

<stdbool.h>
<stdio.h>
"driverlib/sysctl.h"
"driverlib/gpio.h"
"driverlib/interrupt.h"
"utils/uartstdio.h"

#include
#include
#include
#include

"ES_Configure.h"
"ES_Framework.h"
"ES_Port.h"
"termio.h"

#include
#include
#include
#include
#include
#include
#include

"inc/hw_memmap.h"
"inc/hw_timer.h"
"inc/hw_sysctl.h"
"inc/hw_nvic.h"
"inc/hw_types.h"
"inc/hw_gpio.h"
"bitdefs.h"

#include "PWMShoot.h"
// 40,000 ticks per mS assumes a 40Mhz clock
#define TicksPerMS 40000
#define ControlInterval 100
#define PriChunk 8
#define PeriodShootControl 200
#define delayTime 500*TicksPerMS
#define Kp 0.28
#define Ki 0.05
/******************************Module Constants*********************************
*/
//static const uint32_t delayTime = 25000000; //tick
/******************************Module Variables*********************************
*/
static uint16_t TargetRPMShoot;
static uint32_t LastCaptureShoot;
static uint64_t PeriodShoot = 110000000;
void InitInputCaptureShoot( void )
{
// start by enabling the clock to the timer (Wide Timer 5)
HWREG(SYSCTL_RCGCWTIMER) |= SYSCTL_RCGCWTIMER_R5;
int Dummy = HWREG(SYSCTL_RCGCWTIMER);
// enable the clock to Port D
HWREG(SYSCTL_RCGCGPIO) |= SYSCTL_RCGCGPIO_R3;
// since we added this Port D clock init, we can immediately start
// into configuring the timer, no need for further delay
// make sure that timer (Timer A) is disabled before configuring

HWREG(WTIMER5_BASE+TIMER_O_CTL) &= ~TIMER_CTL_TAEN;


HWREG(WTIMER5_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(WTIMER5_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(WTIMER5_BASE+TIMER_O_TAILR) = 0xffffffff;
HWREG(WTIMER5_BASE+TIMER_O_TBILR) = TicksPerMS*PeriodShootControl;
// we don't want any prescaler (it is unnecessary with a 32 bit count)
// HWREG(WTIMER0_BASE+TIMER_O_TAPR) = 0;
// set up timer A in capture mode (TAMR=3, TAAMS = 0),
// for edge time (TACMR = 1) and up-counting (TACDIR = 1)
HWREG(WTIMER5_BASE+TIMER_O_TAMR) =
(HWREG(WTIMER5_BASE+TIMER_O_TAMR) & ~TIMER_TAMR_TAAMS) |
(TIMER_TAMR_TACDIR | TIMER_TAMR_TACMR | TIMER_TAMR_TAMR_CAP);
//set up Timer B in periodic mode
HWREG(WTIMER5_BASE+TIMER_O_TBMR)=(HWREG(WTIMER5_BASE+TIMER_O_TBMR)&~ TIM
ER_TBMR_TBMR_M)| TIMER_TBMR_TBMR_PERIOD;
// To set the event to rising edge, we need to modify the TAEVENT bits
// in GPTMCTL. Rising edge = 00, so we clear the TAEVENT bits
HWREG(WTIMER5_BASE+TIMER_O_CTL) &= ~TIMER_CTL_TAEVENT_M;
// Now Set up the port to do the capture (clock was enabled earlier)
// start by setting the alternate function for Port D bit 6 (WT5CCP0)
HWREG(GPIO_PORTD_BASE+GPIO_O_AFSEL) |= BIT6HI;
// 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_PORTD_BASE+GPIO_O_PCTL) =
(HWREG(GPIO_PORTD_BASE+GPIO_O_PCTL) & 0xf0ffffff) + (7<<24);
// Enable pin on Port C for digital I/O
HWREG(GPIO_PORTD_BASE+GPIO_O_DEN) |= BIT6HI;
// make pin 4 on Port C into an input
HWREG(GPIO_PORTD_BASE+GPIO_O_DIR) &= BIT6LO;
// back to the timer to enable a local capture interrupt
HWREG(WTIMER5_BASE+TIMER_O_IMR) |= TIMER_IMR_CAEIM;
// enable a periodic interrupt
HWREG(WTIMER5_BASE+TIMER_O_IMR)|=TIMER_IMR_TBTOIM;
// enable the Timer A in Wide Timer 0 interrupt in the NVIC
// it is interrupt number 94 so appears in EN2 at bit 30
HWREG(NVIC_EN3) |= BIT8HI | BIT9HI;
// 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(WTIMER5_BASE+TIMER_O_CTL) |= (TIMER_CTL_TAEN | TIMER_CTL_TASTALL);
HWREG(WTIMER5_BASE+TIMER_O_CTL) |= (TIMER_CTL_TBEN | TIMER_CTL_TBSTALL);
}
void InitMatchStopShoot(void)
{
// start by enabling the clock to the timer (Wide Timer 2)
HWREG(SYSCTL_RCGCWTIMER) |= SYSCTL_RCGCWTIMER_R4;
int Dummy = HWREG(SYSCTL_RCGCWTIMER);
// make sure that timer (Timer A) is disabled before configuring
HWREG(WTIMER4_BASE+TIMER_O_CTL) &= ~TIMER_CTL_TAEN;
// 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(WTIMER4_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(WTIMER4_BASE+TIMER_O_TAILR) = 0xffffffff;
// we don't want any prescaler (it is unnecessary with a 32 bit count)
// HWREG(WTIMER0_BASE+TIMER_O_TAPR) = 0;
// set up timer A in periodic mode (TAMR=3, TAAMS = 0),
// for edge time (TACMR = 1) and up-counting (TACDIR = 1)
HWREG(WTIMER4_BASE+TIMER_O_TAMR) =
(HWREG(WTIMER4_BASE+TIMER_O_TAMR) & ~TIMER_TAMR_TAAMS) |
(TIMER_TAMR_TACDIR | TIMER_TAMR_TAMR_PERIOD);
// back to the timer to enable a local match interrupt
HWREG(WTIMER4_BASE+TIMER_O_TAMR) |= TIMER_TAMR_TAMIE;
HWREG(WTIMER4_BASE+TIMER_O_IMR) |= TIMER_IMR_TAMIM;
// set the match value to 0xffffffff
HWREG(WTIMER4_BASE+TIMER_O_TAMATCHR) = 0xffffffff;
// enable the Timer A in Wide Timer 2 interrupt in the NVIC
// it is interrupt number 98 so appears in EN3 at bit 2
HWREG(NVIC_EN3) |= BIT6HI;
// 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(WTIMER4_BASE+TIMER_O_CTL) |= (TIMER_CTL_TAEN | TIMER_CTL_TASTALL);
}
void SetTargetRPMShoot(uint16_t newTarget)
{
TargetRPMShoot = newTarget;
}
void InterruptShootControl(void)
{

// start by clearing the source of the interrupt, the time out event
HWREG(WTIMER5_BASE+TIMER_O_ICR) = TIMER_ICR_TBTOCINT;
// now grab the captured value and calculate the period
double CurrentDuty;
double PError;
static double IError;
double CurrentRPM;
//calculate current RPM
CurrentRPM = 40000000/ PeriodShoot;
PError = CurrentRPM-(double)TargetRPMShoot;
IError += PError;
CurrentDuty = - Kp * PError - Ki * IError;
if (CurrentDuty < 0)
{
CurrentDuty = 0;
IError -= PError;
}
else if (CurrentDuty >= 40)
{
CurrentDuty = 40;
IError -= PError;
}
//printf("PError = %d\n\r", (int)PError);
//printf("IError = %d\n\r", (int)IError);
//printf("CurrentDuty = %d\n\r", (int)CurrentDuty);
if (TargetRPMShoot == 0)
{
IError = 0;
CurrentDuty = 0;
}
SetShoot((uint8_t)CurrentDuty);
//printf("interruptControl!\n\r");
}
void InputCaptureShoot( void )
{
uint32_t ThisCapture;
uint32_t TempMatchVal;
// start by clearing the source of the interrupt, the input capture event
HWREG(WTIMER5_BASE+TIMER_O_ICR) = TIMER_ICR_CAECINT;
// now grab the captured value and calculate the period
ThisCapture = HWREG(WTIMER5_BASE+TIMER_O_TAR);
//
uint32_t LastPeriodShoot = PeriodShoot;
//if ((ThisCapture - LastCaptureShoot)>= 20000)
PeriodShoot = ThisCapture - LastCaptureShoot;
//calculate the next Match Value , update match value
//printf("WheelCurrentRPM = %d \n\r", (uint32_t)(40000000/Period
Shoot));
// update LastCapture to prepare for the next edge
TempMatchVal = ThisCapture + delayTime;
HWREG(WTIMER4_BASE+TIMER_O_TAMATCHR) = TempMatchVal;
LastCaptureShoot = ThisCapture;
}
void MatchStopShootInterrupt(void)
{
//clear the source of interrupt, match event
HWREG(WTIMER4_BASE+TIMER_O_ICR) = TIMER_ICR_TAMCINT;

//set PeriodLeft to 110000000


PeriodShoot = 41000000;
//printf("!!!CurrentRPM = %d\n\r", (uint32_t)(40000000/PeriodShoot));
}
void SetShootRPSTarget(uint16_t newRPS)
{
TargetRPMShoot = newRPS;
}
uint32_t QueryRPS(void)
{
return (uint32_t)(40000000/PeriodShoot);
}
//test harnest for encoder
#ifdef testShootEncoder
#define clrScrn()
#define goHome()
#define clrLine()

printf("\x1b[2J")
printf("\x1b[1,1H")
printf("\x1b[K")

int main(void)
{
// Set the clock to run at 40MhZ using the PLL and 16MHz external crysta
l
SysCtlClockSet(SYSCTL_SYSDIV_5 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN
| SYSCTL_XTAL_16MHZ);
TERMIO_Init();
clrScrn();
printf("test shoot encoder\n\r");
TargetRPMShoot = 0;
InitShootPWM();
InitInputCaptureShoot();
InitMatchStopShoot();
InitServoPWM();
while(1)
{
char command = getchar();
static uint8_t temp = 0;
if (command == 'u')
{
temp = 1;
puts("up!\n\r");
}
else if (command == 'd')
{
temp = 0;
puts("down!\n\r");
}
else if (command == 'h')
{
TargetRPMShoot = 60;
}
else if (command == 'l')
{

TargetRPMShoot = 0;
}
SetServo(temp);
}
return 0;
}
#endif
//test harnest for wheel RPM control
#ifdef testInterupt
int main(void)
{
// Set the clock to run at 40MhZ using the PLL and 16MHz external crysta
l
SysCtlClockSet(SYSCTL_SYSDIV_5 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN
| SYSCTL_XTAL_16MHZ);
TERMIO_Init();
clrScrn();
PortFunctionInit();
puts("Test Shoot!\n\r");
InitServoPWM();
InitShootPWM();
//
PWM8_TIVA_Init();
//
PWM8_TIVA_SetFreq( 5000, 2);
//
PWM8_TIVA_SetDuty(50,4);
//
PWM8_TIVA_SetDuty(50,5);
LastCaptureShoot = 0;
while(1)
{
char command = getchar();
static uint8_t temp = 0;
static int8_t temp2 = 0;
if (command == 'u')
{
temp = 1;
puts("up!\n\r");
}
else if (command == 'd')
{
temp = 0;
puts("down!\n\r");
}
else if (command == 'h')
{
if (temp2<40) temp2 +=3;
printf("CurrentDuty is %d \n\r", temp2);
}
else if (command == 'l')
{
if (temp2 >0 ) temp2 -=3;
printf("CurrentDuty is %d\n\r", temp2);
}
SetServo(temp);
SetShoot(temp2);
}
}

#endif
#ifdef testWheelControl
#define clrScrn()
printf("\x1b[2J")
#define goHome()
printf("\x1b[1,1H")
#define clrLine()
printf("\x1b[K")
int main(void)
{
// Set the clock to run at 40MhZ using the PLL and 16MHz external crysta
l
SysCtlClockSet(SYSCTL_SYSDIV_5 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN
| SYSCTL_XTAL_16MHZ);
TERMIO_Init();
clrScrn();
printf("test Wheel control\n\r");
InitInputCapturePeriodLeft();
InitLeftRPMControlInt();
uint16_t Temp = 60;
SetTargetLeft(Temp);
while (1)
{
char ch = getchar();
if (ch == '8')
{
Temp += 5;
}
else if (ch == '2')
{
Temp -= 5;
}
if (Temp < 0) Temp = 0;
printf("CurrentTargetRPM = %d\n\r", Temp);
SetTargetLeft(Temp);
}
return 0;
}
#endif

S-ar putea să vă placă și