这次的代码很有意思,可以学到很多编程的思想。
首先,电容触摸按键是基于模电的RC充放电电路,一开始:R+=v1,R-=0,I1=V1/R;充电过程中:R+=v1,R-=V2,I2=(V1-V2)/R 从公式中可以看出,在相同的条件中,充电时间是与电容值成正比的,而且当手触碰电容触摸按键,它的容值就会增加,根据这个原理,我们可以测量充电的时间来判断是否按下了按键。 程序的思路是这样的,1)初始化TIM5的通道2输入捕获,将PA1的模式设为推挽输出,输出0,放电,然后将定时器清零,以等待按下充电。2)捕获上升沿,即充电完成的时间。3)10次捕获没有按下的充电时间,以此来作为以后判定的比较值,取中间6次值的平均值,确保这个数据的准确性。4)TPAD_Scan()的作用是读取N次充电时间的最大值,然后与比较值作对比,比它大一定的阈值则说明已经用手按下。阈值由经验取100us。 读取10次数和将10次数排列的程序如下,这个循环嵌套程序在C语言程序设计的书里很常见。 vu16 Tpad_Default_Val=0;这个vu16代表volatile unsigned short int;与u16不同的是多了一个volatile关键词,它的作用是作为指令关键字,确保本条指令不会因编译器的优化而省略,且要求每次直接读值,volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了。 多任务环境下各任务共享的标志需要加volatile。 f(rval>(tpad_default_val+TPAD_GATE_VAL)) { if(keyen==0)res=1; //printf("r:%drn",rval); keyen=3; } 之前对这条程序很不理解,后来经过开源电子网的查询才明白。 因为如果一直按下的话,if的条件是满足的,虽然keyen--执行后变成2,但在if中又变成了3,所以不松手的话keyen的值会一直是2,也就是说要检测到3次的松手上升沿读取后,即if条件不满足,才能将keyen变成0。 这次在解决问题中发现自己的硬件仿真有点生疏,虽然上次有学过,但很久没用已经忘的差不多了,汗,决定下午重新学一下。 通过串口调试助手可见充电时间