1、当前PCB版本是这样的,设计时忘记把触摸按键周围的铜皮挖空了。

然后实际调试时,电容本来用的是10nF,读取扫描出来的值是2000左右。把电容换成33nF后,读取出来的值在40000-50000之间。
现在的一个现象是,不隔面板时,触摸之后,按键值会降得很大,所以按键效果就很灵敏。
但是隔了一个1.7mm的亚克力面板之后,按键值就只降了2000左右,所以按键效果就不灵敏。
问题一:在不改PCB的情况下,能否通过改变软件来提高灵敏度?
2、按键驱动根据电子琴的代码做了一些修改,麻烦大佬们帮忙看看有没有修改建议
触摸电子琴从无到有心得分享——基于STC8H4K64TL的电子琴
https://www.stcaimcu.com/thread-1380-1-1.html
(出处: 国芯技术交流网站)
volatile u32 TK_cnt[TK_Length]={0}; // 键计数值,从触摸中断中保存当前触摸通道的值
u32 xdata TK_Test=0, TK_zero[TK_Length]={0};// 0点读数
u32 xdata T_KeyCmp[TK_Length]={0};//按键按下后,TK_zero-T_KeyCmp后,判断是否真正按下的阈值
bit B_ReadKeyOk=0; //标志已转换完成4个键
u16 Count[TK_Length]={0}; //按键按下后的时间计数
u16 LastState = 0; //8位变量 b0=1,代表k0上一次按下过
//========================================================================
// 函数: void TKSU_Interrupt(void)
// 描述: 触摸按键中断。
// 参数: none.
// 返回: none.
// 版本: VER1.0
// 日期: 2021-02-01
// 备注:
//========================================================================
void TKSU_Interrupt(void) interrupt 13
{
u8 j;
j = TSSTA2;
if(j & 0x40) //数据溢出, 错误处理(略)
{
TSSTA2 |= 0x40; //写1清零
}
if(j & 0x80) //扫描完成
{
j &= 0x0f;
TSSTA2 |= 0x80; //写1清零
switch(j)
{
case 4:
TK_cnt[0] = TSDAT; //保存某个通道的读数
break;
case 5:
TK_cnt[1] = TSDAT; //保存某个通道的读数
break;
case 6:
TK_cnt[2] = TSDAT; //保存某个通道的读数
break;
case 7:
TK_cnt[3] = TSDAT; //保存某个通道的读数
break;
}
if( j>=7 ){
Uart_Test0++;
if(Uart_Test0>=65536)
Uart_Test0=0;
B_ReadKeyOk=1;//读完一次循环
}
}
}
void KEY_TK_Init(void)
{
u8 i,j;
TSCHEN1 = 0xF0; //TK04~TK07
TSRT = 0x00; //没有LED分时扫描
TSCFG1 = (7<<4) + 5; //开关电容工作频率 = fosc/(2*(TSCFG1[6:4]+1)), 放电时间(系统时钟周期数) 0(125) 1(250) 2(500) 3(1000) 4(2000) 5(2500) 6(5000) 7(7500) 最小3
TSCFG2 = 2; //配置触摸按键控制器的内部参考电压(AVCC的分压比), 0(1/4) 1(1/2) 2(5/8) 3(3/4)
TSCTRL = 0xA0; //开始自动扫描, 无平均, B7: TSGO, B6: SINGLE, B5: TSWAIT, B4: TSWUCS, B3: TSDCEN, B2: TSWUEN, B1 B0: TSSAMP
// TSCTRL = (1<<7) + (1<<6); //开始单次扫描, 无平均
// TSCTRL = (1<<7) + (1<<6)+3; //开始单次扫描, 4次平均
// TSCTRL = (1<<7) + (1<<6)+1; //开始单次扫描, 2次平均
// TSWUTC = 12; //100ms唤醒一次
IE2 |= 0x80; //使能触摸中断
delay_ms(50);
while(j<=10)//读取10次键值,将此值作为未触摸时的0点, 要求上电时不要触摸按键
{
WDT_Clear(); //喂狗
if( B_ReadKeyOk ){ //每完成一次循环
for(i=0;i<TK_Length;i++){
TK_zero[i] += TK_cnt[i];//保存初始化值做为0点
}
B_ReadKeyOk = 0;
j++;
}
delay_ms(25);
}
for(i=0;i<TK_Length;i++){
TK_zero[i]=(TK_zero[i]>>3);//取8次读取后的平均值
TK_zero[i]=TK_zero[i]-TK_zero[i]%10;//取整数值,将此值视为初始化后的0点
switch(i)
{
case 0:
T_KeyCmp[i]=TK_zero[i]/30;
break;
case 1:
T_KeyCmp[i]=TK_zero[i]/30;
break;
case 2:
T_KeyCmp[i]=TK_zero[i]/30;
break;
case 3:
T_KeyCmp[i]=TK_zero[i]/40;
break;
}
}
}
//========================================================================
// 函数名称: KEY_Deal
// 函数功能: 按键状态读取
// 入口参数: 无
// 函数返回: 无
// 当前版本: VER1.0
// 修改日期: 2023 - 1-1
// 当前作者:
// 其他备注:循环读取八个端口的状态,并将按下的时间赋值给 Count 数组,按下的状态赋值给LastState
//========================================================================
void KEY_Deal(void) //检查所有的按键状态 10ms执行一次
{
u8 i = 0;
if(!B_ReadKeyOk){//循环读取完成才进入按键状态读取,12ms左右一个周期
return;
}
B_ReadKeyOk = 0;
// printf("(%u,%u,%u)\r\n",(u16)TK_cnt[0],(u16)TK_cnt[1],(u16)TK_cnt[2]);
for(i=0;i<TK_Length;i++)//循环4次 i的取值范围是0-3 代表了P14-P17的状态查询
{
if( TK_cnt[i] < (TK_zero[i]-T_KeyCmp[i])) //当前读取的值与初始值比较,持续按下,变量+1
{
if( Count[i]<60000 )
Count[i] ++; //按键按下,这个计数变量+1
}
else //按键松开了,变量清0
{
if( Count[i]>0 )//如果这个变量是按下过的
{
LastState |= (1<<i); //这个变量相应的标志位置位
}
else
{
LastState &= ~(1<<i); //这个变量相应的标志位清0
}
Count[i] = 0; //按键按下,这个计数变量清0
}
}
}
//========================================================================
// 函数名称: KEY_ReadState
// 函数功能: 读取指定的按钮的状态
// 入口参数: @keynum : 按钮的端口号 例如P32端口,端口号就是2
// 函数返回: 看其他备注
// 当前版本: VER1.0
// 修改日期: 2023 - 1- 1
// 当前作者:
// 其他备注: 函数返回值如下
// #define KEY_NOPRESS 0 //按键未按下
// #define KEY_FILCKER 1 //消抖
// #define KEY_PRESS 2 //单击
// #define KEY_PRESSOVER 3 //单击结束
// #define KEY_LONGPRESS 4 //长按3秒
// #define KEY_LONGOVER 5 //长按结束
// #define KEY_RELAX 6 //按键松开
//========================================================================
u8 KEY_ReadState(u8 keynum) //读取指定的按键的状态 10ms执行一次
{
if( Count[keynum]>0 ) //按键是按下的各种状态返回
{
if( Count[keynum]<5 ) //按下<50ms 返回消抖状态
{
return KEY_FILCKER;
}
else if( Count[keynum]==5 ) //按下正好50ms 返回单击
{
return KEY_PRESS;
}
else if( Count[keynum]<150 ) //按下不到3000ms 返回单击结束
{
return KEY_PRESSOVER;
}
else if( Count[keynum]==150 ) //按下正好3000ms 返回长按状态
{
return KEY_LONGPRESS;
}
else //长按结束
{
return KEY_LONGOVER;
}
}
else //按键已经松开了,返回各种状态
{
if( LastState &( 1<<keynum ) ) //按键之前按下过
{
return KEY_RELAX;
}
else //按键之前没有按下
{
return KEY_NOPRESS;
}
}
}
问题二:由于我这里只用了4个按键(TK4-TK7),那么在中断扫描通道时,是否还是16个全部扫描?有没有办法从TK4扫描到TK7时,直接回到TK4重新扫描?
问题三:在KEY_Deal函数中,查询当前按键值的for循环,能否改成非阻塞式的查询?像普通按键一样用按键状态值做按键判断?
3、根据手册的触摸按键PCB设计建议,做了以下修改,不知修改得对不对,麻烦大佬们指点一下。

问题四:本来想在触摸弹簧下放置一个实心感应盘的,但是现在在触摸弹簧下加了一个LED,这个实心感应盘还能放吗?如果还能放的话,那么这个感应盘应该怎么设计?
问题五:铜皮是否要改成45°网格状?
以上问题,有大佬看到的话,麻烦帮忙解答一下,谢谢🙏🙏