📄 adc.c
字号:
//*****************************************************************************
//
// adc.c - Driver for the ADC.
//
// Copyright (c) 2005,2006 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 Stellaris Family of 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 852 of the Stellaris Driver Library.
//
//*****************************************************************************
//*****************************************************************************
//
//! \addtogroup adc_api
//! @{
//
//*****************************************************************************
#include "hw_adc.h"
#include "hw_ints.h"
#include "hw_memmap.h"
#include "hw_types.h"
#include "adc.h"
#include "debug.h"
#include "interrupt.h"
//*****************************************************************************
//
// The currently configured software oversampling factor for each of the ADC
// sequencers.
//
//*****************************************************************************
unsigned char g_pucOversampleFactor[3];
//*****************************************************************************
//
//! Registers an interrupt.handler for an ADC interrupt.
//!
//! \param ulBase is the base address of the ADC module.
//! \param ulSequenceNum is the sample sequence number.
//! \param pfnHandler is a pointer to the function to be called when the
//! ADC sample sequence interrupt occurs.
//!
//! This function sets the handler to be called when a sample sequence
//! interrupt occurs. This will enable the global interrupt in the interrupt
//! controller; the sequence interrupt must be enabled with ADCIntEnable(). It
//! is the interrupt.handler's responsibility to clear the interrupt source via
//! ADCIntClear().
//!
//! \sa IntRegister() for important information about registering interrupt
//! handlers.
//!
//! \return None.
//
//*****************************************************************************
void
ADCIntRegister(unsigned long ulBase, unsigned long ulSequenceNum,
void (*pfnHandler)(void))
{
unsigned long ulInt;
//
// Check the arguments.
//
ASSERT(ulBase == ADC_BASE);
ASSERT(ulSequenceNum < 4);
//
// Determine the interrupt to register based on the sequence number.
//
ulInt = INT_ADC0 + ulSequenceNum;
//
// Register the interrupt.handler.
//
IntRegister(ulInt, pfnHandler);
//
// Enable the timer interrupt.
//
IntEnable(ulInt);
}
//*****************************************************************************
//
//! Unregisters the interrupt.handler for an ADC interrupt.
//!
//! \param ulBase is the base address of the ADC module.
//! \param ulSequenceNum is the sample sequence number.
//!
//! This function unregisters the interrupt.handler. This will disable the
//! global interrupt in the interrupt controller; the sequence interrupt must
//! be disabled via ADCIntDisable().
//!
//! \sa IntRegister() for important information about registering interrupt
//! handlers.
//!
//! \return None.
//
//*****************************************************************************
void
ADCIntUnregister(unsigned long ulBase, unsigned long ulSequenceNum)
{
unsigned long ulInt;
//
// Check the arguments.
//
ASSERT(ulBase == ADC_BASE);
ASSERT(ulSequenceNum < 4);
//
// Determine the interrupt to unregister based on the sequence number.
//
ulInt = INT_ADC0 + ulSequenceNum;
//
// Disable the interrupt.
//
IntDisable(ulInt);
//
// Unregister the interrupt.handler.
//
IntUnregister(ulInt);
}
//*****************************************************************************
//
//! Disables a sample sequence interrupt.
//!
//! \param ulBase is the base address of the ADC module.
//! \param ulSequenceNum is the sample sequence number.
//!
//! This function disables the requested sample sequence interrupt.
//!
//! \return None.
//
//*****************************************************************************
void
ADCIntDisable(unsigned long ulBase, unsigned long ulSequenceNum)
{
//
// Check the arguments.
//
ASSERT(ulBase == ADC_BASE);
ASSERT(ulSequenceNum < 4);
//
// Disable this sample sequence interrupt.
//
HWREG(ulBase + ADC_O_IM) &= ~(1 << ulSequenceNum);
}
//*****************************************************************************
//
//! Enables a sample sequence interrupt.
//!
//! \param ulBase is the base address of the ADC module.
//! \param ulSequenceNum is the sample sequence number.
//!
//! This function enables the requested sample sequence interrupt. Any
//! outstanding interrupts are cleared before enabling the sample sequence
//! interrupt.
//!
//! \return None.
//
//*****************************************************************************
void
ADCIntEnable(unsigned long ulBase, unsigned long ulSequenceNum)
{
//
// Check the arguments.
//
ASSERT(ulBase == ADC_BASE);
ASSERT(ulSequenceNum < 4);
//
// Clear any outstanding interrupts on this sample sequence.
//
HWREG(ulBase + ADC_O_ISC) = 1 << ulSequenceNum;
//
// Enable this sample sequence interrupt.
//
HWREG(ulBase + ADC_O_IM) |= 1 << ulSequenceNum;
}
//*****************************************************************************
//
//! Gets the current interrupt status.
//!
//! \param ulBase is the base address of the ADC module.
//! \param ulSequenceNum is the sample sequence number.
//! \param bMasked is false if the raw interrupt status is required and true if
//! the masked interrupt status is required.
//!
//! This returns the interrupt status for the specified sample sequence.
//! Either the raw interrupt status or the status of interrupts that are
//! allowed to reflect to the processor can be returned.
//!
//! \return The current raw or masked interrupt status.
//
//*****************************************************************************
unsigned long
ADCIntStatus(unsigned long ulBase, unsigned long ulSequenceNum,
tBoolean bMasked)
{
//
// Check the arguments.
//
ASSERT(ulBase == ADC_BASE);
ASSERT(ulSequenceNum < 4);
//
// Return either the interrupt status or the raw interrupt status as
// requested.
//
if(bMasked)
{
return(HWREG(ulBase + ADC_O_ISC) & (1 << ulSequenceNum));
}
else
{
return(HWREG(ulBase + ADC_O_RIS) & (1 << ulSequenceNum));
}
}
//*****************************************************************************
//
//! Clears sample sequence interrupt source.
//!
//! \param ulBase is the base address of the ADC module.
//! \param ulSequenceNum is the sample sequence number.
//!
//! The specified sample sequence interrupt is cleared, so that it no longer
//! asserts. This must be done in the interrupt.handler to keep it from being
//! called again immediately upon exit.
//!
//! \return None.
//
//*****************************************************************************
void
ADCIntClear(unsigned long ulBase, unsigned long ulSequenceNum)
{
//
// Check the arugments.
//
ASSERT(ulBase == ADC_BASE);
ASSERT(ulSequenceNum < 4);
//
// Clear the interrupt.
//
HWREG(ulBase + ADC_O_ISC) = 1 << ulSequenceNum;
}
//*****************************************************************************
//
//! Enables a sample sequence.
//!
//! \param ulBase is the base address of the ADC module.
//! \param ulSequenceNum is the sample sequence number.
//!
//! Allows the specified sample sequence to be captured when its trigger is
//! detected. A sample sequence must be configured before it is enabled.
//!
//! \return None.
//
//*****************************************************************************
void
ADCSequenceEnable(unsigned long ulBase, unsigned long ulSequenceNum)
{
//
// Check the arugments.
//
ASSERT(ulBase == ADC_BASE);
ASSERT(ulSequenceNum < 4);
//
// Enable the specified sequence.
//
HWREG(ulBase + ADC_O_ACTSS) |= 1 << ulSequenceNum;
}
//*****************************************************************************
//
//! Disables a sample sequence.
//!
//! \param ulBase is the base address of the ADC module.
//! \param ulSequenceNum is the sample sequence number.
//!
//! Prevents the specified sample sequence from being captured when its trigger
//! is detected. A sample sequence should be disabled before it is configured.
//!
//! \return None.
//
//*****************************************************************************
void
ADCSequenceDisable(unsigned long ulBase, unsigned long ulSequenceNum)
{
//
// Check the arugments.
//
ASSERT(ulBase == ADC_BASE);
ASSERT(ulSequenceNum < 4);
//
// Disable the specified sequences.
//
HWREG(ulBase + ADC_O_ACTSS) &= ~(1 << ulSequenceNum);
}
//*****************************************************************************
//
//! Configures the trigger source and priority of a sample sequence.
//!
//! \param ulBase is the base address of the ADC module.
//! \param ulSequenceNum is the sample sequence number.
//! \param ulTrigger is the trigger source that initiates the sample sequence;
//! must be one of the \b ADC_TRIGGER_* values.
//! \param ulPriority is the relative priority of the sample sequence with
//! respect to the other sample sequences.
//!
//! This function configures the initiation criteria for a sample sequence.
//! Valid sample sequences range from zero to three; sequence zero will capture
//! up to eight samples, sequences one and two will capture up to four samples,
//! and sequence three will capture a single sample. The trigger condition and
//! priority (with respect to other sample sequence execution) is set.
//!
//! The parameter \b ulTrigger can take on the following values:
//!
//! - \b ADC_TRIGGER_PROCESSOR - A trigger generated by the processor, via the
//! ADCProcessorTrigger() function.
//! - \b ADC_TRIGGER_COMP0 - A trigger generated by the first analog
//! comparator; configured with ComparatorConfigure().
//! - \b ADC_TRIGGER_COMP1 - A trigger generated by the second analog
//! comparator; configured with ComparatorConfigure().
//! - \b ADC_TRIGGER_COMP2 - A trigger generated by the third analog
//! comparator; configured with ComparatorConfigure().
//! - \b ADC_TRIGGER_EXTERNAL - A trigger generated by an input from the Port
//! B4 pin.
//! - \b ADC_TRIGGER_TIMER - A trigger generated by a timer; configured with
//! TimerControlTrigger().
//! - \b ADC_TRIGGER_PWM0 - A trigger generated by the first PWM generator;
//! configured with PWMGenIntTrigEnable().
//! - \b ADC_TRIGGER_PWM1 - A trigger generated by the second PWM generator;
//! configured with PWMGenIntTrigEnable().
//! - \b ADC_TRIGGER_PWM2 - A trigger generated by the third PWM generator;
//! configured with PWMGenIntTrigEnable().
//! - \b ADC_TRIGGER_ALWAYS - A trigger that is always asserted, causing the
//! sample sequence to capture repeatedly (so long as
//! there is not a higher priority source active).
//!
//! Note that not all trigger sources are available on all Stellaris family
//! members; consult the data sheet for the device in question to determine the
//! availability of triggers.
//!
//! The parameter \b ulPriority is a value between 0 and 3, where 0 represents
//! the highest priority and 3 the lowest. Note that when programming the
//! priority among a set of sample sequences, each must have unique priority;
//! it is up to the caller to guarantee the uniqueness of the priorities.
//!
//! \return None.
//
//*****************************************************************************
void
ADCSequenceConfigure(unsigned long ulBase, unsigned long ulSequenceNum,
unsigned long ulTrigger, unsigned long ulPriority)
{
//
// Check the arugments.
//
ASSERT(ulBase == ADC_BASE);
ASSERT(ulSequenceNum < 4);
ASSERT((ulTrigger == ADC_TRIGGER_PROCESSOR) ||
(ulTrigger == ADC_TRIGGER_COMP0) ||
(ulTrigger == ADC_TRIGGER_COMP1) ||
(ulTrigger == ADC_TRIGGER_COMP2) ||
(ulTrigger == ADC_TRIGGER_EXTERNAL) ||
(ulTrigger == ADC_TRIGGER_TIMER) ||
(ulTrigger == ADC_TRIGGER_PWM0) ||
(ulTrigger == ADC_TRIGGER_PWM1) ||
(ulTrigger == ADC_TRIGGER_PWM2) ||
(ulTrigger == ADC_TRIGGER_ALWAYS));
ASSERT(ulPriority < 4);
//
// Compute the shift for the bits that control this sample sequence.
//
ulSequenceNum *= 4;
//
// Set the trigger event for this sample sequence.
//
HWREG(ulBase + ADC_O_EMUX) = ((HWREG(ulBase + ADC_O_EMUX) &
~(0xf << ulSequenceNum)) |
((ulTrigger & 0xf) << ulSequenceNum));
//
// Set the priority for this sample sequence.
//
HWREG(ulBase + ADC_O_SSPRI) = ((HWREG(ulBase + ADC_O_SSPRI) &
~(0xf << ulSequenceNum)) |
((ulPriority & 0x3) << ulSequenceNum));
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -