STM8S觸摸按鍵固件庫詳解

由於剛好有小項目需要用到觸摸按鍵,stm8s可以節約一塊觸摸按鍵的片子,並且成本比較低。在某些對成本比較敏感的應用還是有價值的。現將自己網上找到的資料與自己學習的心得記下與大家分析。ST的底層庫對滾動條也支持,效果還是不錯的

一、原理分析

ST的電容式觸摸按鍵方案通過一個電阻和感應電極的電容CX構成的阻容(RC)網絡的充電/放電時間來檢測人體觸摸所帶來的電容變化。


如上圖所示,當人手按下時相當於感應電極上並聯了一個電容Cx,增加了感應電極上的電容,感應電極進行充放電的時間會增加,從而檢測到按鍵的狀態。

先用開關將 Cs(或 Cs+Cx)上的電放盡,然後斷開開關,讓 R 給 Cs(或 Cs+Cx)充電,當沒有手指觸摸的時候, Cs 的充電曲線如圖中的 A 曲線。而當有手指觸摸的時候, 手指和 TPAD之間引入了新的電容 Cx,此時 Cs+Cx 的充電曲線如圖中的 B 曲線。 從上圖可以看出, A、 B兩種情況下, Vc 達到 Vth 的時間分別爲 Tcs 和 Tcs+Tcx。
其中, 除了 Cs 和 Cx 我們需要計算,其他都是已知的,

根據電容充放電公式:Vc=V0*(1-e^(-t/RC))
其中 Vc 爲電容電壓, V0 爲充電電壓, R 爲充電電阻, C 爲電容容值, e 爲自然底數, t 爲充電時間。根據這個公式,我們就可以計算出 Cs 和 Cx。 利用這個公式,我們還可以作一個簡單的電容計,直接可以測電容容量了,有興趣的朋友可以搗鼓下。

其實我們只要能夠區分 Tcs 和 Tcs+Tcx,就已經可以實現觸摸檢測了,當充電時間在 Tcs 附近,就可以認爲沒有觸摸,而當充電時間大於 Tcs+Tx 時,就認爲有觸摸按下( Tx爲檢測閥值)。
實際應用中感應電極可以直接在PCB板上繪製成按鍵、滾輪或滑動條的應用樣式,也可以做成彈簧件插在PCB板上,即使隔着絕緣層(玻璃、樹脂)也不會對其檢測性能有所影響。

二、硬件設計


網絡標號描述

REF_LOAD:對按鍵進行充放電的引腳,所有按鍵必須共用一個LOAD(保證一致性)。也可以用VCC代替。

SH_MCKEY:屏蔽引腳,這個根據實際情況來覺得是否接,一般調試的時候預留着

PD2-PD6 PC6 PC7爲用戶按鍵部分

注意:不要將按鍵檢測腳安排在True open drain引腳和OSC1/PA1,OSC2/PA2引腳上(前者無法輸出高電平,後者的內部結構與一般IO口不同,不適宜作爲按鍵檢測腳使用)


三、軟件分析

MCU需要資源

1個16位定時器 (用於採集按鍵信號: 測量RC充放電時間)
1個8位定時器 (主要作爲後處理的時基信號)

資料與固件代碼下載地址

主函數(main)
void main(void)
{
    volatile u16 temp;

    CLK_HSICmd(ENABLE);//使能HSI
    CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1);//
    CLK_SYSCLKConfig(CLK_PRESCALER_HSIDIV1);//主頻16M
    Delay(10000);  

    TSL_Init(); //按鍵庫初始化
    Extra_Init();


    while(1) 
    { 
        temp = uMainCounting;
        TSL_Action();//獲取按鍵狀態
        Runing_Session[0] = uMainCounting - temp;


        temp = uMainCounting;
        Key_State_Machine();
        Runing_Session[1] = uMainCounting - temp;
    }
}

初始化觸摸固件庫
void TSL_Init(void)
{

  disableInterrupts();

  DetectionIntegrator = DETECTION_INTEGRATOR_DEFAULT;
  EndDetectionIntegrator = END_DETECTION_INTEGRATOR_DEFAULT;
  ECSTimeStep = ECS_TIME_STEP_DEFAULT;
  ECSTemporization = ECS_TEMPO_DEFAULT;
  RecalibrationIntegrator = RECALIBRATION_INTEGRATOR_DEFAULT;
  DetectionTimeout = DTO_DEFAULT;

  ECS_K_Fast = ECS_IIR_KFAST_DEFAULT;
  ECS_K_Slow = ECS_IIR_KSLOW_DEFAULT;
  ECSTimeStepCounter = ECSTimeStep;
  ECSTempoCounter = 0;
  ECSTempoPrescaler = 0;

  TSL_IO_Init();

#if (RTOS_MANAGEMENT == 0)
  TSL_Timer_Init();
#endif

#if NUMBER_OF_SINGLE_CHANNEL_KEYS > 0
  TSL_SCKey_Init();
#endif
#if NUMBER_OF_MULTI_CHANNEL_KEYS > 0
  TSL_MCKey_Init();
#endif

  enableInterrupts();

  TSLState = TSL_IDLE_STATE;

}






發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章