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

📄 ui_onboard.c

📁 Luminary Micro BLDC motor control software
💻 C
📖 第 1 页 / 共 2 页
字号:
//*****************************************************************************
//
// 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 + -