?? sensors.c
字號:
//*****************************************************************************
//
// sensors.c - Code for sampling the car sensors.
//
// 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_adc.h"
#include "../../hw_ints.h"
#include "../../hw_memmap.h"
#include "../../hw_nvic.h"
#include "../../hw_timer.h"
#include "../../hw_types.h"
#include "compiler.h"
#include "random.h"
#include "sensors.h"
#include "system.h"
//*****************************************************************************
//
//! \page sensors_intro Introduction
//!
//! There are three infra-red ranging sensors on the car; one is pointed
//! forward, one is pointed approximately 30 degrees to the left, and one is
//! pointed approximately 30 degrees to the right. These sensors are used to
//! determine the presence of and distance to obstacles. The sensors provide
//! an analog voltage that is inversely proportional to the measured distance.
//!
//! Additionally, there is a current sense resistor on the low side of the two
//! H bridges for the motors that provides a voltage proportional to the
//! current through the two bridges, and there is an internal temperature
//! sensor measuring junction temperature of the microcontroller itself.
//!
//! All of these analog signals are sampled in a periodic fashion in order to
//! obtain knowledge about the environment in which the car resides. The
//! captured data is inserted into the entropy pool for the random number
//! generator, and is low pass filtered for use by the car's decision making
//! process.
//!
//! The code for handling the sensors is contained in <tt>sensors.c</tt>,
//! with <tt>sensors.h</tt> containing the API definitions for use by the
//! remainder of the application.
//
//*****************************************************************************
//*****************************************************************************
//
//! \defgroup sensors_api Definitions
//! @{
//
//*****************************************************************************
//*****************************************************************************
//
//! The current averaged samples from the ADC for all five ADC inputs (three
//! ranging sensors in samples zero through two, the motor bridge current in
//! sample three, and the internal temperature sensor in sample four).
//!
//! The contents of this array may change at any time (in response to an ADC
//! interrupt), so any processing which depends upon these values begin stable
//! should copy them locally and use the local copies for any processing.
//
//*****************************************************************************
ZERO_INIT unsigned short g_pusSamples[5];
//*****************************************************************************
//
//! Handles the ADC sequence 0 interrupt.
//!
//! This function is called when ADC sequence 0 generates an interrupt. The
//! newly captured samples are read from the ADC FIFO and feed through the low
//! pass filter into the set of current averaged samples. The low order byte
//! of the raw sample is placed into the entropy pool as environmental data.
//!
//! The low pass filter is a single pole IIR with coefficients a0 = 0.1 and
//! b1 = 0.9. The filter is processed in the integer domain with a fixed-point
//! 16.16 representation.
//!
//! \return None.
//
//*****************************************************************************
void
ADC0IntHandler(void)
{
unsigned long ulIdx, ulData;
//
// Clear the ADC interrupt.
//
HWREG(ADC_BASE + ADC_O_ISC) = ADC_ISC_IN0;
//
// Loop through the five new samples.
//
for(ulIdx = 0; ulIdx < 5; ulIdx++)
{
//
// Read this sample.
//
ulData = HWREG(ADC_BASE + ADC_O_SSFIFO0);
//
// Add the sample to the bucket.
//
g_pusSamples[ulIdx] = (((g_pusSamples[ulIdx] * 58982) +
(ulData * 6554)) / 65536);
//
// Add the sample to the entropy pool.
//
RandomAddEntropy(ulData);
}
//
// Remove any remaining samples from the FIFO. There should be none, but
// if there are it will forever mix up the ordering that is read above.
//
while(!(HWREG(ADC_BASE + ADC_O_SSFSTAT0) & ADC_SSFSTAT_EMPTY))
{
HWREG(ADC_BASE + ADC_O_SSFIFO0);
}
}
//*****************************************************************************
//
//! Configures the sensors.
//!
//! This function prepares the sensors for normal operation. The ADC is
//! configured to capture all five of its inputs (four input pins and the
//! internal temperature sensor) at a fixed rate, triggered by the expiration
//! of a timer.
//!
//! \return None.
//
//*****************************************************************************
void
SensorsInit(void)
{
//
// Configure and enable the first sample sequencer.
//
HWREG(ADC_BASE + ADC_O_EMUX) = ADC_EMUX_EM0_TIMER;
HWREG(ADC_BASE + ADC_O_SSMUX0) = ((0 << ADC_SSMUX_MUX0_SHIFT) |
(1 << ADC_SSMUX_MUX1_SHIFT) |
(2 << ADC_SSMUX_MUX2_SHIFT) |
(3 << ADC_SSMUX_MUX3_SHIFT));
HWREG(ADC_BASE + ADC_O_SSCTL0) = (ADC_SSCTL_TS4 | ADC_SSCTL_IE4 |
ADC_SSCTL_END4);
HWREG(ADC_BASE + ADC_O_ACTSS) = ADC_ACTSS_ASEN0;
//
// Enable the ADC interrupt.
//
HWREG(ADC_BASE + ADC_O_IM) = ADC_IM_MASK0;
HWREG(NVIC_EN0) = 1 << (INT_ADC0 - 16);
//
// Configure the timer as two 16-bit timers.
//
HWREG(TIMER2_BASE + TIMER_O_CFG) = TIMER_CFG_16_BIT;
//
// Configure timer B as a periodic timer.
//
HWREG(TIMER2_BASE + TIMER_O_TBMR) = TIMER_TNMR_TNTMR_PERIOD;
//
// Set the period on timer B so that it times out every 1/500th of a
// second.
//
HWREG(TIMER2_BASE + TIMER_O_TBPR) = 15;
HWREG(TIMER2_BASE + TIMER_O_TBILR) = (SYSTEM_CLOCK / (500 * 16)) - 1;
//
// Enable timer B.
//
HWREG(TIMER2_BASE + TIMER_O_CTL) |= TIMER_CTL_TBOTE | TIMER_CTL_TBEN;
}
//*****************************************************************************
//
// Close the Doxygen group.
//! @}
//
//*****************************************************************************
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -