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

//#define TestServo

/****************************************************************************
Module
PWMShoot.c
Revision
1.0
Description
This is the PWM4Wheel Module for Initialization of PWM for wheels, set the
direction and duty cycle of PWM.
Notes
History
When
Who
What/Why
----------------------02/10/2015
10:33 Sky
Initial version
****************************************************************************/
#include <stdint.h>
#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"
"bitdefs.h"
<stdio.h>

#include
#include
#include
#include
#include

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

#include
#include
#include
#include
#include

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

// 40,000 ticks per mS assumes a 40Mhz clock, we will use SysClk/32 for PWM
#define PWMTicksPerMS 40000/32
// set 200 Hz frequency so 5mS period
#define PeriodInMS 20
#define PeriodShoot 40000/32/10
#define OffPulseWidth 1200/1000
#define OnPulseWidth 850/1000
#define BitsPerNibble 4
#define
#define
#define
#ifndef
#define
#endif

clrScrn()
printf("\x1b[2J")
goHome()
printf("\x1b[1,1H")
clrLine()
printf("\x1b[K")
ALL_BITS
ALL_BITS (0xff<<2)

// we will use PWM module 0 for this demo and program it for up/down counting
void InitServoPWM( void ){
volatile uint32_t Dummy; // use volatile to avoid over-optimization
// start by enabling the clock to the PWM Module (PWM0)
HWREG(SYSCTL_RCGCPWM) |= SYSCTL_RCGCPWM_R0;
// enable the clock to Port B
HWREG(SYSCTL_RCGCGPIO) |= SYSCTL_RCGCGPIO_R4;
// Select the PWM clock as System Clock/32
HWREG(SYSCTL_RCC) = (HWREG(SYSCTL_RCC) & ~SYSCTL_RCC_PWMDIV_M) |
(SYSCTL_RCC_USEPWMDIV | SYSCTL_RCC_PWMDIV_32);
// make sure that the PWM module clock has gotten going
while ((HWREG(SYSCTL_PRPWM) & SYSCTL_PRPWM_R0) != SYSCTL_PRPWM_R0)
;
// disable the PWM while initializing
HWREG( PWM0_BASE+PWM_O_2_CTL ) = 0;
// program generator A to go to 0 at rising comare A, 1 on falling compare A
HWREG( PWM0_BASE+PWM_O_2_GENA) =
(PWM_2_GENA_ACTCMPAU_ZERO | PWM_2_GENA_ACTCMPAD_ONE );
// Set the PWM period. Since we are counting both up & down, we initialize
// the load register to 1/2 the desired total period
HWREG( PWM0_BASE+PWM_O_2_LOAD) = ((PeriodInMS * PWMTicksPerMS)-1)>>1;
// Set the initial Duty cycle on A to 50% by programming the compare value
// to 1/2 the period to count up (or down)
HWREG( PWM0_BASE+PWM_O_2_CMPA) = ((PWMTicksPerMS*OffPulseWidth)-1)>>1;
// HWREG( PWM0_BASE+PWM_O_2_LOAD)
//
//// Set the initial Duty cycle on
//// to 1/2 the period to count up
// HWREG( PWM0_BASE+PWM_O_2_CMPA)

= PeriodShoot;
A to 50% by programming the compare value
(or down)
= PeriodShoot * 10/100;

// set changes to the PWM output Enables to be locally syncronized to a


// zero count
HWREG(PWM0_BASE+PWM_O_ENUPD) = (HWREG(PWM0_BASE+PWM_O_ENUPD) &
~(PWM_ENUPD_ENUPD4_M))|PWM_ENUPD_ENUPD4_LSYNC ;
// enable the PWM outputs
HWREG( PWM0_BASE+PWM_O_ENABLE) |= (PWM_ENABLE_PWM4EN);
// now configure the Port B pins to be PWM outputs
// start by selecting the alternate function for PB6 & 7
HWREG(GPIO_PORTE_BASE+GPIO_O_AFSEL) |= BIT4HI;
// now choose to map PWM to those pins, this is a mux value of 4 that we
// want to use for specifying the function on bits 6 & 7
HWREG(GPIO_PORTE_BASE+GPIO_O_PCTL) =
(HWREG(GPIO_PORTE_BASE+GPIO_O_PCTL) & 0xfff0ffff) + (4<<(4*BitsPerNibble));
// Enable pins 6 & 7 on Port B for digital I/O

HWREG(GPIO_PORTE_BASE+GPIO_O_DEN) |= (BIT4HI);
// make pins 6 & 7 on Port B into outputs
HWREG(GPIO_PORTE_BASE+GPIO_O_DIR) |= (BIT4HI);
// set the up/down count mode and enable the PWM generator
HWREG(PWM0_BASE+ PWM_O_2_CTL) |= (PWM_2_CTL_MODE | PWM_2_CTL_ENABLE);
}

void InitShootPWM( void ){


volatile uint32_t Dummy; // use volatile to avoid over-optimization
// start by enabling the clock to the PWM Module (PWM1)
HWREG(SYSCTL_RCGCPWM) |= SYSCTL_RCGCPWM_R1;
// enable the clock to Port E
HWREG(SYSCTL_RCGCGPIO) |= SYSCTL_RCGCGPIO_R4;
// Select the PWM clock as System Clock/32
HWREG(SYSCTL_RCC) = (HWREG(SYSCTL_RCC) & ~SYSCTL_RCC_PWMDIV_M) |
(SYSCTL_RCC_USEPWMDIV | SYSCTL_RCC_PWMDIV_32);
// make sure that the PWM module clock has gotten going
while ((HWREG(SYSCTL_PRPWM) & SYSCTL_PRPWM_R1) != SYSCTL_PRPWM_R1)
;
// disable the PWM while initializing
HWREG( PWM1_BASE+PWM_O_1_CTL ) = 0;
// program generator A to go to 0 at rising comare A, 1 on falling compare A
HWREG( PWM1_BASE+PWM_O_1_GENB) =
(PWM_1_GENB_ACTCMPBU_ZERO | PWM_1_GENB_ACTCMPBD_ONE );
// program generator B to go to 0 at rising comare B, 1 on falling compare B
//HWREG( PWM0_BASE+PWM_O_2_GENB) =
//(PWM_2_GENA_ACTCMPBU_ZERO | PWM_2_GENA_ACTCMPBD_ONE );
// Set the PWM period. Since we are counting both up & down, we initialize
// the load register to 1/2 the desired total period
HWREG( PWM1_BASE+PWM_O_1_LOAD) = PeriodShoot;
// Set the initial Duty cycle on A to 50% by programming the compare value
// to 1/2 the period to count up (or down)
HWREG( PWM1_BASE+PWM_O_1_CMPB) = PeriodShoot*0/100;
// Set the initial Duty cycle on B to 25% by programming the compare value
// to 1/4 the period
//HWREG( PWM0_BASE+PWM_O_0_CMPB) = ((PeriodInMS * PWMTicksPerMS)-1)>>1;
// set changes to the PWM output Enables to be locally syncronized to a
// zero count
HWREG(PWM1_BASE+PWM_O_ENUPD) = (HWREG(PWM1_BASE+PWM_O_ENUPD) &
~(PWM_ENUPD_ENUPD3_M))|PWM_ENUPD_ENUPD3_LSYNC ;
// enable the PWM outputs
HWREG( PWM1_BASE+PWM_O_ENABLE) |= (PWM_ENABLE_PWM3EN);

// now configure the Port B pins to be PWM outputs


// start by selecting the alternate function for PB6 & 7
HWREG(GPIO_PORTE_BASE+GPIO_O_AFSEL) |= BIT5HI;
// now choose to map PWM to those pins, this is a mux value of 4 that we
// want to use for specifying the function on bits 6 & 7
HWREG(GPIO_PORTE_BASE+GPIO_O_PCTL) =
(HWREG(GPIO_PORTE_BASE+GPIO_O_PCTL) & 0xff0fffff) + (5<<(5*BitsPerNibble));
// Enable pins 6 & 7 on Port B for digital I/O
HWREG(GPIO_PORTE_BASE+GPIO_O_DEN) |= (BIT5HI);
// make pins 6 & 7 on Port B into outputs
HWREG(GPIO_PORTE_BASE+GPIO_O_DIR) |= (BIT5HI);
// set the up/down count mode and enable the PWM generator
HWREG(PWM1_BASE+ PWM_O_1_CTL) |= (PWM_1_CTL_MODE | PWM_1_CTL_ENABLE);
}
/****************************************************************
FUNCTION SetDuty
ARGUMENTS

: channelNum (LEFTWHEEL or RIGHTWHEEL)


newDuty --> the new duty
cycle which will be set to PWM channel
RETURN
DESCRIPTION
)

: No return
: This function will set new dutycycle to PWM channel(channelNum

Always set rotate direct


ion before set duty.
****************************************************************/
void SetServo(uint8_t ServoStatus)
{
if (ServoStatus == 1) // set dutycycle of channel #1
{
HWREG(PWM0_BASE+PWM_O_2_CMPA) = (((PWMTicksPerMS*OnPulse
Width) -1)>>1);
}
else
{
HWREG(PWM0_BASE+PWM_O_2_CMPA) = (((PWMTicksPerMS*OffPuls
eWidth) -1)>>1);
}
}
void SetShoot(uint8_t newDuty)
{
//puts("setDuty1");
uint8_t Duty = newDuty;
//if (DirectionLeft == BACKWARD) Duty = 100-newDuty; //c
alculate the duty that should be set to PWM depends on newDuty and current direc
tion
if ((HWREG( PWM1_BASE+PWM_O_ENABLE) & PWM_ENABLE_PWM3EN)
== 0)
HWREG( PWM1_BASE+PWM_O_ENABLE) |= PWM_ENABLE_PWM3EN;
//if this PWM channel is disabled, enable it

if (Duty == 0) HWREG( PWM1_BASE+PWM_O_ENABLE) &= ~PWM_EN


ABLE_PWM3EN; //set new dutycycle
else if (newDuty >= 40) HWREG(PWM1_BASE+PWM_O_1_CMPB) =
PeriodShoot * 40 / 100;
else HWREG(PWM1_BASE+PWM_O_1_CMPB) = PeriodShoot* Duty /
100;
}

#ifdef TestServo
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);
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