赛元单片机-触摸库使用总结

赛元单片机-触摸库使用总结,第1张

SC95F8617触摸库使用笔记 一、资料概述

主要参考资料:《赛元SC95F系列TouchKey MCU 应用指南v0.0.1.pdf》。

资料包链接如下:
1.我下载时的地址:
SC95F8X1X触控资料
2.我转存的百度盘:SC95F8X1X触控资料
3.csdn下载 SC95F8X1X触控资料
先来看看资料包的内容:

触摸库分为2种(高可靠模式和高灵敏度模式),3个(高灵敏度有T1和T2两种),看看他们有什么区别:

通过上表的信息,我只用到一路触摸,我就选用了高灵敏度模式T1。

因为T2至少要3个按键

二、关键的配置参数

下面来看看配置文件的源码《S_TOUCHKEYCFG.H》:

//*************************************************************************************************
//  Copyright (c) 	深圳市赛元微电子有限公司
//	文件名称	:  S_TouchKeyCFG.h
//	作者		: 
//	模块功能	:  触控键配置文件
// 	版本		:  V0.1
// 	更改记录	:
//************************************************************************************************
#ifndef __S_TOUCHKEYCFG_H__
#define __S_TOUCHKEYCFG_H__
#define		SOCAPI_SET_TOUCHKEY_TOTAL	 	2 	//	触摸按键总数	
#define		SOCAPI_SET_TOUCHKEY_CHANNEL		0x000000c0	//	1个bit对应的引脚																																		 
unsigned int  code TKCFG[17] = {
1,		//	[0]应用类型(0-d簧,1-隔空)
0,		//	[1]按键类型(0-单键,1-双键)
0,		//	[2]AirSeparationDistance 隔空距离
7,		//	[3]CONFIRMTOUCHCNT 确认按键次数:该参数决定触控算法运行的出键速度,出键速度与一轮按键扫描时间有关,若
		//					扫描一轮按键需要 12MS,按键确认次数为5次,则按键需要的响应时间为5*12MS=60MS.
10,		//	[4]INIT_AUTO_UPDATE_TIME 初始化自动更新时间,这个意思可能是没有按键时,自动更新按键AD基值
3000,	//	[5]SET_KEY_CONTI_TIME 按键最长输出,单位为轮数.
					//如果按键一直触摸,超过这个时间,就会取消按键有效状态,并把这时的AD当做新的按键AD基值。

300, // [6]SET_SYNC_UPDATE 动态更新基线时间:该参数用于处理按键浮起的更新速度,保持默认不改动 200, // [7]SET_UPDATE_SPEED 基线更新速度:该参数用于更新基线。

保持默认不改动 2, // [8]AUTO_UPDATE_TIME 基线复位速度:该参数决定基线复位的速度。

值越大,更新速度越慢,保持默认不改动 0, // [9]FilteredKValue 滤波 K值:保持默认不改动 0, // [10]SET_ANTIJAM 抗干扰设置:用于扫描时钟变频,有助于通过 EMI 测试,当项目有 EMI 测试要求, // 需要选择打开 1:12bit。

4, // [11]BAUD 100, // [12]DwellTime 采样时间 10, // [13]SaveTime 65535, // [14]SaveTime 65535, // [15]SaveTime 10 // [16]NOISE }; unsigned char code TKChannelCfg[SOCAPI_SET_TOUCHKEY_TOTAL][8]={ 0x03, //SET_TOUCH_FREQ 时钟 0x18, //SET_RESOLUTION 分辨率 0x04, //SET_GAIN_CFG 增益 0x1f, //SCANTIME 扫描周期 0x1f, //SET_ICHA 0x05, // 0x0C, //FINGER_THRESHOLD_H 触摸阈值高字节 0xbe, //FINGER_THRESHOLD_L 触摸阈值低字节 0x03,0x18,0x04,0x1f,0x1f,0x05,0x05,0x3a, }; #endif

我就更改了3个地方:

  1. 按键总数 SOCAPI_SET_TOUCHKEY_TOTAL 由demo的3改为2;
  2. 根据我的触摸按键IO口,SOCAPI_SET_TOUCHKEY_CHANNEL 改为0x000000C0;TK0对应0x00000001;TK1对应0x00000002;以此类推。

  3. 触摸阈值的高字节由0x07 改为 0x0C,这是因为我的系统有电机,如果是原来的0x07,过于灵敏,会误触发。

三、把触摸库整合到自己的工程

高灵敏度模式T1包含了2个库,就是库使用到的临时变量区间选择在哪个区域。

我选用了Small。

SC95F8X1X_HighSensitive_Lib_T1_S_V0.0.2.LIB  ---    使用Small模式编译,变量区间在data
SC95F8X1X_HighSensitive_Lib_T1_L_V0.0.2.LIB  ---    使用Large模式编译,变量区间在xdata
3.1把库文件添加进工程

把库文件添加到自己的工程中,下面4个文件:

这几个文件的官方介绍:

触摸库API函数接口说明:

触摸库使用流程图:

3.2触摸库API使用源码分析

3.2.1 设置IO口为推挽输出,且输出高电平(我用了P31-TK6作为触摸口)

	P3CON = B0011_1111;  设置P3.6,P3.7输入模式
	P3PH  = 0x00;
	P31 = 1;		//	P31作为触控,配置成强推挽,输出1

3.2.2 在main函数中调用初始化函数TouchKeyInit

	TouchKeyInit();			 //调用库函数,初始化TouchKey

3.2.3 在main函数中,1ms扫描一次按键

void main(void)
{
	...
	TouchKeyInit();
	...
	while(1){
		WDT_CLR ;  //清看门狗
		if(FlagTick_1ms){
			FlagTick_1ms = 0;
#if		CFG_TOUCH_BODY == 1	
			Sys_Scan();	//	扫描触摸按键
#endif
		}
		...
	}
}
void Sys_Scan(void)
{
	if(SOCAPI_TouchKeyStatus&0x80)	//重要步骤2:  触摸键扫描一轮标志,是否调用TouchKeyScan()一定要根据此标志位置起后
	{	   																	
		SOCAPI_TouchKeyStatus &=0x7f;	//重要步骤3: 清除标志位, 需要外部清除。

exKeyValueFlag = TouchKeyScan(); ChangeTouchKeyvalue(); //键值 TouchKeyRestart(); //启动下一轮转换 } } /************************************************** *函数名称:void ChangeTouchKeyvalue(void) *函数功能:键值转换函数 *入口参数:void *出口参数:void *功能说明:请参考触控库使用手册进行 *** 作 **************************************************/ #define KEY_STAT_DELAY_TICK 15 #define KEY_UP_STAT_DELAY_TICK 15 unsigned char xdata bKeyIsDown; /// 记录前一个状态,累计10次确认 unsigned char xdata keyChangeDelay; /// 状态时间累计 void ChangeTouchKeyvalue(void) { if(exKeyValueFlag != 0x00000000) //有键按下 { switch(exKeyValueFlag) { case 0x00000040: if(!bKeyIsDown){ // 前一个状态是按下的,累计时间 keyChangeDelay++; if(keyChangeDelay > KEY_STAT_DELAY_TICK){ keyChangeDelay = 0; bKeyIsDown = 1; FlagPeopleNotInBed = 0; LED1 = 1; } } break; default: exKeyValueFlag = 0x00000000; } }else { //释放按键 if(bKeyIsDown){ // 前一个状态是按下的,累计时间 keyChangeDelay++; if(keyChangeDelay > KEY_UP_STAT_DELAY_TICK){ keyChangeDelay = 0; bKeyIsDown = 0; LED1 = 0; FlagPeopleNotInBed = 1; } } } }

四、针对特殊应用修改触摸库函数

我的应用有些特殊,我是在按摩椅系统中,用来检测人体是否到位。

在按摩椅表层放置一根细长的导线。

一开始,我把TKCFG[5]SET_KEY_CONTI_TIME 按键最长输出 设置为0xFFFF(默认为十进制3000),按键最长输出为8分钟左右,我需要按键能够持续输出30分钟。

于是找到了触摸库文件《S_TouchKeyCFG.C》

/**************************************************
*函数名称:unsigned int TouchKeyScan(void)
*函数功能:检测按键接口
*入口参数:void
*出口参数:按键通道, 返回的是一个int , 通道数
*备注	 :1,  调用触控库检测函数SensorKeyFlag()
		   2,  分析得出16个通道,哪个通道有按下,按下bit 位设置为1,否则为0
		   3,  检测是否需要立即更新baseline:  大于MAX_KEY_RESET_BASELINE 个按键按下时立即更新baseline
		   4,  双键或者单键按下时, 时间大于SetOneKeyPushResetTime()结果时更新baseline 
**************************************************/
unsigned long int TouchKeyScan(void)
{
	unsigned char t;
    unsigned char MultipleCnt = 0;//按键计数
	unsigned long int Keyvalue = 0; 
	unsigned long int KeyData = 0; 	
	
	if(GetIsNeedUpdateBaseline() == 0)				//检测是否需要更新baseline 
	{
		Keyvalue = SensorKeyFlag();					//Sensor判断, 这里如果bMultiple = 1 表示中间有干扰	 //分析按键,得出标准的16通道bit 位                     							   
		for(t=0;t<CurrentChannelMax;t++)
		{
			Keyvalue = Keyvalue>>1;
			if(TK_CY)
			{
				KeyData |= ((unsigned long int)0x01 << (CurrentChannel[t]));              
				MultipleCnt++;							
			}
		}                
		if(MultipleCnt >= 2) 	 									//进入多按键处理
		{			
			bMultiple = 1;			
			if(MultipleCnt >= SOCAPI_MAX_KEY_NUM_INVALID)
			{
				SetNeedUpdateBaseline(); 							// 立即更新baseline ,例如亚克力板盖上去
			}
			else
			{					
				if(IsDoubleKeyOrSlideKey())
				{
					bMultiple = 0;
				} 				 
			}			
		}			

		if(bMultiple == 0)							//进入按键判断
		{		
			if(KeyData != 0x0)					    //单个按键达到多长时间就update baseline ,松手检测
			{			
				UpdateBaseLNum++; 
			}
			else	
			{
				UpdateBaseLNum = 0; 	
			} 
		}	
		else
		{   
		    //考虑基线更新		
			MultipleLNum++; 
			KeyData = 0x00;
		}

//		if(UpdateBaseLNum > SetOneKeyPushResetTime()){	  //按键超出最长输出时间更新基线
//		 	SetNeedUpdateBaseline();	
//			UpdateBaseLNum = 0;		
//			}
				
		if(MultipleLNum >SOCAPI_MAX_KEY_MUTIPLE)		  //干扰计数大于最大计数更新基线
 		{
			SetNeedUpdateBaseline(); 
			MultipleDealTpye = 1; 
			MultipleLNum = 0;
		}  
	}			
	else
	{
		MultipleDeal(TKCFG[AUTO_UPDATE_TIME]);										//基线复位处理
	}  
	
	return KeyData;
}

注释掉的如下代码,就可以保证按键持续输出时间超过30分钟:

		if(UpdateBaseLNum > SetOneKeyPushResetTime())	  //按键超出最长输出时间更新基线
		{
 			SetNeedUpdateBaseline(); 
			UpdateBaseLNum = 0;
		}

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/673417.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-19
下一篇 2022-04-19

发表评论

登录后才能评论

评论列表(0条)

保存