STM32 TSC 触摸滑条算法笔记

/ 0评 / 5

触摸按键算法基本没用到,因为可以直接判断阈值也行.但是滑条就要计算了.所以就有一个方法叫CalcPos.
首先触摸是需要先配置好采样,一般来说,实现滑条最小需要3个通道.中间和两边,这也是ST算法用到的最精简方式,看他代码也就知道.

TSL_Status_enum_T TSL_linrot_CalcPos(void)
{
  TSL_tIndex_T idx;
  TSL_ChannelData_T *p_Ch = TSL_Globals.This_LinRot->p_ChD;
  TSL_tDelta_T norm_delta;
  static TSL_tDelta_T delta1;
  static TSL_tDelta_T delta2;
  static TSL_tDelta_T delta3;
  static TSL_tIndex_T index1;
  static TSL_tIndex_T index2;
  TSL_tNb_T minor;
  TSL_tNb_T major;
  TSL_tNb_T sector_computation = 0;
  TSL_tNb_T position_correction = 0;
  TSL_tsignPosition_T new_position = 0;
  TSL_tPosition_T u_new_position = 0;
  delta1 = 0;
  delta2 = 0;
  delta3 = 0;
  index1 = 0;
  index2 = 0;
  // The position change flag will be set only if a new position is detected.
  THIS_POSCHANGE = TSL_STATE_NOT_CHANGED;
  // The position is calculated only if the number of channels is greater than 2
  if (THIS_NB_CHANNELS < 3)
  {
    return TSL_STATUS_ERROR;
  }

所以,我们的STM32F072-DISCO也是有3个通道,共6个IO连着的(好心疼IO,数量不够用啊.)
然后使用排序算法,选出最大,最小,中间的数值,先不用管是干嘛的,反正他就选出.

  //--------------------------------------------------------------------------
  // Sort the channels' delta
  //   - delta1 and index1 = biggest
  //   - delta2 and index2 = middle
  //   - delta3 and index3 = lowest
  //--------------------------------------------------------------------------
  for (idx = 0; idx < THIS_NB_CHANNELS; idx++)
  {
#if TSLPRM_LINROT_USE_NORMDELTA > 0
    norm_delta = TSL_linrot_NormDelta(p_Ch, idx); // Normalize the Delta
#else
    norm_delta = p_Ch->Delta; // Take only the Delta
#endif
    // The Delta must be positive only otherwise it is noise
    if (norm_delta < 0) {norm_delta = 0;}
    if (norm_delta > delta1)
    {
      delta3 = delta2;
      delta2 = delta1;
      delta1 = norm_delta;
      index2 = index1;
      index1 = idx;
    }
    else
    {
      if (norm_delta > delta2)
      {
        delta3 = delta2;
        delta2 = norm_delta;
        index2 = idx;
      }
      else
      {
        if (norm_delta > delta3)
        {
          delta3 = norm_delta;
        }
      }
    }
    p_Ch++; // Next channel
  } // for all channels

我现在使用的例程是TouchSensing_Linear_IT,所以在HAL_TSC_ConvCpltCallback里面处理事务.实际上,也就是在这里改变Delta的数值.直接进入Debug模式,看到采样数值中,Meas,也就是直接读取寄存器的.数值是:

其实p_chData是个数组,只是IDE没识别出来.因为Delta算法是:

(TSL_Globals.Bank_Array[0]).p_chData[idx].Delta = ((TSL_tDelta_T)((TSL_Globals.Bank_Array[0]).p_chData[idx].Ref - (TSL_Globals.Bank_Array[0]).p_chData[idx].Meas));

所以,执行后Detla就是-1976,因为是负数,会被判断为噪音,无效的.下一次采样时候,Meas就是寄存器数值.然后Ref是个稳定参考了,以后都不会改变,Delta就是Ref和Meas的差距.

画风一变,进入到CalcPos下,看重要实现.当delta大于一个阈值时候,就会进入.

  // Noise filter: we need at least two significant Delta measurements
  if (delta2 < ((TSL_tThreshold_T)(THIS_DETECTOUT_TH >> 1) - 1))
  {
    return TSL_STATUS_ERROR;
  }

如图:

主要算法是下面的注释:

这个是调理前坐标.

实际上后面的调理算法非常简单.按着看就知道了.但是对于他为什么能计算,我还不是很明白.
总结起来,ST的触摸库效率其实并不低,用起来腰部酸腿不疼而且还那么准确.

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注