stc15f104實(shí)現(xiàn)觸摸開(kāi)關(guān)
想做個(gè)觸摸打開(kāi),延時(shí)關(guān)斷的小控制器
用普通的輕觸開(kāi)關(guān)似乎很難看,而且開(kāi)關(guān)也不方便 固定,總不好把控制板放在外面吧?
想使用觸摸的開(kāi)關(guān),網(wǎng)上搜索了好久沒(méi)找到合適的,stc官方文檔上有個(gè)電容感應(yīng)開(kāi)關(guān)
需要占用2個(gè)io,一個(gè)產(chǎn)生pwm信號(hào),一個(gè)用于ad判斷,另外還需要2個(gè)電阻2個(gè)二極管和1個(gè)電容。
感覺(jué)有點(diǎn)復(fù)雜了,嘗試了一下,最后只用了一個(gè)io口,一個(gè)電阻和一個(gè)電容搞定了。
思路是這樣的:
一個(gè)2M電阻接電源和IO口(我用了p3.3)
一個(gè)33p電容接IO口和地。
IO口接一根線到金屬片什么的用來(lái)觸摸。
p3.3置0先把電容的電放掉,然后置高阻態(tài),這時(shí)候電源會(huì)通過(guò)電阻給電容充電,
時(shí)間常數(shù)2M*33p約66μs,使用定時(shí)器統(tǒng)計(jì)io口變成高電平的時(shí)間,
不用計(jì)時(shí)器的話擔(dān)心受中斷的影響,會(huì)有誤差。
這個(gè)時(shí)間可能需要做平滑處理避免干擾。
開(kāi)機(jī)的時(shí)候沒(méi)有人觸摸,記錄下這個(gè)時(shí)候充電時(shí)間做為基準(zhǔn)。
如果有人觸摸,則充電時(shí)間加長(zhǎng),所以定時(shí)檢測(cè)下這個(gè)充電時(shí)間,
發(fā)現(xiàn)充電時(shí)間比基準(zhǔn)充電時(shí)間長(zhǎng)很多(我用了2倍基準(zhǔn)時(shí)間來(lái)比較),就可以認(rèn)為是有人觸摸了。
已經(jīng)完工投入使用,目前看可靠性、抗干擾能力都可以滿足要求。
void mw(){//主工作循環(huán)
unsigned int i;
static unsigned int cdsj=0,bzz;//充電時(shí)間,標(biāo)準(zhǔn)值
static unsigned char csh=10;//初始化計(jì)數(shù)
T2H=T2L=0;//計(jì)數(shù)器2計(jì)數(shù)值初始化為0
P3M1 |=0x8;//p3.3置開(kāi)漏狀態(tài)
P3M0 |=0x8;//
P3_3=0;//p3.3輸出清0
delay(100);
P3M1 |=0x8;//p3.3置高阻狀態(tài)
P3M0 &=0xf7;//
AUXR |= 0x10;
//開(kāi)始計(jì)數(shù)器2運(yùn)行
P3_3=1;//p3.3輸出為1,輸入狀態(tài)
IE1=0;//清外部中斷1的狀態(tài)
EX1=1;//打開(kāi)外部中斷1
while(EX1);//外部中斷未執(zhí)行完畢循環(huán)等待
i=cdsj>>3;
cdsj=cdsj-i+T2L;//平滑處理
if(csh){
csh--;
if(csh==0){//初始10次計(jì)數(shù)結(jié)束,取當(dāng)前值為標(biāo)準(zhǔn)值
bzz=i+i;
};
return;
};
if(i>bzz){
此條件滿足表明開(kāi)關(guān)被觸摸
};
}