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

SC95F8617触摸库使用笔记

一、资料概述

主要参考资料:《赛元SC95F系列TouchKey MCU 应用指南v0.0.1.pdf》。资料包链接如下:
1.我下载时的地址:
SC95F8X1X触控资料
2.我转存的百度盘:[SC95F8X1X触控资料] 链接:https://pan.baidu.com/s/1FaoaZUbpgLb9LvdgFPGV7w?pwd=fnn7
提取码:fnn7

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-弹簧,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;
		}
posted @ 2022-04-15 17:04  汉塘阿德  阅读(432)  评论(0编辑  收藏  举报  来源