Sie sind auf Seite 1von 3

/****************************************************************************

Module
Servo.c
Revision
1.0
Description
Initialize the PWM for servo control.
Functions that implement feeding function.
Notes
History
When
Who
What/Why
----------------------02/11/2015 09:02
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 "Servo.h"
#define PWMFEED
20
#define PWMMID
50
#define SERVOFREQ 50
// 40,000 ticks per mS assumes a 40Mhz clock, we will use SysClk/32 for PWM
#define PWMTicksPerMS 40000/32
// set 20 Hz frequency so 50ms period
#define PeriodInMS 50
#define BitsPerNibble 4
/****************************Private Function Prototypes***********************/
static void SetDuty(uint8_t);
/********************************Public Functions******************************/
void InitPWMServo(void)
{
//M1PWM2, M1PWM3 on PE4 and PE5
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_GENA) =
(PWM_1_GENA_ACTCMPAU_ZERO | PWM_1_GENA_ACTCMPAD_ONE );
// program generator B to go to 0 at rising comare B, 1 on falling compare B
HWREG( PWM1_BASE+PWM_O_1_GENB) =
(PWM_1_GENA_ACTCMPBU_ZERO | PWM_1_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) = ((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( PWM1_BASE+PWM_O_1_CMPA) = ((PeriodInMS * PWMTicksPerMS)-1)>>2;
// Set the initial Duty cycle on B to 25% by programming the compare value
// to 1/4 the period
HWREG( PWM1_BASE+PWM_O_1_CMPB) = ((PeriodInMS * PWMTicksPerMS)-1)>>3;
// 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_ENUPD0_M | PWM_ENUPD_ENUPD1_M)) |
(PWM_ENUPD_ENUPD0_LSYNC | PWM_ENUPD_ENUPD1_LSYNC);
// enable the PWM outputs
HWREG( PWM1_BASE+PWM_O_ENABLE) |= (PWM_ENABLE_PWM2EN | PWM_ENABLE_PWM3EN);
// now configure the Port E pins to be PWM outputs
// start by selecting the alternate function for PE4 & 5
HWREG(GPIO_PORTE_BASE+GPIO_O_AFSEL) |= (BIT4HI | 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 4 & 5
HWREG(GPIO_PORTE_BASE+GPIO_O_PCTL) =
(HWREG(GPIO_PORTE_BASE+GPIO_O_PCTL) & 0xff00ffff) + (4<<(4*BitsPerNibble)) +
(4<<(5*BitsPerNibble));
// Enable pins 4 & 5 on Port E for digital I/O
HWREG(GPIO_PORTE_BASE+GPIO_O_DEN) |= (BIT4HI | BIT5HI);
// make pins 4 & 5 on Port E into outputs
HWREG(GPIO_PORTE_BASE+GPIO_O_DIR) |= (BIT4HI | 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);
}
void ServoFeed(void)
{
SetDuty(PWMFEED);

}
void ServoBack(void)
{
SetDuty(PWMMID);
}
/*********************************Private Functions*****************************
********/
static void SetDuty(uint8_t newDuty)
{
if ((HWREG( PWM1_BASE+PWM_O_ENABLE) & PWM_ENABLE_PWM2EN) == 0)
HWREG( PWM1_BASE+PWM_O_ENABLE) |= PWM_ENABLE_PWM2EN;
//if this PWM channel is disabled, enable it
if (newDuty == 0) HWREG( PWM1_BASE+PWM_O_ENABLE) &= ~PWM_ENABLE_PWM0EN;
//set new dutycycle
else HWREG(PWM1_BASE+PWM_O_1_CMPA) = (((PeriodInMS * PWMTicksPerMS) -1)>
>1) * newDuty / 100;
}

Das könnte Ihnen auch gefallen