📄 ui_onboard.c
字号:
//*****************************************************************************
//
// ui_onboard.c - A simple control interface utilizing push button(s) and a
// potentiometer on the board.
//
// Copyright (c) 2006-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 716 of the BLDC motor application.
//
//*****************************************************************************
#include "ui_onboard.h"
//*****************************************************************************
//
//! \page ui_onboard_intro Introduction
//!
//! The on-board user interface consists of a push button and a potentiometer.
//! The push button triggers actions when pressed, released, and when held for
//! a period of time. The potentiometer specifies the value of a parameter.
//!
//! The push button is debounced using a vertical counter. A vertical counter
//! is a method where each bit of the counter is stored in a different word,
//! and multiple counters can be incremented simultaneously. They work really
//! well for debouncing switches; up to 32 switches can be debounced at the
//! same time. Although only one switch is used, the code is already capable
//! of debouncing an additional 31 switches.
//!
//! A callback function can be called when the switch is pressed, when it is
//! released, and when it is held. If held, the press function will not be
//! called for that button press.
//!
//! The potentiometer input is passed through a low-pass filter and then a
//! stable value detector. The low-pass filter reduces the noise introduced
//! by the potentiometer and the ADC. Even the low-pass filter does not remove
//! all the noise and does not produce an unchanging value when the
//! potentiometer is not being turned. Therefore, a stable value detector is
//! used to find when the potentiometer value is only changing slightly. When
//! this occurs, the output value is held constant until the potentiometer
//! value has changed significantly. Because of this, the parameter value that
//! is adjusted by the potentiometer will not jitter around when the
//! potentiometer is left alone.
//!
//! The application is responsible for reading the value of the switch(es) and
//! the potentiometer on a periodic basis. The routines provided here perform
//! all the processing of those values.
//!
//! The code for handling the on-board user interface elements is contained in
//! <tt>ui_onboard.c</tt>, with <tt>ui_onboard.h</tt> containing the
//! definitions for the structures and functions exported to the remainder of
//! the application.
//
//*****************************************************************************
//*****************************************************************************
//
//! \defgroup ui_onboard_api Definitions
//! @{
//
//*****************************************************************************
//*****************************************************************************
//
//! The debounced state of the switches.
//
//*****************************************************************************
static unsigned long g_ulUIOnboardSwitches;
//*****************************************************************************
//
//! This is the low order bit of the clock used to count the number of samples
//! with the switches in the non-debounced state.
//
//*****************************************************************************
static unsigned long g_ulUIOnboardClockA;
//*****************************************************************************
//
//! This is the high order bit of the clock used to count the number of samples
//! with the switches in the non-debounced state.
//
//*****************************************************************************
static unsigned long g_ulUIOnboardClockB;
//*****************************************************************************
//
//! The value of the potentiometer after being passed through the single pole
//! IIR low pass filter.
//
//*****************************************************************************
static unsigned long g_ulUIOnboardPotValue;
//*****************************************************************************
//
//! The detected stable value of the potentiometer. This will be 0xffff.ffff
//! when the value of the potentiometer is changing and will be a value within
//! the potentiometer range when the potentiometer value is stable.
//
//*****************************************************************************
static unsigned long g_ulUIOnboardFilteredPotValue;
//*****************************************************************************
//
//! The minimum value of the potentiometer over a small period. This is used
//! to detect a stable value of the potentiometer.
//
//*****************************************************************************
static unsigned long g_ulUIOnboardPotMin;
//*****************************************************************************
//
//! The maximum value of the potentiometer over a small period. This is used
//! to detect a stable value of the potentiometer.
//
//*****************************************************************************
static unsigned long g_ulUIOnboardPotMax;
//*****************************************************************************
//
//! An accumulator of the low pass filtered potentiometer values for a small
//! period. When a stable potentiometer value is detected, this is used to
//! compute the average value (and therefore the stable value of the
//! potentiometer).
//
//*****************************************************************************
static unsigned long g_ulUIOnboardPotSum;
//*****************************************************************************
//
//! The count of samples that have been collected into the accumulator
//! (g_ulUIOnboardPotSum).
//
//*****************************************************************************
static unsigned long g_ulUIOnboardPotCount;
//*****************************************************************************
//
//! Debounces a set of switches.
//!
//! \param ulSwitches is the current state of the switches.
//!
//! This function takes a set of switch inputs and performs software debouncing
//! of their state. Changes in the debounced state of a switch are reflected
//! back to the application via callback functions. For each switch, a press
//! can be distinguished from a hold, allowing two functions to coexist on a
//! single switch; a separate callback function is called for a hold as opposed
//! to a press.
//!
//! For best results, the switches should be sampled and passed to this
//! function on a periodic basis. Randomness in the sampling time may result
//! in degraded performance of the debouncing routine.
//!
//! \return None.
//
//*****************************************************************************
void
UIOnboardSwitchDebouncer(unsigned long ulSwitches)
{
unsigned long ulDelta, ulIdx;
//
// Determine the switches that are at a different state than the debounced
// state.
//
ulDelta = ulSwitches ^ g_ulUIOnboardSwitches;
//
// Increment the clocks by one.
//
g_ulUIOnboardClockA ^= g_ulUIOnboardClockB;
g_ulUIOnboardClockB = ~g_ulUIOnboardClockB;
//
// Reset the clocks corresponding to switches that have not changed state.
//
g_ulUIOnboardClockA &= ulDelta;
g_ulUIOnboardClockB &= ulDelta;
//
// Get the new debounced switch state.
//
g_ulUIOnboardSwitches &= (g_ulUIOnboardClockA | g_ulUIOnboardClockB);
g_ulUIOnboardSwitches |= ((~(g_ulUIOnboardClockA | g_ulUIOnboardClockB)) &
ulSwitches);
//
// Determine the switches that just changed debounced state.
//
ulDelta ^= (g_ulUIOnboardClockA | g_ulUIOnboardClockB);
//
// Loop through all of the switches.
//
for(ulIdx = 0; ulIdx < g_ulUINumButtons; ulIdx++)
{
//
// See if this switch just changed state.
//
if(ulDelta & (1 << g_sUISwitches[ulIdx].ucBit))
{
//
// See if the switch was just pressed or released.
//
if(!(g_ulUIOnboardSwitches & (1 << g_sUISwitches[ulIdx].ucBit)))
{
//
// The switch was just pressed. If there is no hold defined
// and there is a press function to call then call it now.
//
if((g_sUISwitches[ulIdx].ulHoldTime == 0) &&
g_sUISwitches[ulIdx].pfnPress)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -