8.1 電容觸摸簡(jiǎn)介
8.1.1 電容觸摸概述
隨著科技的發(fā)展,傳統(tǒng)的機(jī)械按鍵正在逐步從設(shè)備上面消失,這個(gè)原因主要有機(jī)械按鍵由于是采用機(jī)械接觸的方式,壽命比較短,從用戶(hù)體驗(yàn)上看,機(jī)械按鍵也顯得操作復(fù)雜,對(duì)比現(xiàn)在的電容按鍵,電容按鍵具有壽命長(zhǎng),因?yàn)椴淮嬖跈C(jī)械接觸,占用空間少,以前的機(jī)械按鍵在設(shè)計(jì)外殼的時(shí)候需要考慮尺寸,現(xiàn)在換成電容按鍵后這個(gè)問(wèn)題不再需要考慮。
8.1.2 檢測(cè)原理
常規(guī)的檢測(cè)方式一般是通過(guò)計(jì)算電容放電時(shí)間來(lái)判斷是否有手指按下,這是因?yàn)槭种笗?huì)與線(xiàn)路板的銅箔接觸面上產(chǎn)生電容效應(yīng),當(dāng)手指沒(méi)有放在銅箔上的時(shí)候,銅箔與PCB之間存在雜散電容,這兩個(gè)狀態(tài)的電容值差別很大,檢測(cè)原理如下圖所示。
在檢測(cè)之前首先用開(kāi)關(guān)將電容Cs里面的電荷放盡,然后此時(shí)CPU開(kāi)始計(jì)算Cs的充電時(shí)間,這一部分是采用捕捉信號(hào)來(lái)測(cè)量,盡管單片機(jī)屬于數(shù)字電路,但是數(shù)字電路的邏輯電平也是有電壓限制的,比如在3.3V供電環(huán)境下,當(dāng)電壓大于2.4V則被認(rèn)為是邏輯電平1,當(dāng)電壓小于0.4V則被認(rèn)為是邏輯電平0,單片機(jī)的輸入捕獲功能來(lái)判斷輸入信號(hào)的電平是否為邏輯電平1,如果檢測(cè)到邏輯電平1,則認(rèn)為電容此時(shí)充電達(dá)到了2.4V以上,將這個(gè)時(shí)間記錄下來(lái),當(dāng)手指放在銅箔上的時(shí)候,相當(dāng)于增加了Cs的容值,此時(shí)我們繼續(xù)進(jìn)行輸入捕獲采樣,將這個(gè)捕獲的時(shí)間記錄下來(lái),兩個(gè)時(shí)間求差值,這個(gè)差值高于某個(gè)閾值的時(shí)候就可以認(rèn)為此時(shí)手指按下了電容按鍵,用這種方式就可以實(shí)現(xiàn)虛擬按鍵的使用了。這種檢測(cè)原理實(shí)際是采用了在電路分析中學(xué)習(xí)到的RC電路的零狀態(tài)響應(yīng)來(lái)實(shí)現(xiàn)的。根據(jù)RC電路的零狀態(tài)響應(yīng)可以得出電容的充電公式為
其中Vc表示電容的充電電壓,VDD為RC電路的輸入電壓,R為電阻的阻值,C為充電電容的容值,通過(guò)這個(gè)公式我們可以反推得到充點(diǎn)電容的容值。也就是說(shuō)我們可以利用這個(gè)公式實(shí)現(xiàn)電容的測(cè)量。
8.1.3 預(yù)備知識(shí)
首先我們?cè)谶M(jìn)行電容觸摸檢測(cè)的時(shí)候需要用到STM32的輸入捕獲功能,從這一章開(kāi)始,關(guān)于寄存器文件的添加,驅(qū)動(dòng)文件的添加不再作為重點(diǎn),重點(diǎn)開(kāi)始轉(zhuǎn)為程序的編寫(xiě)及小算法的編寫(xiě)。
輸入捕獲的工作原理如下圖所示。
首先設(shè)置定時(shí)器的輸入通道為上升沿捕獲,檢測(cè)到上升沿之后,將計(jì)數(shù)寄存器CNT中的數(shù)據(jù)存儲(chǔ)在CCRx1中并清空CNT的數(shù)據(jù),然后設(shè)置定時(shí)器的輸入通道為下降沿捕獲,檢測(cè)到下降沿后將計(jì)數(shù)寄存器CNT中的數(shù)據(jù)存儲(chǔ)在CCRx2中并清空CNT的數(shù)據(jù),此時(shí)將CCRx2的值與CCRx1的值做差值就可以得到1個(gè)波形中高電平的時(shí)間,由于這兩個(gè)數(shù)值獲取的過(guò)程中,會(huì)由于高電平時(shí)間過(guò)長(zhǎng)導(dǎo)致定時(shí)器產(chǎn)生多次中斷,這個(gè)多次中斷的值記為N,此時(shí)高電平的時(shí)間計(jì)算公式如下所示:
其中M為定時(shí)器的計(jì)數(shù)周期,N為定時(shí)器的溢出次數(shù),ARR為自動(dòng)重裝載計(jì)數(shù)器的值,CCRx2為捕獲到的數(shù)據(jù)。
8.2 常用寄存器
8.2.1 捕獲/比較寄存器1:TIMx_CCMR1
15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
IC2F[3:0] | IC2PSC[1:0] | CC2S[1:0] | IC1F[3:0] | IC1PSC[1:0] | CC1S[1:0] |
ICxF[3:0]:輸入捕獲x濾波器(定義輸入采樣頻率及數(shù)字濾波器長(zhǎng)度)
ICxPSC[1:0]:輸入/捕獲x預(yù)分頻器(一旦CCxE=0,則預(yù)分頻器復(fù)位)
00:每1個(gè)事件觸發(fā)一次捕獲
01:每2個(gè)事件觸發(fā)一次捕獲
10:每4個(gè)事件觸發(fā)一次捕獲
11:每8個(gè)事件觸發(fā)一次捕獲
CCxS[1:0]:捕獲/比較x選擇(用于定義通道x輸入還是輸出)
00:輸出模式
01:輸入模式,映射在TI1上
10:輸入模式,映射在TI2上
11:輸入模式,映射在TRC上,此模式引用于內(nèi)部觸發(fā)器輸入被選中時(shí)
8.2.2 捕獲/比較使能寄存器:TIMx_CCER
15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
- | CC4P | CC4E | - | CC3P | CC3E | - | CC2P | CC2E | - | CC1P | CC1E |
CCxP:輸入/捕獲x輸入/輸出極性
通道在輸出模式下
0:高電平有效
1:低電平有效
通道在輸入模式下
0:不反相,上升沿觸發(fā)
1:反相,下降沿觸發(fā)
CCxE:輸入/捕獲x輸入/輸出使能
通道在輸出模式下
0:關(guān)閉輸出
1:開(kāi)啟輸出
通道在輸入模式下
0:禁止捕獲
1:使能捕獲
8.3 電容觸摸例程
現(xiàn)在PA1端口接一個(gè)觸摸按鍵(一塊銅箔),利用PA1的觸摸按鍵控制PA0端口的LED狀態(tài),按下時(shí)LED點(diǎn)亮,抬起時(shí)LED熄滅。
(1)新建基礎(chǔ)工程,并創(chuàng)建tpad.c,tpad.h,led.c和led.h文件,并導(dǎo)入工程,如下圖所示。
(2)在tpad.h文件內(nèi)添加以下代碼。
(3)在led.h文件內(nèi)添加以下代碼
(4)在led.c文件中添加以下代碼
(5)在tpad.c文件內(nèi)添加以下代碼
#include "tpad.h"
#include "delay.h"
/***************************************************
Name :TPAD_Get_Value
Function :觸摸按鍵值獲取
Paramater :None
Return :獲取的充電時(shí)間
***************************************************/
u16 TPAD_Get_Value()
{
//電容放電
GPIOA->CRL &= 0xFFFFFF0F ; //PA1輸入
GPIOA->CRL |= 0x00000030 ; //推挽輸出
GPIOA->ODR &= ~( 1<<1 ) ; //輸出低電平放電
delay_ms( 5 ) ;
TIM5->SR = 0 ; //清除標(biāo)記
TIM5->CNT = 0 ; //歸零
GPIOA->CRL &= 0xFFFFFF0F ; //PA1輸入
GPIOA->CRL |= 0x00000040 ; //浮空輸入
//等待捕獲上升沿
while( ( TIM5->SR&0x04 )==0 )
{
if( TIM5->CNT>( 65535-500 ) )
return TIM5->CNT ;
}
return TIM5->CCMR2 ;
}
/***************************************************
Name :TPAD_Get_MaxVal
Function :觸摸按鍵最大值獲取
Paramater :None
Return :獲取的最大充電時(shí)間
***************************************************/
u16 TPAD_Get_MaxVal( u8 n )
{
u16 temp=0;
u16 res=0;
while( n-- )
{
temp = TPAD_Get_Value() ;
if( temp>res )
res = temp ;
}
return res ;
}
/***************************************************
Name :TPAD_Init
Function :觸摸按鍵初始化
Paramater :None
Return :None
***************************************************/
TPADData TPAD_Data ;
void TPAD_Init()
{
u16 buff[ 10 ], temp ;
u8 i, j ;
RCC->APB2ENR |= 1<<2 ;
GPIOA->CRL &= 0xFFFFFF0F ; //PA1 輸入
GPIOA->CRL |= 0x00000040 ; //浮空輸入
RCC->APB1ENR |= 1<<3 ; //TIM5時(shí)鐘開(kāi)啟
TIM5->ARR = 65535 ;
TIM5->PSC = 5 ;
TIM5->CCMR1 |= 1<<8 ; //選擇輸入端IC2映射到TI2上
TIM5->CCMR1 &= ~( 1<<12 ) ; //采樣頻率8分頻
TIM1->CCMR1 &= ~( 1<<10 ) ; //配置輸入不分頻
TIM5->CCER &= ~( 1<<5 ) ; //上升沿捕獲
TIM5->CCER |= 1<<4 ; //允許捕獲功能
TIM5->CR1 |= 1<<0 ; //開(kāi)啟定時(shí)器5
//連續(xù)采樣10次
for( i=0; i<10; i++ )
{
buff[ i ] = TPAD_Get_Value() ;
delay_ms( 10 ) ;
}
//排序
for( i=0; i<9; i++ )
{
for( j=i+1; j<10; j++ )
{
//升序排列
if( buff[ i ]>buff[ j ] )
{
temp= buff[ i ] ;
buff[ i ] = buff[ j ] ;
buff[ j ] = temp ;
}
}
}
temp = 0 ;
//獲取中間數(shù)據(jù)的均值
for( i=2; i<8; i++ )
temp += buff[ i ] ;
TPAD_Data.value = temp/6 ;
}
/***************************************************
Name :TPAD_Scan
Function :觸摸按鍵掃描
Paramater :None
Return :None
***************************************************/
void TPAD_Scan()
{
u16 rval ;
rval = TPAD_Get_MaxVal( 3 ) ;
if( rval>( TPAD_Data.value+100 ) )
TPAD_Data.State = 1 ; //手指按下
}
(6)在1.c文件內(nèi)添加主函數(shù)
#include "sys.h"
#include "delay.h"
#include "usart1.h"
#include "led.h"
#include "tpad.h"
int main()
{
STM32_Clock_Init( 9 ) ; //STM32時(shí)鐘初始化
SysTick_Init( 72 ) ; //SysTick初始化
USART1_Init( 72, 115200 ) ; //初始化串口1波特率115200
LED_Init() ; //LED初始化
TPAD_Init() ; //觸摸按鍵初始化
while( 1 )
{
TPAD_Scan() ; //觸摸按鍵掃描
if( TPAD_Data.State==1 )
{
LED = 0 ;
TPAD_Data.State = 0 ;
}
else
LED = 1 ;
}
}
——————————————分割線(xiàn)——————————————
8.4 STM32工程管理
這里的總結(jié)是針對(duì)與之前所學(xué)的所有嵌入式內(nèi)容進(jìn)行總結(jié),隨著后續(xù)代碼越來(lái)越多,對(duì)于工程的管理顯得格外重要,不僅僅是采用本章節(jié)介紹的方法管理工程代碼,對(duì)于后續(xù)的Linux開(kāi)發(fā)和操作系統(tǒng)移植也最好是按照固定的工程格式進(jìn)行管理。
對(duì)于STM32的工程可以劃分為以下幾個(gè)部分:
(1)過(guò)程文件以及最終生成的hex文件:這些文件通通放置在工程1級(jí)目錄下的OBJECT文件中,文件中的內(nèi)容如下圖所示。
圖中標(biāo)注部分就是最終生成的hex文件,其他的文件均屬于過(guò)程文件,集成開(kāi)發(fā)系統(tǒng)IDE編譯的實(shí)質(zhì)其實(shí)就是采用gcc交叉編譯器將我們編寫(xiě)的代碼轉(zhuǎn)換成對(duì)應(yīng)的機(jī)器代碼的過(guò)程,具體的步驟會(huì)在Linux系統(tǒng)移植中描述,這里只需要知道利用交叉編譯器進(jìn)行編譯的時(shí)候會(huì)產(chǎn)生大量的鏈接文件和過(guò)程文件,這些文件統(tǒng)統(tǒng)放置在OBJECT目錄下。將工程文件中的過(guò)程文件放置在該目錄下的設(shè)置方式如下圖所示。
(2)主函數(shù)文件及主工程文件:在Keil中創(chuàng)建的工程,以及包括main函數(shù)的c文件都位于這個(gè)目錄內(nèi)。
圖中標(biāo)注的3個(gè)文件都是必不可少的文件,帶有Keil圖標(biāo)的文件就是工程文件,里面包含了整個(gè)工程所需的頭文件,文件路徑以及編譯器位置,文本文件圖標(biāo)的則是c文件,main函數(shù)就放在這個(gè)位置,.s后綴的為匯編啟動(dòng)文件,用于幫助芯片創(chuàng)建C代碼運(yùn)行環(huán)境,初始化堆棧等功能,為了達(dá)到最快效率,所以采用匯編語(yǔ)言來(lái)編寫(xiě)這個(gè)文件。
(3)自定義系統(tǒng)文件:自定義的系統(tǒng)文件位于SYSTEM目錄中,目錄內(nèi)有3個(gè)子目錄,分別是sys,delay和usart1,如下圖所示。
delay目錄:是利用SysTick時(shí)鐘來(lái)實(shí)現(xiàn)的延時(shí)功能,主要有毫秒級(jí)延時(shí)和微秒級(jí)延時(shí);
usart1目錄:則是利用串口1來(lái)實(shí)現(xiàn)printf打印輸出的功能,主要用于調(diào)試數(shù)據(jù)的輸出;
sys目錄:是最基礎(chǔ)的工程文件,這個(gè)目錄內(nèi)有1個(gè)c文件和2個(gè)h文件,c文件主要實(shí)現(xiàn)STM32時(shí)鐘樹(shù)的配置和中斷系統(tǒng)的設(shè)置功能,是C函數(shù)中最重要的一個(gè)文件,stmxx.h文件則是最底層的寄存器定義文件,里面定義了STM32芯片內(nèi)部所有寄存器的地址和結(jié)構(gòu),通過(guò)C語(yǔ)言來(lái)調(diào)用這里面的寄存器實(shí)現(xiàn)芯片的控制功能。
(4)驅(qū)動(dòng)文件:驅(qū)動(dòng)文件位于HEADERWARE目錄中,用于存放項(xiàng)目所用到的驅(qū)動(dòng),比如之前實(shí)驗(yàn)所用到的LED,KEY,TIM這些外設(shè)都屬于驅(qū)動(dòng)文件內(nèi)容。
至此整個(gè)工程的目錄結(jié)構(gòu)如下圖所示。
-
機(jī)械
+關(guān)注
關(guān)注
8文章
1685瀏覽量
41880 -
按鍵
+關(guān)注
關(guān)注
4文章
227瀏覽量
58060 -
電容按鍵
+關(guān)注
關(guān)注
0文章
5瀏覽量
1496
發(fā)布評(píng)論請(qǐng)先 登錄
瑞薩電容觸摸技術(shù)之低功耗應(yīng)用—RX140實(shí)驗(yàn)環(huán)節(jié)(1)

迅為IMX6ULL開(kāi)發(fā)板Linux下電容觸摸實(shí)驗(yàn)程序編寫(xiě)
迅為IMX6ULL開(kāi)發(fā)板SRTC 電容觸摸實(shí)驗(yàn)編譯及運(yùn)行
電容觸摸屏和觸摸面板應(yīng)用的意義
ATK-7 TFT LCD電容觸摸屏模塊測(cè)試實(shí)驗(yàn)的工程文件免費(fèi)下載
電容觸摸的工作原理及應(yīng)用設(shè)計(jì)方式

“電容觸摸按鍵實(shí)驗(yàn)”實(shí)例解析

STM32學(xué)習(xí)心得十九:電容觸摸按鍵實(shí)驗(yàn)及相關(guān)代碼解讀

STM32入門(mén)學(xué)習(xí)筆記之電容觸摸實(shí)驗(yàn)(上)

STM32入門(mén)學(xué)習(xí)筆記之電容觸摸實(shí)驗(yàn)(下)

評(píng)論