项目场景:
接上一条,电容式触摸按键实现水位检测(CA51F351S3)
问题描述
一、水位判断
一开始为了图省事只用到了一个标志位来表示水位的状态,但是这种方法存在一定的局限性,就是2的水位却和3息息相关云云,这在逻辑上看起来没有问题,但是实际应用起来很容易出现今天调好了没问题,明天一早起来就不行了这种情况,就是不太稳定。
if(CapRate_3 < WATER_RATE_THD_3){ //CapRate是通过实时采集到的按键值计算得到的比例,WATER_RATE_THD是根据经验设定的门限值
WaterFlag = 3;
}
else if((CapRate_3 > NO_WATER_RATE_THD_3)&&(CapRate_2 < WATER_RATE_THD_2)){
WaterFlag = 2;
}
else if((CapRate_2 > NO_WATER_RATE_THD_2)&&(CapRate_1 < WATER_RATE_THD_1)){
WaterFlag = 1;
}
else if(CapRate_1 > NO_WATER_RATE_THD_1){
WaterFlag = 0;
}
if(buf!=WaterFlag){
switch(WaterFlag)
{
case 1: TK_Debug_UartPutChar('a');
break;
case 2: TK_Debug_UartPutChar('b');
break;
case 3: TK_Debug_UartPutChar('c');
break;
}
buf=WaterFlag;
}
解决方案:
一、水位判断
在马工的建议下,对每个的标志位进行区分,并把他们存储在数组中,对每个按键的情况分别进行判断,有水为1,无水则为0.这样改正之后确实更加稳定了。
if(!WaterFlag[0])
{
if(CapRate_1 < WATER_RATE_THD_1)
{
WaterFlag[0] = 1;
}
}
else
{
if(CapRate_1 > NO_WATER_RATE_THD_1)
{
WaterFlag[0] = 0;
}
}
if(!WaterFlag[1])
{
if(CapRate_2 < WATER_RATE_THD_2)
{
WaterFlag[1] = 1;
}
}
else
{
if(CapRate_2 > NO_WATER_RATE_THD_2)
{
WaterFlag[1] = 0;
}
}
if(!WaterFlag[2])
{
if(CapRate_3 < WATER_RATE_THD_3)
{
WaterFlag[2] = 1;
}
}
else
{
if(CapRate_3 > NO_WATER_RATE_THD_3)
{
WaterFlag[2] = 0;
}
}
同时,主函数的串口打印也要做出调整
if(WaterFlag[0]&&WaterFlag[1]&&WaterFlag[2]){
if(temp!=d){
uart_printf("%d\r\n",d);//这样就只有在变化的时候才会串口输出
temp=d;
}
}
else if(WaterFlag[0]&&WaterFlag[1]){
if(temp!=c){
uart_printf("%d\r\n",c);
temp=c;
}
}
else if(WaterFlag[0]){
if(temp!=b){
uart_printf("%d\r\n",b);
temp=b;
}
}
else{
if(temp!=a){
uart_printf("%d\r\n",a);
temp=a;
}
}
二、基准值更新
通常情况下,按键被按下后按键值会变小,通过按键值与基准值的差值与门限值进行比较,来判断按键是否被按下,开启此宏之后,当按键按下一定时间后,会把基准值更新为当前按键值。
#define FINGER_LONG_TOUCH_TIME_LIMIT 0 //限制按键输出时间,单位为0.5s,若定义为0,则关闭此功能
三、板子上的电容
5号引脚对应通道TK2外接电容作为参考通道,不用接出(一开始理解错误参考通道的含义了,以为要接出来按键才行)。2号引脚对应通道TK_CAP,调整它的大小,可以改变各个按键的灵敏度,容值越大,灵敏度越大,可用范围10nF~47nF.
四、串口打印
要通过串口打印达到c语言中printf的效果,只需要在uart.c中加入以下函数(记得在头文件中进行函数声明)
void UartPutStr(char *str)
{
while(*str)
{
Uart0_PutChar(*str++);
}
}
void uart_printf(char *fmt,...)
{
va_list ap;
char xdata string[128];
va_start(ap,fmt);
vsprintf(string,fmt,ap);
UartPutStr(string);
va_end(ap);
}
五、调试
要使用触摸开发调试,只需要在程序中打开Debug的宏定义,并关掉程序中其他地方的串口,因为要用到串口。
#define DEBUG 1
同理,要使用keil自带的调试,也需要关掉串口。
#define UART0_EN //如果使用UART0,打开此宏定义
应该意识到,以后的代码中要更加熟练宏的运用,来使调试和集成多功能更加方便。
标签:记录,一下,RATE,WATER,WaterFlag,按键,CapRate,THD From: https://blog.csdn.net/qq_56353083/article/details/141180888希望这个Demo可以尽快结束,我快受不了啦……