主要内容9 [4 s3 X2 w; x6 y% E# t) M8 `+ `
1) 电容触摸按键原理;1 L7 ?; Z6 M5 m& u; r# L" i
2)部分实验代码解读。
7 K6 i3 ^; M; l& Y% L0 G实验内容
6 t! h5 }1 X: R1 I9 }手触摸按键后,LED1灯翻转。; o# ?% P' X) u f
% H0 N8 n: {" C: @4 n
硬件原理图
) @8 q* P1 u' P$ d; v$ ~: j% H \4 t @0 F
/ M8 ^: D* t# B
上图,TPAD与STM_ADC用跳线帽相连,即TPAD与PA1引脚相连,而PA1引脚也可复用为TIM5_CH2(定时器5的通道2),因此可以用TIM5_CH2进行输入捕获来识别电容触摸。6 y- x& w O( h4 N/ w. K6 e+ Y" Y# x
* y2 g" w, d1 c0 q
1. 电容触摸按键原理& H# ?8 `* E9 c* f" |# }
1.1 RC充放电电路原理
- d4 m- D) G$ [9 ^- e1 c+ h$ z2 |' u5 g% A' m
L6 S1 w4 {1 i# X6 F m$ }6 X
3 N, h5 K1 c, f: h( W2 D) i) C
1.2 RC电路充放电公式
" v6 w, M. N5 W+ F# o7 \$ ^2 p! f; S4 N& y, [
Vt = V0+(V1-V0)* [1-e(-t/RC)]# j& T5 O4 {$ Q
$ O- i9 D( K0 P# x$ W. [( B! D
上式中:V0 为电容上的初始电压值; V1 为电容最终可充到或放到的电压值; Vt 为t时刻电容上的电压值。 如果V0为0,也就是从0V开始充电。那么公式简化为:3 d, U. d8 ~+ `( z' }: v; h$ @$ }
Vt= V1* [1-e(-t/RC)]; J9 b, d! [2 U5 m+ ^5 d, F
3 ^# W) U9 b" l4 Y! L6 f结论:同样的条件下,电容值C跟时间值t成正比关系,电容越大,充电到达某个临界值的时间越长。
+ u) w) u0 @- M( v# D/ V* S1.3 电容充电时间与电容大小关系
* `; h: H2 k7 \7 M9 K% D+ n2 L4 ]8 q5 a: C ^, G- S
7 `' ~# e* L: \2 d W E4 H7 g; ^( I' G& e. C/ m
2. 电容触摸按键+ u5 g4 }7 y9 P* v
2.1 电容触摸按键原理* s7 S* l0 d* r+ t4 y9 p2 z* b4 Z: N
! o6 t. M! A% D1 y3 Z: r( ~/ F& {; k
2 f& e2 l+ e# [8 p% V6 T
' D$ {. X: p w
R:外接电容充放电电阻;$ u, ~3 j* m9 }8 N1 J
Cs:TPAD和PCB间的杂散电容;
' F) T, [' Q' {; I0 H. OCx:手指按下时,手指和TPAD之间的电容;
4 Q" C( Y* Z1 [1 Q s$ |8 Z开关:电容放电开关,由STM32 IO口代替。) ?5 t* Q6 M# |( R- t) @
2.2 检测电容触摸按键过程, M% v0 n( M5 A0 s! ?
2.2.1 TPAD引脚设置为推挽输出,输出0,实现电容放电到0;6 j+ D) `, x! h
2.2.2 TPAD引脚设置为浮空输入(IO复位后的状态),电容开始充电;! _7 W: X( D3 n2 A( @$ t
2.2.3 同时开启TPAD引脚的输入捕获开始捕获;
& D& x' `: j6 @6 M/ R2.2.4 等待充电完成(充电到底Vx,检测到上升沿); ~+ @1 u2 n9 `* c/ N1 ~8 E" d
2.2.5 计算充电时间。
$ S& ^5 Z# \/ a* i( ~没有按下的时候,充电时间为T1(default)。按下TPAD,电容变大,所以充电时间为T2。我们可以通过检测充放电时间,来判断是否按下。如果T2-T1大于某个值,就可以判断有按键按下。
3 y* O( m) z' Y, h. [8 ]/ e* S9 n# k' {9 |4 j; `
3. 相关库函数
0 V4 d: W0 ?8 h. m. {3.1 void TPAD_Reset(void)函数,) N! @% b B3 {+ D
作用:复位TPAD
4 c6 r$ v1 a& y: r4 [设置IO口为推挽输出输出0,电容放电。等待放电完成之后,设置为浮空输入,从而开始充电。同时把计数器的CNT设置为0。1 R; Q( u2 E5 f! Q
3.2 TPAD_Get_Val()函数,
. V: O6 w x0 [作用:获取一次捕获值(得到充电时间)
. D: h3 ], }0 Y, P! W复位TPAD,等待捕获上升沿,捕获之后,得到定时器的值,计算充电时间。3 ]0 i% x& S2 Y7 I: F
3.3 TPAD_Get_MaxVal()函数,* M4 x# ~* _6 k2 P- E6 k
多次调用TPAD_Get_Val函数获取充电时间,获取最大的值。
/ c6 a) ?0 X2 ~' E3 T! d+ _3.4 TPAD_Init()函数,
1 T3 y T0 p& g- L% K5 M6 o作用:初始化TPAD6 X4 A$ z9 {' R/ A& ?: a
在系统启动后,初始化输入捕获。先10次调用TPAD_Get_Val()函数获取10次充电时间,然后获取中间N(N=8或者6)次的平均值,作为在没有电容触摸按键按下的时候的充电时间缺省值tpad_default_val。
9 X4 \( S9 T2 l& z% P' y5 c) n" g3.5 TPAD_Scan()函数,
' w' a" p5 u4 L! ]& S$ ?作用:扫描TPAD j, Q$ i6 I0 g) u* y$ t. T
调用TPAD_Get_MaxVal函数获取多次充电中最大的充电时间,跟tpad_default_val比较,如果大于某个阈值tpad_default_val+TPAD_GATE_VAL,则认为有触摸动作。. i) l( p }& J
3.6 void TIM5_CH2_Cap_Init(u16 arr,u16 psc)函数,: e+ K' _$ \, ~7 v0 {! ^; X1 C( H
作用:输入捕获通道初始化' s. A! q9 T) Y- ?# P7 H
可以使用任何一个定时器。M3使用定时器5,M4使用的定时器2。. \% l( A- [8 o5 H. l, N' {2 j
% N0 y" `- u: Y' c$ M5 Q/ N. N' [
4. 程序思路1 [7 Z1 i B8 ], z
5 R: m) W- E& ~! `! j
, V. L/ q2 p. j- C5 g
+ a" `9 {0 C ~/ G- m0 O3 b$ x
5. 实验部分代码解读, _' H6 a6 T! f% e
5.1 tpad.h头文件6 _3 d1 Y* { i$ ^
q& K" e' n) ~* b, p# W
- #ifndef __TPAD_H7 S6 s, w: j, f) m" ~
- #define __TPAD_H
0 w6 \# j- l0 {+ N* Q5 g8 L - #include "sys.h" ( Y( h( r6 l) e/ |% r9 S2 m
- //引用在别的文件中申明的变量tpad_default_cal//
+ f. F6 G7 m' W; A$ O# h/ q E - extern vu16 tpad_default_val;/ U- ?) C8 W' ~. k) c! Z8 R- @
- //*****函数一*****//3 r/ R9 \- m+ n) i) H7 R
- //申明void TPAD_Reset(void)函数,无返回值,无入口参数// 9 ~% M* B8 T8 Z+ o
- void TPAD_Reset(void);* L" t+ G I$ q; i7 r7 J1 V* m
- //*****函数二*****//
~' g6 y; u( p# X - //申明u16 TPAD_Get_Val(void)函数,返回u16数据格式的值,无入口参数//" [8 V+ _2 u" ?' G% f. S2 i
- u16 TPAD_Get_Val(void);
) V/ ]8 G! c/ r8 W: f O - //*****函数三*****//! _% G3 h U4 G$ b, F( v/ W5 P& y
- //申明u16 TPAD_Get_MaxVal(u8 n))函数,返回u16数据格式的值,入口参数为8位的变量n//
% e: h" s/ W9 u0 r/ Z$ g - u16 TPAD_Get_MaxVal(u8 n);1 w5 z8 r+ T0 E
- //*****函数四->初始化触摸按键*****//
1 b' F/ j, @$ [5 Q. \* m# l3 C* C - //申明u8 TPAD_Init(u8 psc)函数,返回u8数据格式的值,入口参数为8位的变量psc//$ N9 Y! y. b" Q8 p* Z
- u8 TPAD_Init(u8 psc); x2 q4 _7 V; O4 \7 O, S8 R
- //*****函数五*****//2 |. [2 b" m7 t% w
- //申明u8 TPAD_Scan(u8 mode)函数,返回u8数据格式的值,入口参数为8位的变量mode//( \3 K! J, `# P. x. N: T$ }
- u8 TPAD_Scan(u8 mode);
) L- p, J1 x; ] - //*****函数六*****//
* o9 C/ Y( f3 X X" u R: Q) E6 r - //申明void TIM5_CH2_Cap_Init(u16 arr,u16 psc)函数,无返回值,入口参数为16位的两个变量arr和psc//
" T3 _9 L; Q( _) ?% O - void TIM5_CH2_Cap_Init(u16 arr,u16 psc);
+ g {) B e& g# x7 h - #endif& d$ o A& K$ H% f+ t7 w
复制代码 ; R d n& u V. O
5.2 tpad.c文件4 t$ w% T2 r- |" d& M
9 X6 X: V" B* x; i# f" Y
- #include "tpad.h"
: a' @9 Q* O& I( d$ O$ u - #include "delay.h"
" A0 J8 t0 {. r1 h! I - #include "usart.h"
. i+ w) a' ` m" k - //定义TPAD_ARR_MAX_VAL为一常量,即0xFFFF//9 }/ L( w% o: ]+ x
- #define TPAD_ARR_MAX_VAL 0XFFFF
5 U9 I+ L5 z. g$ W' c- b - //定义变量tpad_default_val=0,即空载时候(手没按下),计数器需要的时间//. r- S/ z% P9 J+ I3 ~% x- g9 b2 }
- vu16 tpad_default_val=0;! @- W2 {5 G% B( e; ^; d m
- //*****函数一—>TPAD复位-void TPAD_Reset(void)*****//
k5 ]1 l4 f" u) g/ z/ X - void TPAD_Reset(void)
5 f6 ?7 G9 G2 b8 U1 N9 S - {
' [ ]6 {$ u4 C- H$ D/ [ - GPIO_InitTypeDef GPIO_InitStructure; //定义GPIO初始化结构体//
- g, P) c; p" ] - RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能PA端口时钟// # ]; L; b A- |/ v: ]5 e" Q- F
- //设置GPIOA.1为推挽输出//4 c$ f+ p" [1 h& K
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; //PA1 端口配置, j) \! ]! v: [0 X. M
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出/ K# M' M* D1 Z: w' F
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //50MHz//7 x9 N! c% }# N# B% c: z: d
- GPIO_Init(GPIOA, &GPIO_InitStructure);
( ?6 h9 [2 z6 z: D - GPIO_ResetBits(GPIOA,GPIO_Pin_1); //PA.1输出0,放电//
+ c2 j5 z9 \4 z- j8 y0 L/ n - //等待5ms//# t1 Y5 e9 Q D# p
- delay_ms(5);+ x3 ?- F9 P3 e: u
- TIM_SetCounter(TIM5,0); //将TIM5_CNT计数器寄存器的值设0//3 M8 L# H# ^; v3 N. C
- TIM_ClearITPendingBit(TIM5, TIM_IT_CC2|TIM_IT_Update); //清除定时器5的捕获2标志和更新标志//! ]' k* T/ x) B M: ]0 a+ j+ K
- //设置GPIOA.1为浮空输入//
3 ^) w9 X% z1 C6 o$ i# i/ o9 z - GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING; //浮空输入//
# l+ N1 t; o0 o3 A - GPIO_Init(GPIOA, &GPIO_InitStructure); //再次初始化GPIOA0后,开始充电//
( |: q* g. @2 ]7 z - }
/ M' P% _- h8 i: e1 W - //*****函数二->获得TPAD捕获值-u16 TPAD_Get_Val(void)*****//
) u! K& q. ^6 [+ E! w' G/ T - //返回值:如果超时,则直接返回定时器5的计数值;如果没超时,则返回定时器5的CCR2寄存器的值//
) |8 v( ]) M( t# `( e: ] - u16 TPAD_Get_Val(void)
% H- w$ X1 K& q2 Z# i6 o - { # [" f- c s b+ `7 N$ Y
- TPAD_Reset();
/ ]7 t) h, |- ^7 Q - //针对TIM5_SR状态寄存器,输入模式下,当第[2]位值CC2IF为1时,即通道2捕获到上升沿,则运行下述括号内代码,否则跳过//
& m* c Q0 ~2 B. n: B" W1 T - while(TIM_GetFlagStatus(TIM5, TIM_IT_CC2) == RESET) 9 c! B% z5 b+ w2 K/ Q" B: w+ j
- {- {; T9 n4 n- A( J/ r' e1 w! q) P
- //针对TIM5_CNT计数器寄存器,若TIM5_CNT的值大于TPAD_ARR_MAX_VAL-500,返回TIM5_CNT的值,表示超时了//
5 n0 p! g9 g- e3 j - if(TIM_GetCounter(TIM5)>TPAD_ARR_MAX_VAL-500)return TIM_GetCounter(TIM5);" B$ {1 l5 D6 v* h
- }; ! K/ Q3 a4 |2 w6 l2 ~9 |
- //若没超时,返回TIM5_CCR2的值//
9 ?% @3 F9 ]0 S# Y& n2 k& q2 n/ R - return TIM_GetCapture2(TIM5);
; z# ~1 u; x' w+ F - }
9 j" b$ y% G6 _. [" x" T( Z - //*****函数三->读取n次,取最大值-u16 TPAD_Get_MaxVal(u8 n)*****//
. [6 @- d3 X$ K) }3 f0 z* J. L - //返回值:n次读数里面读到的最大读数值res//
& O5 j* w" }* r% z8 n0 M - u16 TPAD_Get_MaxVal(u8 n)' |& T1 K* C8 s+ m) Q' o% f" y
- {
% a" Q6 I) k0 W3 x. F - u16 temp=0;
2 X/ I7 c& j9 _% I \7 E - u16 res=0;
9 b. C- I) {% Z0 Q7 Z, N - while(n--)6 k1 b, D" L0 |# b
- {
4 Z" H3 ~1 G& F2 _ - temp=TPAD_Get_Val();//得到一次值
& f: q; V2 o( r E. E' L - if(temp>res)res=temp;
) s+ Y8 C) K0 M' q9 \/ N' W- x G - };9 s# `. R* x* s- N9 p+ ]" F6 Q
- return res;+ S) ]% D% I! L7 {( w% N' z
- }
' } T- t# b8 D0 ` - //*****函数四->初始化触摸按键-u8 TPAD_Init(u8 psc)*****//
5 c" i- |4 B2 z% @1 T1 T9 p# c6 } - //作用:获得空载时触摸按键的取值//; N% ]2 I+ v9 u. y- Q( j( d
- //返回值:0,初始化成功;1,初始化失败// M+ u1 d% ?- K
- u8 TPAD_Init(u8 psc)
1 }9 Y+ O+ u# o$ Q2 D4 O- y8 b4 U - {6 Y& m; v" ?+ k3 K
- u16 buf[10]; //一个16位,组数长度为10的变量组//6 p# }; N0 V5 l4 X4 `
- u16 temp; //一个16位变量temp//
H, A2 L9 |# c, R# U# t0 } - u8 j,i; //两个8位变量j和i//
) ]8 H. A0 S2 r f4 K' M2 x- ] - TIM5_CH2_Cap_Init(TPAD_ARR_MAX_VAL,psc-1); //以1Mhz的频率计数 3 s# e" F7 ~$ w8 r6 A+ R
- //10次for循环//( k; W. o( p' g! t) @7 ~9 n
- for(i=0;i<10;i++)
1 a9 T0 N1 T+ N- \ - { $ @/ ?3 A7 J, e$ R6 q# y
- buf<i>=TPAD_Get_Val(); //将第i次循环获取的TPAD_Get_Val()返回值传至buf<i>中//
# J% x) @5 {+ f! G w - delay_ms(10); //10ms延迟// ! T1 S p+ v Y/ a- A
- }
3 S7 {4 v0 N; B2 X( S1 @, _7 D - //*****将buf里的10个数值由小到大排列*****//
% n, K) D, N6 U+ |, K - for(i=0;i<9;i++)9 b& {. X7 E( [: s6 u& O6 E
- {5 B7 q. j9 ~5 J
- for(j=i+1;j<10;j++)- }4 ?5 G: h, g, q" N8 z6 P
- {
# y: ]4 B( D. A/ { - if(buf<i>>buf[j]); \6 e- X( z' B4 ~. \, Y
- {/ V0 c/ X4 A2 i' _
- temp=buf<i>;
' i( V1 n4 O; B1 m# V+ s' Z - buf<i>=buf[j]; P& P) i6 S! V# n
- buf[j]=temp;6 V3 U5 A1 B0 _. ]. ]$ [* Q
- }
/ @3 T+ `2 C2 \' N7 } - }* G' L+ a; s! f9 z& f# [: `
- }
! X6 r4 v* m5 Y& n5 K6 C* D! W" |! P - //*************************************// B" M3 N, A: [9 N- d. e% T/ z
- //******buf[2:7]六个数据加起来平均******//5 V* V+ J& |; N5 j( p! J' j& [
- temp=0;7 m7 f4 O x& R8 B y& ]7 S$ @" _4 P% M
- for(i=2;i<8;i++)1 r1 n6 a9 d) @: ^" H5 W+ o N
- temp+=buf<i>;
. Y4 |+ i# l: L0 @7 K* o - tpad_default_val=temp/6; //赋值给tpad_default_val//% [! B/ T" A. H( t. g+ S6 `
- printf("tpad_default_val:%d\r\n",tpad_default_val);
. G L5 t& i) \; U9 ^/ J7 c - //若上述计算的均值大于TPAD_ARR_MAX_VAL的一半,则不正常//
- C) A f+ V. T) J/ Z: }8 q - if(tpad_default_val>TPAD_ARR_MAX_VAL/2)
$ a" p# n3 O+ w1 I# p/ ^# H3 I - return 1;! ~. Z- g* W9 G B
- return 0;
- F% }8 L5 |7 ~0 A4 Z$ A; w - }8 n" p5 R& `, Q
- //*****函数五->扫描触摸按键-u8 TPAD_Scan(u8 mode)*****//
' i$ a" \6 o, n- J - //mode:0,不支持连续触发(按下一次必须松开才能按下一次);1,支持连续触发(可以一直按下)//
- D( e8 L; ]. m" B7 M) c - //返回值:0,没有按下;1,有按下; //
# U) n( R/ H( `2 y4 r& ` - #define TPAD_GATE_VAL 100 //触摸的门限值,也就是必须大于tpad_default_val+TPAD_GATE_VAL,才认为是有效触摸.//
5 w, I8 Z$ b( H: U" ]6 f" g/ X Q - u8 TPAD_Scan(u8 mode)
6 y+ C$ o- s& w+ j# m" J - {4 y4 v" W0 V9 @# y* B+ F1 O7 B
- static u8 keyen=0; //0,可以开始检测;>0,还不能开始检测//
5 Y& X& w" K; B+ \/ O8 z - u8 res=0; //res=0说明按键无效,res=1说明按键有效//
% u& i, \1 Q% \+ Q& Z2 _/ w$ t - u8 sample=3; //默认采样次数为3次 1 V3 g4 s3 X* j; w: j$ i: e
- u16 rval; //
- C8 H# g, ?" T" |4 r7 v - if(mode) //mode:0,不支持连续触发//
0 N0 ?$ S5 V& K3 ~( V - {7 s8 M _# j7 [ r
- sample=6; //支持连按的时候,设置采样次数为6次. G0 w3 z/ c" ?: `
- keyen=0; //支持连按
" i) p, S! x( E' \% Y - }
: i! R; K0 P/ f# l4 c, i - rval=TPAD_Get_MaxVal(sample); //连续采样三次,取最大值//. x) _- x! h- ?: @) U
- if(rval>(tpad_default_val+TPAD_GATE_VAL)) //如果rval大于tpad_default_val+TPAD_GATE_VAL,则有效触摸//3 ^* ^3 G# b$ g; w# x# Z
- {
/ ]) E/ S, V: g" R1 g - if(keyen==0) //0,可以开始检测;>0,还不能开始检测// 9 y! N7 h- ~ r, h
- res=1; //当keyen==0,res至1,触摸有效//
# n! E3 R+ A( k$ z( y& }% E - printf("r:%d\r\n",rval);
5 h; S( v$ t& L5 x9 U. P - keyen=3; //至少要再过3次之后才能按键有效// 1 g9 g; f8 z: J* A5 g4 |3 k/ K
- } ) A, z( V: U# E9 l4 Z8 `
- if(keyen)keyen--; //keyen不等于0时,keyen减1//
9 ]/ d8 n2 X4 O& N( o* `/ j; \ p+ y! H - return res; //res=0说明按键无效,res=1说明按键有效//) U: a u5 O% g" S w% }
- }
k+ L' w+ r W - //*****函数六->定时器2通道2输入捕获配置-void TIM5_CH2_Cap_Init(u16 arr,u16 psc)*****//2 c1 A1 ~$ M6 R) Z( g/ g Z0 x3 S
- void TIM5_CH2_Cap_Init(u16 arr,u16 psc)- D4 Q1 P3 G0 I7 k
- {
1 R: s3 n2 w: p7 G3 d' @! S' R - //定义GPIO,TIM时基和TIM输入捕获三个初始化结构//) I# F! {% C; o( O) A" s. \4 P- W* n
- GPIO_InitTypeDef GPIO_InitStructure;
6 z) r1 F& O3 ~4 B3 a2 f Z! q - TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;0 K( a, x0 E3 o
- TIM_ICInitTypeDef TIM5_ICInitStructure; a9 }7 x+ l3 W" i
- //使能TIM5时钟,使能GPIOA的端口时钟//7 N: h0 k& K y$ ?& g
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE);
+ K# d" L% e1 y( t5 t - RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
* z$ X @/ d% y6 u7 E0 b1 g/ h - //设置GPIOA.1为浮空输入,
* n0 V+ a$ J# C* P+ T0 k g9 t8 ~% P - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
5 b5 |& ]$ ^" U - GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;
; o7 j6 H B3 F. A! M - GPIO_Init(GPIOA, &GPIO_InitStructure);
3 R- H2 W! \/ u' k% C# g - //初始化TIM5时基//
! f$ _+ e' O2 o - TIM_TimeBaseStructure.TIM_Period = arr; //设定计数器自动重装值 % G' v$ g/ l+ e
- TIM_TimeBaseStructure.TIM_Prescaler =psc; //预分频器 . |# Y, J4 ]& v- u4 A2 q0 Y2 s1 `
- TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim
8 n9 r* W- R, _ - TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
5 }; y% p" m* b; W3 y2 W) y - TIM_TimeBaseInit(TIM5, &TIM_TimeBaseStructure);
' N$ z' R5 {! [ - //初始化TIM5的捕获通道2//
, g4 y1 _5 {2 O$ H, `* l - TIM5_ICInitStructure.TIM_Channel = TIM_Channel_2; //CC1S=01 选择输入端 IC2映射到TI5上2 k' z; P6 D1 n7 ^6 p/ ^4 j
- TIM5_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; //上升沿捕获
. l8 K( `/ p3 \5 a( Z6 L; u' e9 Y - TIM5_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
( U% I" d3 o) j7 `0 o3 T+ X5 x - TIM5_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; //配置输入分频,不分频
; _) l% T+ j0 h( t - TIM5_ICInitStructure.TIM_ICFilter = 0x03; //IC2F=0011 配置输入滤波器 8个定时器时钟周期滤波
6 @8 L7 A, U5 q - TIM_ICInit(TIM5, &TIM5_ICInitStructure); ]/ p t* y7 b1 B0 e
- //使能定时器5//
4 M9 S$ h4 `% T# o# t7 M% g - TIM_Cmd(TIM5,ENABLE );
; }1 G( A, G8 {( ?+ g. h - }</i></i></i></i></i></i>
复制代码
$ Z. A( u* U" r8 Y0 {5.3 main.c文件
3 p5 O* {! _& p' `# Q
7 ?& L& P9 T* k6 i8 y3 u$ l- #include "led.h", {0 X: }6 R. k0 b
- #include "delay.h"
# W: e1 G f) }9 } - #include "key.h". P4 L( H) Y6 [$ b$ [
- #include "sys.h"( j/ E6 S+ {3 b' V9 [
- #include "usart.h"
3 \2 z- m3 I5 w/ k) W- @8 s5 t - #include "tpad.h"
7 b4 W! M% i( O& S - int main(void)
9 J9 y( P& @) d& F; E - {
/ j& p( g9 I% \' ]/ O - u8 t=0; % A9 [5 E( o+ U# P* ~2 u k ^
- delay_init(); //延时函数初始化
# E& k3 g3 r2 m - NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置NVIC中断分组2:2位抢占优先级,2位响应优先级
4 U5 L2 N" R8 ?) _( M8 b - uart_init(115200); //串口初始化为115200
/ |, e( B- I$ m - LED_Init(); //LED端口初始化
" z/ D d! `8 S7 z* Q* j, j. Z% n - TPAD_Init(6); //初始化触摸按键
! f1 T( c& R j! B - while(1)8 S- P. b6 E3 |% H+ X7 h
- {
|' _3 a! J, Y* ?+ I* ~" e - //TPAD_Scan(1)支持连续触发,TPAD_Scan(0)不支持连续触发//
8 R F/ I, w5 }2 n. y! h - if(TPAD_Scan(1)) //如果成功捕获到了一次上升沿,if返回1
6 `- |) }- T: Q- S; K$ B - {
' |( Y) ~1 z% T0 Q9 |7 @* R0 X% i - LED1=!LED1; //LED1取反//
5 j( ^9 e; {# G - }
d3 v4 [5 Z4 U1 \7 O - t++;
' S, d3 F& r! O. ^! n/ ? - if(t==15) $ h4 @) v, k- J# G) e/ H( H1 T
- {
) |- t& i0 v I5 c+ m - t=0;% H% K: k; k( p* s* Y6 g w0 x, A
- LED0=!LED0; //LED0取反,提示程序正在运行/ z) t% M, p; z$ ?8 D
- }
0 o9 t c0 D9 |* P! i - delay_ms(10);
$ ?& d! `) T5 B - }* W/ g' t w T- \3 ^
- }
复制代码
A/ z1 W4 n: `9 ?
+ b0 D7 i" V" j3 x% V; _4 n————————————————; z; b. c& Y/ t' j0 i* U$ n
版权声明:天亮继续睡( B: N! L- H) F; {" q, H1 Z# H
% r+ G) i" {6 K# i
$ J6 s5 k9 W* z0 G s& }
|