2009年7月27日 星期一

用 PIC16F887 製作電容式觸控開關

本文在 2009/07/27 16:24 發表於 Yahoo!奇摩部落格
因Yahoo!奇摩部落格將於2013年12月26日終止服務故遷移至此


口試結束, 陸續釋放文件
如果沒有被惰性攻陷的話...XD

電容式觸控資料可以由 Microchip 的 Application Note 獲得
本文主要參考 Application Notes 1101, 1102, 1103, 1104
內容由該四篇中取出




電容式觸控的精神是這樣的
PIC 部分型號內建的兩個比較器
這兩個比較器接受兩個類比輸入
當輸入 + 的電壓大於輸入 - 的電壓時
比較器輸出為 1
反之, 若小於, 則輸出 0
輸出是數位的
兩比較器輸出被接到 SR 閂鎖 (SR latch)
當閂鎖輸出為 1 時, 電容 Cs 充電, 標示藍色處電壓上升
當閂鎖輸出為 0 時, 電容 Cs 放電, 電壓下降
注意上方比較器 C2 輸出已被設定反向
所以會變成輸入 + 電壓大於輸入 - 時輸出為 0
設定完成後閂鎖輸出 1 時會對電容 Cs 進行充電
充電電流量會被 120k 電阻限制
充到超過比較器 C2 的輸入 + 時, C2 輸出 0
於是閂鎖輸出為 0, 此時電容 Cs 就會開始放電
而 120k 電阻就是吃掉這放出來的電的負載
它和電容 Cs 一起決定充放電的速度

這堆東西組成一個震盪電路
震盪速度由電容 Cs 和 R 決定
而身體和地也是有電容存在
根據 AN1101 表示, 人體產生電容約 5-15 pF
若把手碰上上圖藍色處就等同並聯一顆電容在那裡
這會改變震盪頻率
透過計算頻率可以得知按鈕是否被按下

把 SR 閂鎖的輸出接入 timer 的 clock 就可以計算震盪頻率
需要 2 個 timer, 一個是用系統 clock 來精準的設定一個固定的時間
然後再這固定的時間內觀察另一個 timer 計算情形
第一個 timer 必須總是在第二個 timer 算完前結束
這樣才能知道頻率值

接著, 動手吧
先校正示波器

在擁有自己的示波器之前我完全不知道要做這
學校的都是弄好的
接著測試前面提的震盪器
若是自己兜電路和程式的話
在看到這波形前都不要繼續做

沒有震盪就一定不會動, 往下做只會浪費時間而且更難找錯
兩個比較器 C1 C2 都要設定
SR 閂鎖也要設定, 然後關聯的類比輸入必須把 ANS 打開
讓類比信號進來, 儘管我們沒有要用 ADC, 還是要開

接著手碰上去看看

好亂的波形
由於這台是二手類比示波器
沒有自動 delay 和平均功能
沒辦法, 窮學生只能買窮機器
加減撐著用唄

附上程式供參考, 適用 PIC16F887
由於輸出接腳就那幾隻固定的
應該少少的修改就能用
用 HI-TECH C compiler lite 編

#include <pic.h>

static void interrupt isr()
{
 if(T0IF){
  TMR1ON = 0;
  if(TMR1H > 0){
   RD1 = 1;
  }else{
   if(TMR1IF){
    RD1 = 1;
   }else{ 
    RD1 = 0;
   } 
  }
  if(TMR1L > 135){
   RD7 = 0;
  }else{
   RD7 = 1;
  }  
  /* restart timer */
  TMR1H = TMR1L = 0;
  T0IF = 0;
  TMR1IF = 0;
  TMR1ON = 1;
 } 
}

void main()
{
 TRISD = 0;
 PORTD = 0;

 /* C2OUT */
 TRISA5 = 0;
 /* C2IN+ */
 ANS2 = 1;
 /* 4 C12IN- */
 ANS0 = 1;
 ANS1 = 1;
 ANS9 = 1;
 ANS10 = 1;
 /* setup reference voltage Vref */
 VRCON = 0xaf; /* about 2/3 */
 /* SR latch */
 SRCON = 0xf0;
 /* init comparator C1, C2 */
 CM1CON0 = 0x94; /* inverted */
 CM2CON0 = 0xa0;
 CM2CON1 = 0x32;
 
 /* timer 0 */
 T0IE = 1;
 T0IF = 0;
 TMR0 = 0;
 OPTION = 0B00000100;
 /* timer 1 */
 TMR1H = TMR1L = 0;
 TMR1IF = 0;
 T1CON = 0B00000111;
 
 /* All interrupt ON */
 GIE = 1;
 
 while(1){
  ;
 } 
}


用這張改到爛的實驗板


手碰下去, 超白光伺候XD


這樣一來就算隔著電路板也能知道燈有亮 (好像很無聊XD)

沒有留言:

張貼留言

注意:只有此網誌的成員可以留言。