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