0% found this document useful (0 votes)
190 views3 pages

Servo

Initialize the PWM for servo control. Functions that implement feeding function. 40,000 ticks per ms assumes a 40Mhz clock, we will use SysClk / 32 for PWM.

Uploaded by

api-280451617
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
190 views3 pages

Servo

Initialize the PWM for servo control. Functions that implement feeding function. 40,000 ticks per ms assumes a 40Mhz clock, we will use SysClk / 32 for PWM.

Uploaded by

api-280451617
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 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;
}

You might also like