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

📄 stm8_tsl_rc_services.c

📁 基于STM8 的电容按键算法, 方案便宜
💻 C
📖 第 1 页 / 共 2 页
字号:
/**
  ******************************************************************************
  * @file STM8_TSL_RC_Services.c
  * @brief RC Touch Sensing Library for STM8 CPU family.
  * Set of library internal functions.
  * @author STMicroelectronics - MCD Application Team
  * @version V1.1.0
  * @date 21-FEB-2009
  ******************************************************************************
  *
  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
  *
  * <h2><center>&copy; COPYRIGHT 2009 STMicroelectronics</center></h2>
  * @image html logo.bmp
  ******************************************************************************
  */

#include "STM8_TSL_RC_API.h"
#include "STM8_TSL_RC_Services.h"

//--------    SECTION DEFINITION FOR THIS FILE   --------------
#if defined(__CSMC__) && defined(USE_PRAGMA_SECTION)
#pragma section [TSL_RAM]
#pragma section @tiny [TSL_RAM0]
#pragma section (TSL_CODE)
#pragma section const {TSL_CONST}
#endif

//============================================================================
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//-----          SINGLE CHANNEL KEY OR COMMON KEY SERVICES               -----
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//============================================================================


/**
  ******************************************************************************
  * @brief Update pointer to current Key Structure.
  * @par Parameters:
  * None
  * @retval void None
  * @par Required preconditions:
  * None
  ******************************************************************************
  */
void TSL_SetStructPointer(void)
{
  pKeyStruct = &sSCKeyInfo[KeyIndex];
}


/**
  ******************************************************************************
  * @brief Delta calculation for the current Key structure.
  * @par Parameters:
  * None
  * @retval void None
  * @par Required preconditions:
  * None
  ******************************************************************************
  */
void TSL_DeltaCalculation(void)
{
  Delta = (s16)(pKeyStruct->Channel.LastMeas - pKeyStruct->Channel.Reference);
}


/**
  ******************************************************************************
  * @brief Short local routine to setup SCKey internal state machine.
  * Used to go to the IDLE state.
  * @par Parameters:
  * None
  * @retval void None
  * @par Required preconditions:
  * None
  ******************************************************************************
  */
void TSL_SCKey_SetIdleState(void)
{
  pKeyStruct->Setting.b.CHANGED = 1;
  TSL_SCKey_BackToIdleState();
}


/**
  ******************************************************************************
  * @brief Short local routine to setup SCKey internal state machine.
  * Used to return to the IDLE state and reset appropriate flags.
  * @par Parameters:
  * None
  * @retval void None
  * @par Required preconditions:
  * None
  ******************************************************************************
  */
void TSL_SCKey_BackToIdleState(void)
{
  pKeyStruct->State.whole = IDLE_STATE;
  pKeyStruct->Setting.b.DETECTED = 0;
  pKeyStruct->Setting.b.LOCKED = 0;
  pKeyStruct->Setting.b.ERROR = 0;
}


/**
  ******************************************************************************
  * @brief Short local routine to setup SCKey internal state machine.
  * Used to go to the PRE_DETECTED state and init integrator counter.
  * @par Parameters:
  * None
  * @retval void None
  * @par Required preconditions:
  * None
  ******************************************************************************
  */
void TSL_SCKey_SetPreDetectState(void)
{
  pKeyStruct->State.whole = PRE_DETECTED_STATE;
  pKeyStruct->Channel.IntegratorCounter = DetectionIntegrator;
}


/**
  ******************************************************************************
  * @brief Short local routine to setup SCKey internal state machine.
  * Used to go to the DETECTED state and init detection timeout + flags.
  * @par Parameters:
  * None
  * @retval void None
  * @par Required preconditions:
  * None
  ******************************************************************************
  */
void TSL_SCKey_SetDetectedState(void)
{
  pKeyStruct->State.whole = DETECTED_STATE;
  pKeyStruct->Setting.b.DETECTED = 1;
  pKeyStruct->Setting.b.CHANGED = 1;
  pKeyStruct->Counter = DetectionTimeout;
}


/**
  ******************************************************************************
  * @brief Short local routine to setup SCKey internal state machine.
  * Used to go to the POST_DETECTED state and init end integrator counter.
  * @par Parameters:
  * None
  * @retval void None
  * @par Required preconditions:
  * None
  ******************************************************************************
  */
void TSL_SCKey_SetPostDetectState(void)
{
  pKeyStruct->State.whole = POST_DETECTED_STATE;
  pKeyStruct->Channel.IntegratorCounter = EndDetectionIntegrator;
}


/**
  ******************************************************************************
  * @brief Short local routine to setup SCKey internal state machine.
  * Used to go back to the DETECTED state
  * @par Parameters:
  * None
  * @retval void None
  * @par Required preconditions:
  * None
  ******************************************************************************
  */
void TSL_SCKey_BackToDetectedState(void)
{
  pKeyStruct->State.whole = DETECTED_STATE;
}


/**
  ******************************************************************************
  * @brief Short local routine to setup SCKey internal state machine.
  * Used to go to the PRE_CALIBRATION state and init integrator counter.
  * @par Parameters:
  * None
  * @retval void None
  * @par Required preconditions:
  * None
  ******************************************************************************
  */
void TSL_SCKey_SetPreRecalibrationState(void)
{
  pKeyStruct->State.whole = PRE_CALIBRATION_STATE;
  pKeyStruct->Channel.IntegratorCounter = RecalibrationIntegrator;
}


/**
  ******************************************************************************
  * @brief Short local routine to setup SCKey internal state machine.
  * Used to go to the CALIBRATION state and init appropriate flags.
  * @par Parameters:
  * None
  * @retval void None
  * @par Required preconditions:
  * None
  ******************************************************************************
  */
void TSL_SCKey_SetCalibrationState(void)
{
  pKeyStruct->State.whole = CALIBRATION_STATE;
  pKeyStruct->Setting.b.DETECTED = 0;
  pKeyStruct->Setting.b.CHANGED = 1;
  pKeyStruct->Setting.b.LOCKED = 0;
  pKeyStruct->Setting.b.ERROR = 0;
  pKeyStruct->Counter = SCKEY_CALIBRATION_COUNT_DEFAULT;
  pKeyStruct->Channel.Reference = 0;
}


/**
  ******************************************************************************
  * @brief Short local routine to setup SCKey internal state machine.
  * Used to go to the ERROR state and init appropriate flags.
  * @par Parameters:
  * None
  * @retval void None
  * @par Required preconditions:
  * None
  ******************************************************************************
  */
void TSL_SCKey_SetErrorState(void)
{
  pKeyStruct->State.whole = ERROR_STATE;
  pKeyStruct->Setting.b.DETECTED = 0;
  pKeyStruct->Setting.b.CHANGED = 1;
  pKeyStruct->Setting.b.LOCKED = 0;
  pKeyStruct->Setting.b.ERROR = 1;
}


/**
  ******************************************************************************
  * @brief Short local routine to setup SCKey internal state machine.
  * Used to go to the DISABLE state and init appropriate flags.
  * @par Parameters:
  * None
  * @retval void None
  * @par Required preconditions:
  * None
  ******************************************************************************
  */
void TSL_SCKey_SetDisabledState(void)
{
  pKeyStruct->State.whole = DISABLED_STATE;
  pKeyStruct->Setting.b.DETECTED = 0;
  pKeyStruct->Setting.b.CHANGED = 1;
  pKeyStruct->Setting.b.LOCKED = 0;
  pKeyStruct->Setting.b.ERROR = 0;
}


/**
  ******************************************************************************
  * @brief Considers all Key information to apply the Environmental Change System (ECS).
  * Uses an IIR Filter with order 1:
  * Y(n) = K x X(n) + (1-K) x Y(n-1)
  * Y is the reference and X is the acquisition value.
  * @par Parameters:
  * None
  * @retval void None
  * @par Required preconditions:
  * None
  ******************************************************************************
  */
void TSL_ECS(void)
{

  u8 K_Filter, K_Filter_Complement;
  s8 ECS_Fast_Direction, ECS_Fast_Enable;
  u32 IIR_Result;

  disableInterrupts();
  Local_TickECS10ms = TSL_TickCount_ECS_10ms;
  TSL_TickCount_ECS_10ms = 0;
  enableInterrupts();

  while ( Local_TickECS10ms-- )
  {
    ECSTimeStepCounter--;
    ECSTempoPrescaler--;
    if ( !ECSTempoPrescaler )
    {
      ECSTempoPrescaler = 10;
      if ( ECSTempoCounter )
        ECSTempoCounter--;
    }

    K_Filter = ECS_K_Slow;   // Default case !
    ECS_Fast_Enable = 1;
    ECS_Fast_Direction = 0;
    for ( KeyIndex = 0; KeyIndex < NUMBER_OF_SINGLE_CHANNEL_KEYS; KeyIndex++ )
    {
      TSL_SetStructPointer();
      // If any key is in DETECT state, ECS is disabled !
      if ( pKeyStruct->State.whole & (PRE_DETECTED_STATE | DETECTED_STATE | POST_DETECTED_STATE) )
      {
        ECSTempoCounter = ECSTemporization;    // Restart temporization counter ...
        break;           // Out from the for loop
      }
      if ( pKeyStruct->State.whole == IDLE_STATE )
      {
        TSL_DeltaCalculation();
        if ( Delta == 0 )  // No Fast ECS !
          ECS_Fast_Enable = 0;
        else
        {
          if ( Delta < 0 )
          {
            if ( ECS_Fast_Direction > 0 )  // No Fast ECS !
              ECS_Fast_Enable = 0;
            else
              ECS_Fast_Direction = -1;
          }
          else
          {
            if ( ECS_Fast_Direction < 0 )  // No Fast ECS !
              ECS_Fast_Enable = 0;
            else
              ECS_Fast_Direction = + 1;
          }
        }
      }
    }

#if NUMBER_OF_MULTI_CHANNEL_KEYS > 0
    for ( KeyIndex = 0; KeyIndex < NUMBER_OF_MULTI_CHANNEL_KEYS; KeyIndex++ )
    {
      TSL_MCKey_SetStructPointer();
      if ( pMCKeyStruct->State.whole & (PRE_DETECTED_STATE | DETECTED_STATE | POST_DETECTED_STATE) )
      {
        ECSTempoCounter = ECSTemporization;    // Restart temporization counter ...
        break;           // Out from the for loop
      }
      if ( pMCKeyStruct->State.whole == IDLE_STATE )
      {
        for ( ChannelIndex = 0; ChannelIndex < CHANNEL_PER_MCKEY; ChannelIndex++ )
        {
          TSL_MCKey_DeltaCalculation( ChannelIndex );
          Delta1 += Delta;
        }
        if ( Delta1 == 0 )
        {   // No Fast ECS !
          ECS_Fast_Enable = 0;
        }
        else
        {
          if ( Delta1 < 0 )
          {
            if ( ECS_Fast_Direction > 0 )
            {   // No Fast ECS !
              ECS_Fast_Enable = 0;
            }
            else
              ECS_Fast_Direction = -1;
          }
          else
          {
            if ( ECS_Fast_Direction < 0 )
            {   // No Fast ECS !
              ECS_Fast_Enable = 0;
            }
            else
              ECS_Fast_Direction = + 1;
          }
        }
      }
    }
#endif

    if ( !ECSTimeStepCounter && !ECSTempoCounter )
    {
      ECSTimeStepCounter = ECSTimeStep;

      if (ECS_Fast_Enable)
      {
        K_Filter = ECS_K_Fast;
      }

      K_Filter_Complement = (u8)((0xFF ^ K_Filter) + 1);

      if ( K_Filter )
      {
        // Apply filter to generate new reference value.
        for ( KeyIndex = 0; KeyIndex < NUMBER_OF_SINGLE_CHANNEL_KEYS; KeyIndex++ )
        {
          TSL_SetStructPointer();
          if ( pKeyStruct->State.whole == IDLE_STATE )
          {
            IIR_Result = ((u32)(pKeyStruct->Channel.Reference) << 8) + pKeyStruct->Channel.ECSRefRest;
            IIR_Result = K_Filter_Complement * IIR_Result;
            IIR_Result += K_Filter * ((u32)(pKeyStruct->Channel.LastMeas) << 8);
            pKeyStruct->Channel.Reference = (u16)(IIR_Result >> 16);
            pKeyStruct->Channel.ECSRefRest = (u8)(IIR_Result >> 8);
          }
        }
#if NUMBER_OF_MULTI_CHANNEL_KEYS > 0
        for ( KeyIndex = 0; KeyIndex < NUMBER_OF_MULTI_CHANNEL_KEYS; KeyIndex++ )
        {
          TSL_MCKey_SetStructPointer();
          if ( pMCKeyStruct->State.whole == IDLE_STATE )
          {
            for ( ChannelIndex = 0; ChannelIndex < CHANNEL_PER_MCKEY; ChannelIndex++ )
            {
              IIR_Result = ((u32)(pMCKeyStruct->Channel[ChannelIndex].Reference) << 8) + pMCKeyStruct->Channel[ChannelIndex].ECSRefRest;
              IIR_Result = K_Filter_Complement * IIR_Result;
              IIR_Result += K_Filter * ((u32)(pMCKeyStruct->Channel[ChannelIndex].LastMeas) << 8);
              pMCKeyStruct->Channel[ChannelIndex].Reference = (u16)(IIR_Result >> 16);
              pMCKeyStruct->Channel[ChannelIndex].ECSRefRest = (u8)(IIR_Result >> 8);
            }
          }
        }
#endif
      }
    }
  }
}


/**
  ******************************************************************************
  * @brief Apply Detection Exclusion System algorithm (DES).
  * This function modify the LOCKED bit of current Key structure only.
  * @par Parameters:
  * None
  * @retval void None
  * @par Required preconditions:
  * None
  ******************************************************************************
  */
void TSL_SCKey_DES(void)
{

  u8 DESGroupMask, KeyToCheck;

  if ( pKeyStruct->Setting.b.LOCKED )
    return;

  DESGroupMask = pKeyStruct->DESGroup;

  for ( KeyToCheck = 0; KeyToCheck < NUMBER_OF_SINGLE_CHANNEL_KEYS; KeyToCheck++ )
  {
    if ( KeyToCheck != KeyIndex )
    {
      // KeyToCheck and current key are in same group ?
      if ( sSCKeyInfo[KeyToCheck].DESGroup & DESGroupMask )
      {
        if ( sSCKeyInfo[KeyToCheck].Setting.b.LOCKED )
        {
          goto ExitToIdle;
        }
      }
    }
  }

#if NUMBER_OF_MULTI_CHANNEL_KEYS > 0
  for ( KeyToCheck = 0; KeyToCheck < NUMBER_OF_MULTI_CHANNEL_KEYS; KeyToCheck++ )

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -