触摸按键算法基本没用到,因为可以直接判断阈值也行.但是滑条就要计算了.所以就有一个方法叫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的触摸库效率其实并不低,用起来腰部酸腿不疼而且还那么准确.