无意中翻出了大学刚毕业时用来来忽悠老板的触摸按键的程序,突然感概白发又多了。做硬件的不容易,做软件的也不容易,做硬件又做软件的更不容易。。。。
回想起来印象也不深刻,感觉纯粹为了好玩,又发现了键盘边有个有三个焊盘的pcb板,心血来潮把就它翻新了一下。
感觉触摸按键比物理按键简单多了,物理按键还要按键(废话),但是触摸按键的可是是一个铜片,铁片,金属片(反正是导体就行了)。如果手头上又没有pcb按钮的,可以自己随便找个废板,在有铜片的地方挖个按钮引条线出来也是可以的,甚至拿一条导线也可以。手按按钮时要在按键上贴个胶纸绝缘,不然,按下的时候电流都被人体吸光了。
要说明一下,程序和硬件都是借鉴STM8,ST有相关例程,是AN几就忘了。st的例程使用的查询电平的方式,而且连充放电的时间也要去等,我用可是高贵的stm32这么宝贵的cpu时间岂能白白浪费掉,所以我就把它改成了中断触发的方式。
好了,先贴个原理图。
原理图就这么的简单。
PA4,是充电引脚。PA5、PA6、PA7是电平的检测引脚。这里用的是三个按键,R12、R13、R14是充电的限流电阻,这三个电阻要在几百K到几M欧之间,视单片机的性能而定吧,电阻越小电流越大充放电时间就越短,有句话说就是可以避免夜长梦多。但是电阻太小了,时间太短单片机就检测不到了。我在这选的是1M欧,充放电时间大概是10us,R15,R16,R17作用不是太大,不能取太大就是了。
所谓的RC法,就是R和C,R就是电阻,C就是电容也就是按键,利用充放电的时间来检测电容的变化。
更多的资料,百度谷歌很多,就不抛砖头了。
我的按键是这样的,注意要贴上胶布绝缘。
好了贴程序
这里是三个按键,硬件资源使用了两个定时器,4个IO口
TIM2用于时间的记录。
TIM3每100us触发一次,Ttimer_cnt 记录的是触发次数
Ttimer_cnt = 1 现在所有IO都为低电平状态配置所有IO为输入高电平触发中断,并拉高充电的IO口
Ttimer_cnt = 4到这时所有的IO已经充电完毕,可以记录充电的时间
Ttimer_cnt = 5现在的所有IO口都处于高电平状态,配置所有IO为输入低电平触发中断,并拉低充电的IO口,放电
Ttimer_cnt = 8到这时,所有的IO都放电完毕,记录放电时间
Ttimer_cnt = 9计算按键的充放电时间值,滤波。Ttimer_cnt = 0;
芯片使用的是stm32F103
//.h文件
typedef struct
{
uint32_t Pin;//引脚
uint32_t staus;
uint32_t even;
uint32_t Realse;
uint32_t check_cnt;
uint32_t MeasRejected;
uint32_t RejectionCounter;
uint32_t Up_Cnt;
uint32_t Down_Cnt;
uint32_t Temp_Cnt;
uint32_t AcqLoopIndex;
uint32_t Shifter;
uint32_t MaxMeasurement;
uint32_t MinMeasurement;
uint32_t Measurement;
uint32_t FinalMeasurementValue;
uint32_t CumulatedMeasurement;
uint32_t ReadMeasurement;//检测结果
uint32_t Eline;
}Tkey_Action;
//.c文件
#define KEYNUMS 3
//IO方向设置
// IO口设置76543210 IO口设置76543210
#define ACQ_IN(x) {GPIOA->CRL&= ~(0xF << (uint32_t)(x));GPIOA->CRL|= (0x4 << (uint32_t)(x));} //配置为输入高阻
#define ACQ_OUT(x) {GPIOA->CRL&= ~(0xF << (uint32_t)(x));GPIOA->CRL|= (0x8 << (u