📄 pwm.c
字号:
//*****************************************************************************
//
// pwm.c - API for the PWM modules
//
// Copyright (c) 2005-2008 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. You may not combine
// this software with "viral" open-source software in order to form a larger
// program. 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 3416 of the Stellaris Peripheral Driver Library.
//
//*****************************************************************************
//*****************************************************************************
//
//! \addtogroup pwm_api
//! @{
//
//*****************************************************************************
#include "../hw_ints.h"
#include "../hw_memmap.h"
#include "../hw_pwm.h"
#include "../hw_sysctl.h"
#include "../hw_types.h"
#include "debug.h"
#include "interrupt.h"
#include "pwm.h"
//*****************************************************************************
//
// Misc macros for manipulating the encoded generator and output defines used
// by the API.
//
//*****************************************************************************
#define PWM_GEN_BADDR(_mod_, _gen_) \
((_mod_) + (_gen_))
#define PWM_GEN_EXT_BADDR(_mod_, _gen_) \
((_mod_) + PWM_GEN_EXT_0 + \
((_gen_) - PWM_GEN_0) * 2)
#define PWM_OUT_BADDR(_mod_, _out_) \
((_mod_) + ((_out_) & 0xFFFFFFC0))
#define PWM_IS_OUTPUT_ODD(_out_) \
((_out_) & 0x00000001)
//*****************************************************************************
//
//! \internal
//! Checks a PWM generator number.
//!
//! \param ulGen is the generator number.
//!
//! This function determines if a PWM generator number is valid.
//!
//! \return Returnes \b true if the generator number is valid and \b false
//! otherwise.
//
//*****************************************************************************
#ifdef DEBUG
static tBoolean
PWMGenValid(unsigned long ulGen)
{
return((ulGen == PWM_GEN_0) || (ulGen == PWM_GEN_1) ||
(ulGen == PWM_GEN_2) || (ulGen == PWM_GEN_3));
}
#endif
//*****************************************************************************
//
//! \internal
//! Checks a PWM output number.
//!
//! \param ulPWMOut is the output number.
//!
//! This function determines if a PWM output number is valid.
//!
//! \return Returns \b true if the output number is valid and \b false
//! otherwise.
//
//*****************************************************************************
#ifdef DEBUG
static tBoolean
PWMOutValid(unsigned long ulPWMOut)
{
return((ulPWMOut == PWM_OUT_0) || (ulPWMOut == PWM_OUT_1) ||
(ulPWMOut == PWM_OUT_2) || (ulPWMOut == PWM_OUT_3) ||
(ulPWMOut == PWM_OUT_4) || (ulPWMOut == PWM_OUT_5) ||
(ulPWMOut == PWM_OUT_6) || (ulPWMOut == PWM_OUT_7));
}
#endif
//*****************************************************************************
//
//! Configures a PWM generator.
//!
//! \param ulBase is the base address of the PWM module.
//! \param ulGen is the PWM generator to configure. Must be one of
//! \b PWM_GEN_0, \b PWM_GEN_1, \b PWM_GEN_2, or \b PWM_GEN_3.
//! \param ulConfig is the configuration for the PWM generator.
//!
//! This function is used to set the mode of operation for a PWM generator.
//! The counting mode, synchronization mode, and debug behavior are all
//! configured. After configuration, the generator is left in the disabled
//! state.
//!
//! A PWM generator can count in two different modes: count down mode or count
//! up/down mode. In count down mode, it will count from a value down to zero,
//! and then reset to the preset value. This will produce left-aligned PWM
//! signals (that is the rising edge of the two PWM signals produced by the
//! generator will occur at the same time). In count up/down mode, it will
//! count up from zero to the preset value, count back down to zero, and then
//! repeat the process. This will produce center-aligned PWM signals (that is,
//! the middle of the high/low period of the PWM signals produced by the
//! generator will occur at the same time).
//!
//! When the PWM generator parameters (period and pulse width) are modified,
//! their affect on the output PWM signals can be delayed. In synchronous
//! mode, the parameter updates are not applied until a synchronization event
//! occurs. This allows multiple parameters to be modified and take affect
//! simultaneously, instead of one at a time. Additionally, parameters to
//! multiple PWM generators in synchronous mode can be updated simultaneously,
//! allowing them to be treated as if they were a unified generator. In
//! non-synchronous mode, the parameter updates are not delayed until a
//! synchronization event. In either mode, the parameter updates only occur
//! when the counter is at zero to help prevent oddly formed PWM signals during
//! the update (that is, a PWM pulse that is too short or too long).
//!
//! The PWM generator can either pause or continue running when the processor
//! is stopped via the debugger. If configured to pause, it will continue to
//! count until it reaches zero, at which point it will pause until the
//! processor is restarted. If configured to continue running, it will keep
//! counting as if nothing had happened.
//!
//! The \e ulConfig parameter contains the desired configuration. It is the
//! logical OR of the following:
//!
//! - \b PWM_GEN_MODE_DOWN or \b PWM_GEN_MODE_UP_DOWN to specify the counting
//! mode
//! - \b PWM_GEN_MODE_SYNC or \b PWM_GEN_MODE_NO_SYNC to specify the counter
//! load and comparator update synchronization mode
//! - \b PWM_GEN_MODE_DBG_RUN or \b PWM_GEN_MODE_DBG_STOP to specify the debug
//! behavior
//! - \b PWM_GEN_MODE_GEN_NO_SYNC, \b PWM_GEN_MODE_GEN_SYNC_LOCAL, or
//! \b PWM_GEN_MODE_GEN_SYNC_GLOBAL to specify the update synchronization
//! mode for generator counting mode changes
//! - \b PWM_GEN_MODE_DB_NO_SYNC, \b PWM_GEN_MODE_DB_SYNC_LOCAL, or
//! \b PWM_GEN_MODE_DB_SYNC_GLOBAL to specify the deadband parameter
//! synchronization mode
//! - \b PWM_GEN_MODE_FAULT_LATCHED or \b PWM_GEN_MODE_FAULT_UNLATCHED to
//! specify whether fault conditions are latched or not
//! - \b PWM_GEN_MODE_FAULT_MINPER or \b PWM_GEN_MODE_FAULT_NO_MINPER to
//! specify whether minimum fault period support is required
//! - \b PWM_GEN_MODE_FAULT_EXT or \b PWM_GEN_MODE_FAULT_LEGACY to specify
//! whether extended fault source selection support is enabled or not
//!
//! Setting \b PWM_GEN_MODE_FAULT_MINPER allows an application to set the
//! minimum duration of a PWM fault signal. Fault will be signalled for at
//! least this time even if the external fault pin deasserts earlier. Care
//! should be taken when using this mode since during the fault signal period,
//! the fault interrupt from the PWM generator will remain asserted. The fault
//! interrupt handler may, therefore, reenter immediately if it exits prior to
//! expiration of the fault timer.
//!
//! \note Changes to the counter mode will affect the period of the PWM signals
//! produced. PWMGenPeriodSet() and PWMPulseWidthSet() should be called after
//! any changes to the counter mode of a generator.
//!
//! \return None.
//
//*****************************************************************************
void
PWMGenConfigure(unsigned long ulBase, unsigned long ulGen,
unsigned long ulConfig)
{
//
// Check the arguments.
//
ASSERT(ulBase == PWM_BASE);
ASSERT(PWMGenValid(ulGen));
//
// Compute the generator's base address.
//
ulGen = PWM_GEN_BADDR(ulBase, ulGen);
//
// Change the global configuration of the generator.
//
HWREG(ulGen + PWM_O_X_CTL) = ((HWREG(ulGen + PWM_O_X_CTL) &
~(PWM_X_CTL_MODE | PWM_X_CTL_DEBUG |
PWM_X_CTL_LATCH | PWM_X_CTL_MINFLTPER |
PWM_X_CTL_FLTSRC | PWM_X_CTL_DBFALLUPD_M |
PWM_X_CTL_DBRISEUPD_M |
PWM_X_CTL_DBCTLUPD_M |
PWM_X_CTL_GENBUPD_M |
PWM_X_CTL_GENAUPD_M |
PWM_X_CTL_LOADUPD | PWM_X_CTL_CMPAUPD |
PWM_X_CTL_CMPBUPD)) | ulConfig);
//
// Set the individual PWM generator controls.
//
if(ulConfig & PWM_X_CTL_MODE)
{
//
// In up/down count mode, set the signal high on up count comparison
// and low on down count comparison (that is, center align the
// signals).
//
HWREG(ulGen + PWM_O_X_GENA) = (PWM_X_GENA_ACTCMPAU_ONE |
PWM_X_GENA_ACTCMPAD_ZERO);
HWREG(ulGen + PWM_O_X_GENB) = (PWM_X_GENB_ACTCMPBU_ONE |
PWM_X_GENB_ACTCMPBD_ZERO);
}
else
{
//
// In down count mode, set the signal high on load and low on count
// comparison (that is, left align the signals).
//
HWREG(ulGen + PWM_O_X_GENA) = (PWM_X_GENA_ACTLOAD_ONE |
PWM_X_GENA_ACTCMPAD_ZERO);
HWREG(ulGen + PWM_O_X_GENB) = (PWM_X_GENB_ACTLOAD_ONE |
PWM_X_GENB_ACTCMPBD_ZERO);
}
}
//*****************************************************************************
//
//! Set the period of a PWM generator.
//!
//! \param ulBase is the base address of the PWM module.
//! \param ulGen is the PWM generator to be modified. Must be one of
//! \b PWM_GEN_0, \b PWM_GEN_1, \b PWM_GEN_2, or \b PWM_GEN_3.
//! \param ulPeriod specifies the period of PWM generator output, measured
//! in clock ticks.
//!
//! This function sets the period of the specified PWM generator block, where
//! the period of the generator block is defined as the number of PWM clock
//! ticks between pulses on the generator block zero signal.
//!
//! \note Any subsequent calls made to this function before an update occurs
//! will cause the previous values to be overwritten.
//!
//! \return None.
//
//*****************************************************************************
void
PWMGenPeriodSet(unsigned long ulBase, unsigned long ulGen,
unsigned long ulPeriod)
{
//
// Check the arguments.
//
ASSERT(ulBase == PWM_BASE);
ASSERT(PWMGenValid(ulGen));
//
// Compute the generator's base address.
//
ulGen = PWM_GEN_BADDR(ulBase, ulGen);
//
// Set the reload register based on the mode.
//
if(HWREG(ulGen + PWM_O_X_CTL) & PWM_X_CTL_MODE)
{
//
// In up/down count mode, set the reload register to half the requested
// period.
//
ASSERT((ulPeriod / 2) < 65536);
HWREG(ulGen + PWM_O_X_LOAD) = ulPeriod / 2;
}
else
{
//
// In down count mode, set the reload register to the requested period
// minus one.
//
ASSERT((ulPeriod <= 65536) && (ulPeriod != 0));
HWREG(ulGen + PWM_O_X_LOAD) = ulPeriod - 1;
}
}
//*****************************************************************************
//
//! Gets the period of a PWM generator block.
//!
//! \param ulBase is the base address of the PWM module.
//! \param ulGen is the PWM generator to query. Must be one of
//! \b PWM_GEN_0, \b PWM_GEN_1, \b PWM_GEN_2, or \b PWM_GEN_3.
//!
//! This function gets the period of the specified PWM generator block. The
//! period of the generator block is defined as the number of PWM clock ticks
//! between pulses on the generator block zero signal.
//!
//! If the update of the counter for the specified PWM generator has yet
//! to be completed, the value returned may not be the active period. The
//! value returned is the programmed period, measured in PWM clock ticks.
//!
//! \return Returns the programmed period of the specified generator block
//! in PWM clock ticks.
//
//*****************************************************************************
unsigned long
PWMGenPeriodGet(unsigned long ulBase, unsigned long ulGen)
{
//
// Check the arguments.
//
ASSERT(ulBase == PWM_BASE);
ASSERT(PWMGenValid(ulGen));
//
// Compute the generator's base address.
//
ulGen = PWM_GEN_BADDR(ulBase, ulGen);
//
// Figure out the counter mode.
//
if(HWREG(ulGen + PWM_O_X_CTL) & PWM_X_CTL_MODE)
{
//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -