⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 motors.c

📁 eaayarm101自制小车源代码 周立功公司原创
💻 C
📖 第 1 页 / 共 2 页
字号:
//*****************************************************************************
//
// motors.c - Motor driver code.
//
// Copyright (c) 2005-2007 Luminary Micro, Inc.  All rights reserved.
//
// Software License Agreement
//
// Luminary Micro, Inc. (LMI) is supplying this software for use solely and
// exclusively on LMI's microcontroller products.
//
// The software is owned by LMI and/or its suppliers, and is protected under
// applicable copyright laws.  All rights are reserved.  Any use in violation
// of the foregoing restrictions may subject the user to criminal sanctions
// under applicable laws, as well as to civil liability for the breach of the
// terms and conditions of this license.
//
// THIS SOFTWARE IS PROVIDED "AS IS".  NO WARRANTIES, WHETHER EXPRESS, IMPLIED
// OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
// LMI SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
// CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
//
// This is part of revision 199 of an01245.
//
//*****************************************************************************

#include "../../hw_gpio.h"
#include "../../hw_memmap.h"
#include "../../hw_pwm.h"
#include "../../hw_sysctl.h"
#include "../../hw_types.h"
#include "compiler.h"
#include "motors.h"
#include "system.h"

//*****************************************************************************
//
//! \page motors_intro Introduction
//!
//! There are four brushed DC motors on the car; two on the left side of the
//! car and two on the right side.  The drive for the two motors on each side
//! is ganged together; a single H bridge provides current to both motors on
//! the left side of the car and another H bridge provides current to both
//! motors on the right side of the car.
//!
//! Though they are full H bridges, each bridge has only two inputs; inverters
//! inside the bridge chip provides the other two control signals.  Therefore,
//! providing a high signal on one input and alow signal on the other will
//! cause the connected motors to spin one direction, while swapping the inputs
//! will cause the motors to spin in the other direction.
//!
//! The "top" and "bottom" side of each H bridge are defined such that driving
//! the "top" side with a high signal and the "bottom" side with a low signal
//! will cause the motors to spin in the forward direction.
//!
//! When running, the bridge is supplied with a low signal on one if its inputs
//! and a high signal on the other input.  The speed of the motors are
//! controlled by providing a PWM signal in place of the high signal,
//! effectively reducing the drive voltage to the motor.
//!
//! The direction of the motors is switched by simply swapping the input
//! signals to the bridge.  Note that to prevent shoot-through current in the
//! bridge, and to reduce wear on the motors, the motor direction should only
//! be changed after the speed of the motors has been brought to zero.  The
//! motor speed can be brought to zero either by slewing the speed via periodic
//! calls to MotorLeftSpeed() / MotorRightSpeed() or by simply stopping the
//! motors and waiting for a short period.
//!
//! The left and right motors are operated in a fully independent fashion; the
//! only thing they share is a fixed 15 KHz PWM frequency.
//!
//! The code for controlling the motors is contained in <tt>motors.c</tt>,
//! with <tt>motors.h</tt> containing the API definitions for use by the
//! remainder of the application.
//
//*****************************************************************************

//*****************************************************************************
//
//! \defgroup motors_api Definitions
//! @{
//
//*****************************************************************************

//*****************************************************************************
//
//! Enable this define to provide a workaround for the PWM clocking errata that
//! exists on all silicon revision previous to C0 (errata 4.1).  The workaround
//! is harmless for silicon that does not have the clocking errata; the net
//! result of the workaround is to reduce the duty cycle resolution by one bit
//! by pre-dividing the input clock to the PWM generator by two.
//
//*****************************************************************************
#define PWM_ERRATA_WORKAROUND

//*****************************************************************************
//
//! The number of clocks per 15kHz PWM period.  This is used to determine the
//! match value for a particular PWM duty cycle.
//
//*****************************************************************************
#ifdef PWM_ERRATA_WORKAROUND
#define PWM_CLOCK               (SYSTEM_CLOCK / (2 * 15000))
#else
#define PWM_CLOCK               (SYSTEM_CLOCK / 15000)
#endif

//*****************************************************************************
//
//! The GPIO port that contains the pins to which the left motor bridge is
//! connected.
//
//*****************************************************************************
#define LEFT_PORT               GPIO_PORTD_BASE

//*****************************************************************************
//
//! The GPIO pin to which the "top side" of the left motor bridge is connected.
//
//*****************************************************************************
#define LEFT_FORWARD            (1 << 0)

//*****************************************************************************
//
//! The GPIO pin to which the "bottom side" of the left motor bridge is
//! connected.
//
//*****************************************************************************
#define LEFT_BACKWARD           (1 << 1)

//*****************************************************************************
//
//! The GPIO port that contains the pins to which the right motor bridge is
//! connected.
//
//*****************************************************************************
#define RIGHT_PORT              GPIO_PORTB_BASE

//*****************************************************************************
//
//! The GPIO pin to which the "top side" of the right motor bridge is
//! connected.
//
//*****************************************************************************
#define RIGHT_FORWARD           (1 << 0)

//*****************************************************************************
//
//! The GPIO pin to which the "bottom side" of the right motor bridge is
//! connected.
//
//*****************************************************************************
#define RIGHT_BACKWARD          (1 << 1)

//*****************************************************************************
//
//! Configures the motors for operation.
//!
//! This function prepares the motors for normal operation.  The PWM and GPIO
//! blocks are configured to properly drive the motors.  The motors are stopped
//! by default and no default direction is provided (i.e. MotorLeftDir() must
//! be called before the left motor will run, and MotorRightDir() must be
//! called before the right motor will run).
//!
//! \return None.
//
//*****************************************************************************
void
MotorInit(void)
{
    //
    // Stop the motors.
    //
    HWREG(LEFT_PORT + GPIO_O_DIR) |= LEFT_FORWARD | LEFT_BACKWARD;
    HWREG(LEFT_PORT + GPIO_O_DATA + ((LEFT_FORWARD | LEFT_BACKWARD) << 2)) = 0;
    HWREG(RIGHT_PORT + GPIO_O_DIR) |= RIGHT_FORWARD | RIGHT_BACKWARD;
    HWREG(RIGHT_PORT + GPIO_O_DATA + ((RIGHT_FORWARD | RIGHT_BACKWARD) << 2)) =
        0;

    //
    // Configure the PWM generator for the left motor.
    //
    HWREG(PWM_BASE + PWM_GEN_0_OFFSET + PWM_O_X_LOAD) = PWM_CLOCK - 1;
    HWREG(PWM_BASE + PWM_GEN_0_OFFSET + PWM_O_X_CMPA) = PWM_CLOCK - 2;
    HWREG(PWM_BASE + PWM_GEN_0_OFFSET + PWM_O_X_CMPB) = PWM_CLOCK;
    HWREG(PWM_BASE + PWM_GEN_0_OFFSET + PWM_O_X_GENA) =
        ((PWM_GEN_ACT_ONE << PWM_GEN_ACT_LOAD_SHIFT) |
         (PWM_GEN_ACT_ZERO << PWM_GEN_ACT_A_DN_SHIFT));
    HWREG(PWM_BASE + PWM_GEN_0_OFFSET + PWM_O_X_GENB) =
        ((PWM_GEN_ACT_ONE << PWM_GEN_ACT_LOAD_SHIFT) |
         (PWM_GEN_ACT_ZERO << PWM_GEN_ACT_A_DN_SHIFT));
    HWREG(PWM_BASE + PWM_GEN_0_OFFSET + PWM_O_X_CTL) = PWM_X_CTL_ENABLE;

    //
    // Configure the PWM generator for the right motor.
    //
    HWREG(PWM_BASE + PWM_GEN_1_OFFSET + PWM_O_X_LOAD) = PWM_CLOCK - 1;
    HWREG(PWM_BASE + PWM_GEN_1_OFFSET + PWM_O_X_CMPA) = PWM_CLOCK - 2;
    HWREG(PWM_BASE + PWM_GEN_1_OFFSET + PWM_O_X_CMPB) = PWM_CLOCK;
    HWREG(PWM_BASE + PWM_GEN_1_OFFSET + PWM_O_X_GENA) =
        ((PWM_GEN_ACT_ONE << PWM_GEN_ACT_LOAD_SHIFT) |
         (PWM_GEN_ACT_ZERO << PWM_GEN_ACT_A_DN_SHIFT));
    HWREG(PWM_BASE + PWM_GEN_1_OFFSET + PWM_O_X_GENB) =
        ((PWM_GEN_ACT_ONE << PWM_GEN_ACT_LOAD_SHIFT) |
         (PWM_GEN_ACT_ZERO << PWM_GEN_ACT_A_DN_SHIFT));

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -