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

📄 stm8_tsl_rc_multichannelkey.c

📁 STM8-触摸例程
💻 C
📖 第 1 页 / 共 3 页
字号:
u8 TSL_MCKey_Position(void)
{

  u8 Index1, Index2;
#if CHANNEL_PER_MCKEY == 8  
  u8 Index3;
#endif
  u16 Major, Minor, SectorComputation;
  s16 NewPosition;
  u8 uNewPosition;
  u32 tmpdelta;
  u8 PositionCorrection;
  u8 retval = 0x00;
  
  Delta1 = 0;
  Delta2 = 0;
  Delta3 = 0;

  Index1 = 0;
  Index2 = 0;
#if CHANNEL_PER_MCKEY == 8  
  Index3 = 0;
#endif

  for ( ChannelIndex = 0; ChannelIndex < CHANNEL_PER_MCKEY; ChannelIndex++ )
  {
    
    TSL_MCKey_DeltaCalculation( ChannelIndex );
   
    // Delta must be positive only otherwise it is noise
    if ( Delta < 0 )
    {
      Delta = 0;
    }
    
    /* We normalize the Delta */
    tmpdelta = (u32)(Delta * (u32)(pMCKeyStruct->Channel[0].Reference));
    tmpdelta = tmpdelta / pMCKeyStruct->Channel[ChannelIndex].Reference;
    Delta = (s16)tmpdelta;
   
    /* Apply a fixed coefficient */
#if NUMBER_OF_MULTI_CHANNEL_KEYS > 1
  if (KeyIndex == 0) // MCKEY1
    {
#endif
      if (MCKEY1_DELTA_COEFF[ChannelIndex] != 0x0100)
      {
        tmpdelta = (u32)(Delta * MCKEY1_DELTA_COEFF[ChannelIndex]);
        Delta = (s16)(tmpdelta >> (u8)8);
      }
#if NUMBER_OF_MULTI_CHANNEL_KEYS > 1
    }   
    else // MCKEY2
    {
      if (MCKEY2_DELTA_COEFF[ChannelIndex] != 0x0100)
      {
        tmpdelta = (u32)(Delta * MCKEY2_DELTA_COEFF[ChannelIndex]);
        Delta = (s16)(tmpdelta >> (u8)8);
      }
    }
#endif
   
    /* Sort the biggest, middle and lowest signals measured
       - Delta1 and Index1 = biggest
       - Delta2 and Index2 = middle
       - Delta3 and Index3 = lowest */
    if ( Delta > Delta1 )
    {
      Delta3 = Delta2;
      Delta2 = Delta1;
      Delta1 = Delta;
#if CHANNEL_PER_MCKEY == 8
      Index3 = Index2;
#endif
      Index2 = Index1;
      Index1 = ChannelIndex;
    }
    else
    {
      if ( Delta > Delta2 )
      {
        Delta3 = Delta2;
        Delta2 = Delta;
#if CHANNEL_PER_MCKEY == 8        
        Index3 = Index2;
#endif
        Index2 = ChannelIndex;
      }
      else
      {
        if ( Delta > Delta3 )
        {
#if CHANNEL_PER_MCKEY == 8          
          Index3 = ChannelIndex;
#endif
          Delta3 = Delta;
        }
      }
    }

  } /* for all channels */

  /* Noise filter: we need at least two significant Delta measurements */
  if (Delta2 < ((u8)(pMCKeyStruct->EndDetectThreshold >> 1)) - 1)
  {
    return retval;
  }

  //----------------------------------------------------------------------------
  // Position calculation...
  //----------------------------------------------------------------------------
  
  /*----------------------------------------------------------------------------
    B = Biggest signal measured (Delta1/Index1)
    M = Middle signal measured (Delta2/Index2)
    S = Smallest signal measured (Delta3/Index3)
    
    - The equation to find the position is:
      Position = Offset +/- [ Sector_Size x ( Major / (Major + Minor) ) ]
   
    - The Offset is the position of the middle of the Middle signal segment.
      All the Offset values are stored in the ROM table Table_POSITION_OFFSET.
   
    - Major = Biggest - Smallest signals
      Minor = Middle - Smallest signals
   
    - The Sector_Size depends of the number of channels used
  ----------------------------------------------------------------------------*/

  /* Calculates the Major and Minor parameters */
  Minor = Delta2 - Delta3; // Middle - Smallest signals
  Major = Delta1 - Delta3; // Biggest - Smallest signals

#if NUMBER_OF_MULTI_CHANNEL_KEYS > 1
  if (KeyIndex == 0) // MCKEY1
  {
#endif
    NewPosition = MCKEY1_TABLE_POSITION_OFFSET[Index1][Index2];
    SectorComputation = MCKEY1_SECTOR_COMPUTATION;
    PositionCorrection = MCKEY1_POSITION_CORRECTION;
#if NUMBER_OF_MULTI_CHANNEL_KEYS > 1
  }
  else // MCKEY2
  {
    NewPosition = MCKEY2_TABLE_POSITION_OFFSET[Index1][Index2];
    SectorComputation = MCKEY2_SECTOR_COMPUTATION;
    PositionCorrection = MCKEY2_POSITION_CORRECTION;
  }
#endif

  /* Calculates: [ Sector_Size x ( Major / (Major + Minor) ) ] */
  SectorComputation = Major * SectorComputation;
  SectorComputation = SectorComputation / ( Major + Minor );

  // Use the sign bit from table to define the interpretation direction.
  // The NewPosition is multiplied by 2 because the Offset stored in the ROM
  // table is divided by 2...
  if ( NewPosition > 0 ) // means Offset is > 0 in the ROM table
  {
    NewPosition = (s16)(NewPosition << 1); /*lint !e701 suppress info on this line only */
    NewPosition += SectorComputation;
  }
  else // means Offset is <= 0 in the ROM table
  {
    NewPosition = (s16)((-NewPosition) << 1); /*lint !e701 suppress info on this line only */
    NewPosition -= SectorComputation;
  }

  if (pMCKeyStruct->Setting.b.MCKEY_TYPE) // It's a Slider...
  {
    
    /* First adjustment used to shift all the values to obtain the "zero" */
    if (NewPosition > 0)
    {
      NewPosition -= PositionCorrection;
    }
    else
    {
      NewPosition = NewPosition + 256 - PositionCorrection;
    }
    
    /* Second adjustment used to clamp the values at extremities of slider */
    if (NewPosition < 0)
    {
      NewPosition = 0;
    }
    
    if (NewPosition > 255)
    {
      NewPosition = 255;
    }
   
  }
  else // It's a Wheel: we keep only the low byte
  {
    NewPosition = (u8)NewPosition;
  }
  
  //----------------------------------------------------------------------------
  // Direction Change Process
  //----------------------------------------------------------------------------

#if MCKEY_DIRECTION_CHANGE_ENABLED > 0

  if (pMCKeyStruct->Setting.b.DIRECTION) // Anticlockwise direction ...
  {
   
    // Check Direction changed and Position overflow from 0x00 to 0xFF not realized !
    if ( ((u8)NewPosition > pMCKeyStruct->UnScaledPosition) && (((u8)NewPosition - pMCKeyStruct->UnScaledPosition) < MCKEY_DIRECTION_CHANGE_MAX_DISPLACEMENT) )
    {
      if ( NewPosition < (u16)(pMCKeyStruct->UnScaledPosition + pMCKeyStruct->DirectionChangeThreshold) )
      {
        pMCKeyStruct->Channel[1].IntegratorCounter = pMCKeyStruct->DirectionChangeIntegrator;
        return retval;
      }
      else
      {
        pMCKeyStruct->Channel[1].IntegratorCounter--;
        if ( !pMCKeyStruct->Channel[1].IntegratorCounter )
        {
          pMCKeyStruct->Channel[1].IntegratorCounter = pMCKeyStruct->DirectionChangeIntegrator;
          pMCKeyStruct->Setting.b.DIRECTION = 0;  // New direction accepted: clockwise.
        }
        else
        {
          return retval;
        }
      }
    }
    
    // Check position overflow from 0xFF to 0x00 to be filtered !
    if ( (NewPosition + MCKEY_DIRECTION_CHANGE_MAX_DISPLACEMENT) < pMCKeyStruct->UnScaledPosition )
    {
      if ( (NewPosition + MCKEY_DIRECTION_CHANGE_TOTAL_STEPS) < (u16)(pMCKeyStruct->UnScaledPosition + pMCKeyStruct->DirectionChangeThreshold) )
      {
        pMCKeyStruct->Channel[1].IntegratorCounter = pMCKeyStruct->DirectionChangeIntegrator;
        return retval;
      }
      else
      {
        pMCKeyStruct->Channel[1].IntegratorCounter--;
        if ( !pMCKeyStruct->Channel[1].IntegratorCounter )
        {
          pMCKeyStruct->Channel[1].IntegratorCounter = pMCKeyStruct->DirectionChangeIntegrator;
          pMCKeyStruct->Setting.b.DIRECTION = 0;  // New direction accepted: clockwise.
        }
        else
        {
          return retval;
        }
      }
    }
    
  }
  else // Clockwise direction... DEFAULT SETTING !
  {
    
    // Check Direction changed and Position overflow from 0xFF to 0x00 not realized !
    if ( ((u8)NewPosition < pMCKeyStruct->UnScaledPosition) && ((pMCKeyStruct->UnScaledPosition - (u8)NewPosition) < MCKEY_DIRECTION_CHANGE_MAX_DISPLACEMENT) )
    {
      if ( (NewPosition + pMCKeyStruct->DirectionChangeThreshold) > pMCKeyStruct->UnScaledPosition )
      {
        pMCKeyStruct->Channel[1].IntegratorCounter = pMCKeyStruct->DirectionChangeIntegrator;
        return retval;
      }
      else
      {
        pMCKeyStruct->Channel[1].IntegratorCounter--;
        if ( !pMCKeyStruct->Channel[1].IntegratorCounter )
        {
          pMCKeyStruct->Channel[1].IntegratorCounter = pMCKeyStruct->DirectionChangeIntegrator;
          pMCKeyStruct->Setting.b.DIRECTION = 1;  // New direction accepted: anticlockwise.
        }
        else
        {
          return retval;
        }
      }
    }
    
    // Check position overflow from 0x00 to 0xFF to be filtered !
    if ( NewPosition > (u16)(pMCKeyStruct->UnScaledPosition + MCKEY_DIRECTION_CHANGE_MAX_DISPLACEMENT) )
    {
      if ( (NewPosition + pMCKeyStruct->DirectionChangeThreshold) > (u16)(pMCKeyStruct->UnScaledPosition + MCKEY_DIRECTION_CHANGE_TOTAL_STEPS) )
      {
        pMCKeyStruct->Channel[1].IntegratorCounter = pMCKeyStruct->DirectionChangeIntegrator;
        return retval;
      }
      else
      {
        pMCKeyStruct->Channel[1].IntegratorCounter--;
        if ( !pMCKeyStruct->Channel[1].IntegratorCounter )
        {
          pMCKeyStruct->Channel[1].IntegratorCounter = pMCKeyStruct->DirectionChangeIntegrator;
          pMCKeyStruct->Setting.b.DIRECTION = 1;  // New direction accepted: anticlockwise.
        }
        else
        {
          return retval;
        }
      }
    }
    
  }

#endif // MCKEY_DIRECTION_CHANGE_ENABLED

  //----------------------------------------------------------------------------
  // Final result...
  //----------------------------------------------------------------------------
  
  // The UnScaledPosition parameter is always updated
  // The Position parameter is updated only if different from the previous one  

  pMCKeyStruct->UnScaledPosition = (u8)NewPosition;
  
  uNewPosition = (u8)((u8)NewPosition >> (MCKEY_RESOLUTION_CALCULATION - pMCKeyStruct->Resolution));
  
  if ( pMCKeyStruct->Position != uNewPosition )
  {
    pMCKeyStruct->Position = uNewPosition;
    pMCKeyStruct->Setting.b.POSCHANGED = 1; /* Warning: Application layer must reset this flag */
    retval = 0xFF;
  }

  return retval;
  
}


/**
  ******************************************************************************
  * @brief Check for customer code setting and adapt key state.
  * @par Parameters:
  * None
  * @retval void None
  * @par Required preconditions:
  * None
  ******************************************************************************
  */
void TSL_MCKey_CheckDisabled(void)
{

  if ( !pMCKeyStruct->Setting.b.ENABLED )
  {
    TSL_MCKey_SetDisabledState( );
  }

}


/**
  ******************************************************************************
  * @brief Check for customer code setting and adapt key state.
  * @par Parameters:
  * None
  * @retval void None
  * @par Required preconditions:
  * None
  ******************************************************************************
  */
void TSL_MCKey_CheckEnabled(void)
{

  if ( pMCKeyStruct->Setting.b.ENABLED && pMCKeyStruct->Setting.b.IMPLEMENTED )
  {
    TSL_MCKey_SetCalibrationState( );
  }

}


/**
  ******************************************************************************
  * @brief Verify the last burst sequence gave a result within the authorized range.
  * @par Parameters:
  * None
  * @retval u8 Return 0 if OK, 0xFF if Error.
  * @par Required preconditions:
  * None
  ******************************************************************************
  */
u8 TSL_MCKey_CheckErrorCondition(void)
{

  for ( ChannelIndex = 0; ChannelIndex < CHANNEL_PER_MCKEY; ChannelIndex++ )
  {
    if ( (pMCKeyStruct->Channel[ChannelIndex].LastMeas < MCKEY_MIN_ACQUISITION)
         || (pMCKeyStruct->Channel[ChannelIndex].LastMeas > MCKEY_MAX_ACQUISITION) )
    {
      return 0xFF;  // Error case !
    }
  }
  
  return 0;
  
}

//============================================================================
//-----         CONDITIONAL COMPILING FOR MCKEYS !!!               -----------
#endif
//============================================================================

/*********************** (c) 2009 STMicroelectronics **************************/

⌨️ 快捷键说明

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