|
/script> 說到電容非接觸摸技術(shù)相信大家并不陌生...... 由于人體就是導(dǎo)體,通過大地回路形成一個(gè)很小的電容.在人體接近感應(yīng)區(qū)域時(shí),人體電容和IO口內(nèi)部的電容并聯(lián),可以通過RC充電方式測量出這個(gè)電容,在人體沒有接近時(shí),只有IO口內(nèi)部電容,通過軟件處理后可識別是否有人體接近... 由于電容很小,所以電阻要很大才行,現(xiàn)在這里用4M7的電阻.......
那就費(fèi)話少說.....直接上圖...上源代碼..... 此主題相關(guān)圖片如下:
此主題相關(guān)圖片如下:
此主題相關(guān)圖片如下:
此主題相關(guān)圖片如下:
//引入頭文件********************************************************* #include "delay.h" #include "delay.c" #include <pic1684.h> //感應(yīng)輸入*********************************************************** #define RcIn RA3 //感應(yīng)輸入 //輸出定義*********************************************************** #define RcSu TRISA3 //方向輸出設(shè)置 //公用變量*********************************************************** unsigned char follow; //跟蹤校準(zhǔn) //******************************************************************* //函數(shù)名字; PortInit(); //輸入?yún)?shù); 無 //輸出參數(shù); 無 //功能描述; 端口設(shè)置 //建造日期; 2008年08月14日 //******************************************************************* void PortInit(void) { PORTA = 0x00; // PORTB = 0x00; // TRISA = 0xff; //A 口設(shè)置 TRISB = 0x00; //B 口設(shè)置 } //******************************************************************* //函數(shù)名字; DischargeOut(); //輸入?yún)?shù); 無 //輸出參數(shù); 無 //功能描述; 電容放電 //建造日期; 2008年08月14日 //******************************************************************* void DischargeOut(void) { RcIn = 1; //置高電平 RcSu = 0; //開始放電 asm("nop"); //放電時(shí)間 asm("nop"); //精確 5uS asm("nop"); asm("nop"); asm("nop"); } //******************************************************************* //函數(shù)名字; SurveyRc(); //輸入?yún)?shù); 無 //輸出參數(shù); 無 //功能描述; 測量充電時(shí)間 //建造日期; 2008年08月14日 //******************************************************************* unsigned char SurveyRc(void) { unsigned char time = 0; //時(shí)間計(jì)數(shù) DischargeOut(); //電容放電 RcSu = 1; //高阻輸入 while (RcIn) //充電計(jì)時(shí) { time++; //計(jì)時(shí)增加 asm("nop"); //精確10uS if (time > 250) break; //最大限時(shí) } return time; //返回時(shí)間 } //******************************************************************* //函數(shù)名字; DataAdd(*buffer, size); //輸入?yún)?shù); 緩沖區(qū)首址, 大小 //輸出參數(shù); 數(shù)據(jù)總和 //功能描述; 緩沖區(qū)所有數(shù)據(jù)相加 //建造日期; 2008年08月14日 //******************************************************************* unsigned int DataAdd(unsigned char *buffer, unsigned char size) { unsigned int add; unsigned char i; add = 0; //數(shù)據(jù)清零 for (i = 0; i < size; i++) { add += buffer[i]; //數(shù)據(jù)相加 } return add; //返回總和 } //******************************************************************* //函數(shù)名字; DataMax(*buffer, size); //輸入?yún)?shù); 緩沖區(qū)首址, 大小 //輸出參數(shù); 數(shù)據(jù)最大值 //功能描述; 選出緩沖區(qū)最大值 //建造日期; 2008年08月14日 //******************************************************************* unsigned char DataMax(unsigned char *buffer, unsigned char size) { unsigned char max, i; max = buffer[0]; //假設(shè)最大 for (i = 1; i < size; i++) { if (max < buffer[i]) max = buffer[i]; //對比最大 } return max; //最大數(shù)據(jù) } //******************************************************************* //函數(shù)名字; DataMin(*buffer, size); //輸入?yún)?shù); 緩沖區(qū)首址, 大小 //輸出參數(shù); 數(shù)據(jù)最小大值 //功能描述; 選出緩沖區(qū)最小值 //建造日期; 2008年08月14日 //******************************************************************* unsigned char DataMin(unsigned char *buffer, unsigned char size) { unsigned char min, i; min = buffer[0]; //假設(shè)最小 for (i = 1; i < size; i++) { if (min > buffer[i]) min = buffer[i]; //對比最小 } return min; //最小數(shù)據(jù) } //******************************************************************* //函數(shù)名字; DataEqually(idend, isor); //輸入?yún)?shù); 被除數(shù),除數(shù) //輸出參數(shù); 平均值 //功能描述; 數(shù)據(jù)平均 //建造日期; 2008年08月14日 //******************************************************************* unsigned char DataEqually(unsigned int idend, unsigned char isor) { return (idend / isor); //數(shù)據(jù)平均 } //******************************************************************* //函數(shù)名字; FilterData(); //輸入?yún)?shù); 無 //輸出參數(shù); 平均值 //功能描述; 取樣平均濾波 //建造日期; 2008年08月14日 //******************************************************************* unsigned char FilterData(void) { unsigned char i, max, min, data[5]; unsigned int sum; for (i = 0; i < 5; i++) { data[i] = SurveyRc(); //收集數(shù)據(jù) } sum = DataAdd(data, 5); //數(shù)據(jù)相加 max = DataMax(data, 5); //取最大值 min = DataMin(data, 5); //取最小值 return (DataEqually((sum - max - min), 3)); //取平均值 } //******************************************************************* //函數(shù)名字; KeyState(); //輸入?yún)?shù); 無 //輸出參數(shù); 無 //功能描述; 按鍵處理 //建造日期; 2008年08月14日 //******************************************************************* void KeyState(void) { static unsigned char release = 0; //釋放記數(shù) static unsigned char count = 0; //按下記數(shù) static unsigned char valid = 0; //有效標(biāo)志 static unsigned char reach = 0; //長按標(biāo)志 static unsigned char trail = 0; //跟蹤記數(shù) if (valid == 1) //是否有效 { if (FilterData() > follow) //按鍵按下 { release = 0; //釋放清零 if (reach == 0) //長按無效 { if (++count > 5) //防誤處理 { reach = 1; //長按置位 PORTB ^= (1 << 7); //取反輸出 } } } else if (++release > 5) //釋放記數(shù) { valid = 0; //有效清零 reach = 0; //長按清零 count = 0; //記數(shù)清零 } } else { if (FilterData() > follow) { trail = 0; //數(shù)據(jù)清零 valid = 1; //有效置位 } else { if (++trail > 200) //漂移跟蹤 { follow = FilterData(); //更新誤差 PORTB ^= (1 << 6); //跟蹤指示 trail = 0; //數(shù)據(jù)清零 } } } } //******************************************************************* //函數(shù)名字; main(); //輸入?yún)?shù); 無 //輸出參數(shù); 無 //功能描述; 主程序 //建造日期; 2008年08月14日 //******************************************************************* void main(void) { PortInit(); //端口設(shè)置 follow = FilterData(); //讀取誤差 while (1) { KeyState(); //按鍵處理 DelayMs(5); //定時(shí)掃描 } } |