主要内容, T6 Q2 s M3 c3 ?3 J7 g
1) 电容触摸按键原理;
" X: i. v) m% r2)部分实验代码解读。
; k$ ]7 m s4 s" g4 H. r* ^, C: M实验内容; S" C" _/ v( O
手触摸按键后,LED1灯翻转。& v8 q4 Z% v; X3 W3 Q
, ]: J" ~3 \) Z) S硬件原理图
4 ]0 F$ t2 R+ {7 o2 g" H, H
& f6 e$ t9 c9 \
$ g, W% r; y/ p' \3 X
上图,TPAD与STM_ADC用跳线帽相连,即TPAD与PA1引脚相连,而PA1引脚也可复用为TIM5_CH2(定时器5的通道2),因此可以用TIM5_CH2进行输入捕获来识别电容触摸。
* ]4 n2 t% |, F4 a1 G9 e+ B& H: n' Z$ Y8 s8 q3 [$ T
1. 电容触摸按键原理
9 Y+ N( O3 V' ]( S7 y/ ]1.1 RC充放电电路原理# x4 H% B- C, i/ B& ]4 S
" h$ g3 ~7 P% P8 ]$ x; V
! t$ t' y2 G5 `; ^' i+ X
( O& | h# J# x! S! J. D+ g- F
1.2 RC电路充放电公式
% A) J6 u" f4 R# ~. o; g2 v% o$ G0 y% V* x4 X; d, U( |, R& [2 h, P1 {
Vt = V0+(V1-V0)* [1-e(-t/RC)]" W' c' _9 M- Y S( ^( `, G0 k
. ?3 k; E4 G; \% o) I7 z. O上式中:V0 为电容上的初始电压值; V1 为电容最终可充到或放到的电压值; Vt 为t时刻电容上的电压值。 如果V0为0,也就是从0V开始充电。那么公式简化为:: n9 F B* P/ R' M' k
Vt= V1* [1-e(-t/RC)]3 l' T8 W, L7 w j' L
+ U7 O: n1 H# H结论:同样的条件下,电容值C跟时间值t成正比关系,电容越大,充电到达某个临界值的时间越长。
$ i: Z9 c e7 u# i5 z# x: a4 ?2 a3 B- ]1.3 电容充电时间与电容大小关系
) k8 H. g# D3 [7 z" S- l5 B" U; N" e. v% ?6 ~# x6 f6 y
7 ?0 w' p+ c j( X# G# V+ L) X0 S+ x& T
2. 电容触摸按键
% B& R5 C0 E1 f& `6 y2.1 电容触摸按键原理
3 a8 N0 o e4 c7 ^
& Z% q4 J' J2 C4 T- \% i( L1 w
! i5 f3 ]; X; J
( T" c1 y% D& h/ I8 H) `
R:外接电容充放电电阻;
5 ^3 O. T5 K T( }- NCs:TPAD和PCB间的杂散电容;
8 @; `# `% v O; A) oCx:手指按下时,手指和TPAD之间的电容;
0 |. @6 X/ d1 z3 `6 ~, V开关:电容放电开关,由STM32 IO口代替。
, U! F6 o4 c0 H- b1 Y9 i: {2.2 检测电容触摸按键过程' A U! g! Q9 M! E9 y1 I
2.2.1 TPAD引脚设置为推挽输出,输出0,实现电容放电到0;
" ] }; R$ i( S u2.2.2 TPAD引脚设置为浮空输入(IO复位后的状态),电容开始充电;% b1 i B3 P9 U" A
2.2.3 同时开启TPAD引脚的输入捕获开始捕获;
% I6 j8 E; ~$ K* q6 h2.2.4 等待充电完成(充电到底Vx,检测到上升沿);% T# K3 d, V, q; j% q
2.2.5 计算充电时间。
0 V) ]; y) ?. d# X z没有按下的时候,充电时间为T1(default)。按下TPAD,电容变大,所以充电时间为T2。我们可以通过检测充放电时间,来判断是否按下。如果T2-T1大于某个值,就可以判断有按键按下。/ N8 y- d; i# }, e/ j, q
4 B! b& ]: z- X( K: {; q3. 相关库函数3 F2 c- _1 p; |- Q/ n6 Y
3.1 void TPAD_Reset(void)函数,
k9 E1 U5 U; \! R作用:复位TPAD8 t: R9 w+ L( J# v7 d: P5 ]
设置IO口为推挽输出输出0,电容放电。等待放电完成之后,设置为浮空输入,从而开始充电。同时把计数器的CNT设置为0。1 _+ Q# M9 H) Q5 P4 l
3.2 TPAD_Get_Val()函数,7 [- p6 D& U9 K) ?$ U- U
作用:获取一次捕获值(得到充电时间)" ^( I2 h" ~: m, M7 B; p
复位TPAD,等待捕获上升沿,捕获之后,得到定时器的值,计算充电时间。
) _# O2 f, a7 Z. R5 G% r3.3 TPAD_Get_MaxVal()函数,
9 V* F1 ~9 u; ~8 Y' B( k0 Z( q多次调用TPAD_Get_Val函数获取充电时间,获取最大的值。& G. I) W9 V" q; l
3.4 TPAD_Init()函数,% G" V8 b0 o7 {/ s
作用:初始化TPAD
6 o" n- {& b, M: C" b在系统启动后,初始化输入捕获。先10次调用TPAD_Get_Val()函数获取10次充电时间,然后获取中间N(N=8或者6)次的平均值,作为在没有电容触摸按键按下的时候的充电时间缺省值tpad_default_val。! x8 K& E) `7 Q+ g0 u
3.5 TPAD_Scan()函数,
$ z0 x* o4 A9 y0 B作用:扫描TPAD; Q! _" B, o' M
调用TPAD_Get_MaxVal函数获取多次充电中最大的充电时间,跟tpad_default_val比较,如果大于某个阈值tpad_default_val+TPAD_GATE_VAL,则认为有触摸动作。
* ~; y9 B! u/ p; Q: z: d3.6 void TIM5_CH2_Cap_Init(u16 arr,u16 psc)函数,
$ I; ]6 Q3 B9 f4 f& e, E作用:输入捕获通道初始化3 A% k- W* q$ l, ^0 z, I4 t6 {6 z
可以使用任何一个定时器。M3使用定时器5,M4使用的定时器2。; X# z5 H- M9 U% |- |: l
3 J# x& h9 x5 `- J6 n
4. 程序思路
8 R9 H8 b2 [( [* ]5 s3 c m- ^7 P
7 L3 n, g) e3 x. ]$ |
+ L; s6 `# _$ [& H' }
4 H$ w$ \: u& @! ~9 d7 S5. 实验部分代码解读
- K. |( \$ E, L Q" @5.1 tpad.h头文件3 u0 j& F2 c, P2 i
3 i" [' ?& w: Y( ]+ g' B- #ifndef __TPAD_H# A/ t6 b8 M# {4 A( W2 x2 Y7 S
- #define __TPAD_H# `0 `- g5 S3 i& y
- #include "sys.h"
9 M" E7 b' M% ^* C - //引用在别的文件中申明的变量tpad_default_cal//
v4 D1 \& u2 C3 V - extern vu16 tpad_default_val;/ H: L- ?6 v+ Q5 R. X
- //*****函数一*****//7 Q: A# _% \! {! x
- //申明void TPAD_Reset(void)函数,无返回值,无入口参数// : a8 n) L$ L$ U. L( b7 a. [% Q& }; t
- void TPAD_Reset(void);) @& y4 o6 A3 c9 ~8 w; @6 m$ n
- //*****函数二*****//
0 F6 |2 {5 u; h+ ` z! } - //申明u16 TPAD_Get_Val(void)函数,返回u16数据格式的值,无入口参数//
5 |7 b2 G8 x9 g. x9 J P - u16 TPAD_Get_Val(void);7 c4 e7 r6 R$ n; \
- //*****函数三*****//
: E8 R% ]1 [9 x) g7 }( w% q, A; X - //申明u16 TPAD_Get_MaxVal(u8 n))函数,返回u16数据格式的值,入口参数为8位的变量n//2 a9 R5 Y+ P O0 g( u1 b: b
- u16 TPAD_Get_MaxVal(u8 n);% f" j% o, B7 X. t# P
- //*****函数四->初始化触摸按键*****//' \# C# v5 {# f4 O4 T2 Z- M+ Q
- //申明u8 TPAD_Init(u8 psc)函数,返回u8数据格式的值,入口参数为8位的变量psc//
h/ ?% I3 e/ [9 i: K6 \% a1 K3 h - u8 TPAD_Init(u8 psc);
0 V1 ]6 _- {8 P' `0 {( B; z - //*****函数五*****//! L; |. H0 s h% N* p1 j
- //申明u8 TPAD_Scan(u8 mode)函数,返回u8数据格式的值,入口参数为8位的变量mode//( _5 t+ i4 n' S0 G* T# v5 j
- u8 TPAD_Scan(u8 mode);; N0 n! T) t% t; P+ u; E+ C* v- Q
- //*****函数六*****//
. w+ }+ I# W. s- H9 f' g - //申明void TIM5_CH2_Cap_Init(u16 arr,u16 psc)函数,无返回值,入口参数为16位的两个变量arr和psc//( @3 t* \5 Z7 `2 `8 O2 _; ~/ z
- void TIM5_CH2_Cap_Init(u16 arr,u16 psc);
) z! H. p( o/ G3 u4 y - #endif$ V" r+ r$ E% p5 Q, K9 a8 X7 v
复制代码
" t8 _. Q2 J8 @3 h) i% [3 H' Q5.2 tpad.c文件& D" U0 |9 R% D' F
# s8 ?% s- V! I5 D! H, m2 |- #include "tpad.h"
: \9 J1 z8 h2 |7 m7 r: [ b - #include "delay.h" 8 j, o7 G! W \9 K' q4 {( t" G# R5 a
- #include "usart.h"
7 I% S% y/ D% p" f; J0 g1 I - //定义TPAD_ARR_MAX_VAL为一常量,即0xFFFF//: Y6 E; a. w n
- #define TPAD_ARR_MAX_VAL 0XFFFF
8 x, |" O# ] g; M, @ - //定义变量tpad_default_val=0,即空载时候(手没按下),计数器需要的时间//
& d- N% J1 J7 N) S- h - vu16 tpad_default_val=0;/ T/ ^& n' `# X4 p( D
- //*****函数一—>TPAD复位-void TPAD_Reset(void)*****//
* V+ ^5 t( A! e" d# A - void TPAD_Reset(void); w! z/ j3 T r: K4 c1 {4 L! \9 m. K
- {
, J) [9 E" D! c& z8 A& M w - GPIO_InitTypeDef GPIO_InitStructure; //定义GPIO初始化结构体/// p6 b# v7 N c, H% O3 e
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能PA端口时钟//
( e/ \/ [2 l) }5 K D: [ - //设置GPIOA.1为推挽输出//+ ?4 e& m0 [+ r. r
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; //PA1 端口配置, S) A4 }4 N( S ~" {( m
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
) e& s1 n2 ?% ~ y0 r/ | - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //50MHz//& z; G1 Q- V0 L, u2 |8 }8 W7 H
- GPIO_Init(GPIOA, &GPIO_InitStructure);
# N6 F! E! J! Q& h y5 E - GPIO_ResetBits(GPIOA,GPIO_Pin_1); //PA.1输出0,放电// A& n0 [' g" ^8 N# u
- //等待5ms//
5 A5 Z6 a& H: B - delay_ms(5);5 ?/ v/ z4 I* R+ o
- TIM_SetCounter(TIM5,0); //将TIM5_CNT计数器寄存器的值设0//
) `$ x+ ^* `2 a4 Q6 A0 w - TIM_ClearITPendingBit(TIM5, TIM_IT_CC2|TIM_IT_Update); //清除定时器5的捕获2标志和更新标志//# N' d& [4 B, ~
- //设置GPIOA.1为浮空输入//
# P& ?2 @! |+ v& I) u) [ - GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING; //浮空输入//. Q# O8 G" q- p2 E: Z" B" ^ `
- GPIO_Init(GPIOA, &GPIO_InitStructure); //再次初始化GPIOA0后,开始充电// m7 t7 Y: a% B3 q! ]: K5 b
- }1 U" F/ C6 E3 V% D
- //*****函数二->获得TPAD捕获值-u16 TPAD_Get_Val(void)*****//
: E. q& V, ^* h' F! z6 [* U* ^* T' n - //返回值:如果超时,则直接返回定时器5的计数值;如果没超时,则返回定时器5的CCR2寄存器的值//
4 Q/ v* f: e* P- f. n! |5 Z- W5 c - u16 TPAD_Get_Val(void)
9 i/ ] k1 X" g/ L - { 0 B/ l' C# b6 Z# J
- TPAD_Reset();( v$ l8 {- U4 B
- //针对TIM5_SR状态寄存器,输入模式下,当第[2]位值CC2IF为1时,即通道2捕获到上升沿,则运行下述括号内代码,否则跳过//
: o1 r4 ~* R3 m& g h+ b" M - while(TIM_GetFlagStatus(TIM5, TIM_IT_CC2) == RESET)
I# x5 p! H1 N5 Z - {
9 y$ B) a9 S, Q; k: g% J& C - //针对TIM5_CNT计数器寄存器,若TIM5_CNT的值大于TPAD_ARR_MAX_VAL-500,返回TIM5_CNT的值,表示超时了//
) h0 q( o& J& h. u - if(TIM_GetCounter(TIM5)>TPAD_ARR_MAX_VAL-500)return TIM_GetCounter(TIM5);
# C$ Z$ q4 J2 m0 [) y$ I# z - }; 8 i% P+ h; S( D! r2 I! ]
- //若没超时,返回TIM5_CCR2的值//
0 }1 j9 M0 J) t3 t* G% I/ f - return TIM_GetCapture2(TIM5);
; ^) N/ F R+ l - }
' Q6 ^% j* }, `7 i$ |: f( R - //*****函数三->读取n次,取最大值-u16 TPAD_Get_MaxVal(u8 n)*****//9 v( ^2 k% G, l8 |0 ~
- //返回值:n次读数里面读到的最大读数值res//
! M" e+ V( b# b4 U; ]+ c3 b9 h - u16 TPAD_Get_MaxVal(u8 n)
" k1 D0 _- ?7 |6 E - {6 X; C6 g0 y& K
- u16 temp=0;$ ]% @9 i/ W/ l: h7 f
- u16 res=0;$ X- N: [3 S- v. o+ v G. t
- while(n--)* C$ m' s) m- [: S$ o/ F
- {# t9 _! |) S9 x: \% i9 w$ |/ c
- temp=TPAD_Get_Val();//得到一次值
4 `/ Z/ ^: V. j* R6 R - if(temp>res)res=temp;2 K* I I# Q4 B h6 \
- };
( H1 E: ?" t# F' G+ Y - return res;
5 j7 U2 A6 N& [ - } 4 P" t& t0 z+ \+ y% d
- //*****函数四->初始化触摸按键-u8 TPAD_Init(u8 psc)*****//6 E, p- f! j* B+ Y+ L
- //作用:获得空载时触摸按键的取值//- ~7 E% U/ |9 q2 q! B! Q
- //返回值:0,初始化成功;1,初始化失败//
8 ]7 X# i/ Z; O2 L) T3 a5 j - u8 TPAD_Init(u8 psc), _' `9 T7 e+ d6 n( j2 n
- {! }- C1 |! H' G3 x7 U
- u16 buf[10]; //一个16位,组数长度为10的变量组//* R) \. V J# r* u$ j* m# b
- u16 temp; //一个16位变量temp//
) Z; I$ ^% k* ^7 f1 W - u8 j,i; //两个8位变量j和i//5 ?2 S$ L( Z$ q, v2 F5 b ^7 z
- TIM5_CH2_Cap_Init(TPAD_ARR_MAX_VAL,psc-1); //以1Mhz的频率计数 ; v T. T i0 F' R* r
- //10次for循环//
9 o" h/ g ^3 K K - for(i=0;i<10;i++)& I! q2 t r1 P
- { ) B9 y4 u, W% E$ E5 l4 P% W9 E
- buf<i>=TPAD_Get_Val(); //将第i次循环获取的TPAD_Get_Val()返回值传至buf<i>中//8 n9 i; _ h$ W# x& n' P" l
- delay_ms(10); //10ms延迟//
* n# S5 \5 Z+ L8 | - }
) Y# y$ v! `4 ~3 m# A - //*****将buf里的10个数值由小到大排列*****//$ Y4 O8 x6 Z5 A/ f+ I( y# }
- for(i=0;i<9;i++)
$ _% @2 M) u* v - {
% j, n2 r5 L1 r- Y - for(j=i+1;j<10;j++)8 z% n6 r O# H) R: A2 u
- {
9 a1 j$ @5 Y, y+ s% a+ Y! e - if(buf<i>>buf[j])& `- y# x8 P- S5 t
- {( k. `1 Q6 K( l2 N3 l. @
- temp=buf<i>;6 M8 ]; ~& A; t. C
- buf<i>=buf[j];# x( a5 Y! r* v/ Z) c, b1 c' R/ S
- buf[j]=temp;
F9 Z. N n' x% [- | - }6 Y$ f, i" u) a. c$ y* B# Y4 j4 p
- }4 z7 \+ b2 w' v" i k: ?3 h+ @: T
- }2 n7 d" Y5 m1 n
- //*************************************// v& h; l1 U# v) e! ?
- //******buf[2:7]六个数据加起来平均******//- p9 g( A) t$ ?
- temp=0;9 @) V! \4 X# a/ M% f, N
- for(i=2;i<8;i++)$ m5 m% N2 F/ o! p2 h7 f# T
- temp+=buf<i>;
9 x7 t5 O6 l! G8 h - tpad_default_val=temp/6; //赋值给tpad_default_val//( C3 r$ E& ^+ R- j' t' f" O
- printf("tpad_default_val:%d\r\n",tpad_default_val);
* x, l% ~8 W7 d/ R7 X# J7 {) ?3 v& K - //若上述计算的均值大于TPAD_ARR_MAX_VAL的一半,则不正常//
8 |! z9 O: m8 ]* O - if(tpad_default_val>TPAD_ARR_MAX_VAL/2)4 q f3 A0 J9 R
- return 1;
W4 ^5 O* V5 Z* M1 x2 w8 C8 } - return 0;
- ]' z2 j' z f. S1 j! Y - }0 j6 Q$ z! t! n$ O" ^0 D
- //*****函数五->扫描触摸按键-u8 TPAD_Scan(u8 mode)*****//) R0 [* @+ \3 J; H5 L- g
- //mode:0,不支持连续触发(按下一次必须松开才能按下一次);1,支持连续触发(可以一直按下)//
* z/ f- K! f5 t3 U: d - //返回值:0,没有按下;1,有按下; //
0 l8 j) [! p5 `" l p+ `% h, g - #define TPAD_GATE_VAL 100 //触摸的门限值,也就是必须大于tpad_default_val+TPAD_GATE_VAL,才认为是有效触摸.//
% ]! Z* r6 C5 c3 P* l6 W: p - u8 TPAD_Scan(u8 mode)
, T L" [( p8 r5 b6 m - {
5 n3 E; L7 t( Q. m - static u8 keyen=0; //0,可以开始检测;>0,还不能开始检测//
o7 ?# P' Z8 B - u8 res=0; //res=0说明按键无效,res=1说明按键有效//' t( V% b+ m2 T0 i+ r; ]0 j$ u( d( I
- u8 sample=3; //默认采样次数为3次
; p- _/ `! S0 `: M - u16 rval; //5 h: E0 k! { b3 s( ?
- if(mode) //mode:0,不支持连续触发//
. t! R0 q8 X5 @" Z; p! K" M) k# a - {
9 V A2 X+ ~( Y9 o' @; V - sample=6; //支持连按的时候,设置采样次数为6次& p6 A$ h' @8 k' B4 x0 L ?3 F
- keyen=0; //支持连按 % `5 s$ O$ P& R' ?5 H' Q7 o
- } $ |) `8 O& r3 z/ N
- rval=TPAD_Get_MaxVal(sample); //连续采样三次,取最大值//( B9 |, q5 ?" X% o& ^
- if(rval>(tpad_default_val+TPAD_GATE_VAL)) //如果rval大于tpad_default_val+TPAD_GATE_VAL,则有效触摸//- j$ f; m4 h. O, Y9 l
- { 3 f4 Z& U o: i! v8 H
- if(keyen==0) //0,可以开始检测;>0,还不能开始检测// 9 w. v$ Q0 G. X! A0 S
- res=1; //当keyen==0,res至1,触摸有效//
) R5 u% H& m, k4 J0 g - printf("r:%d\r\n",rval); & V' M+ {0 s2 c# L
- keyen=3; //至少要再过3次之后才能按键有效// 2 [/ G( c8 g2 n7 m
- }
- ~4 y% c% A/ s' _ - if(keyen)keyen--; //keyen不等于0时,keyen减1// % ~+ `) f1 J% k, u0 r+ j
- return res; //res=0说明按键无效,res=1说明按键有效//. V* ?: s! G/ p a$ G
- } / v/ K z* x8 N4 A
- //*****函数六->定时器2通道2输入捕获配置-void TIM5_CH2_Cap_Init(u16 arr,u16 psc)*****//
: S5 v- S$ `+ H - void TIM5_CH2_Cap_Init(u16 arr,u16 psc)3 }/ h6 U( E% m+ U
- {
- j, V: L, B O' W+ Y4 M; y, { - //定义GPIO,TIM时基和TIM输入捕获三个初始化结构//8 B V- Y6 G# `" }9 Q" _& f
- GPIO_InitTypeDef GPIO_InitStructure;
( y# j! n5 A; r! d; J - TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;9 @4 s3 U0 h. W, j
- TIM_ICInitTypeDef TIM5_ICInitStructure;, r" z$ o% s( r9 d, k
- //使能TIM5时钟,使能GPIOA的端口时钟//" W& L! Z6 ?+ [. \" `6 g4 ^/ [- A
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE); 3 U+ G1 o$ A' T# J+ Y) M5 R" c
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); ; I, ^- A* @) m w+ S! w" n1 m
- //设置GPIOA.1为浮空输入,
5 s7 c4 B0 B0 k) E - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
# R6 V- d N$ C/ N - GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;
5 b% R" D+ M5 u - GPIO_Init(GPIOA, &GPIO_InitStructure); ) j& Z' t8 E6 V5 l* ^ t3 K
- //初始化TIM5时基//
) Y2 ?; M: x( w( ]8 j$ I$ a' H - TIM_TimeBaseStructure.TIM_Period = arr; //设定计数器自动重装值 1 }6 P8 u# x- Z' q
- TIM_TimeBaseStructure.TIM_Prescaler =psc; //预分频器
5 E) O: A3 j' { - TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim. c- a7 D8 ?) k/ h% Q) D
- TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式! E' R$ f" q" G z& L
- TIM_TimeBaseInit(TIM5, &TIM_TimeBaseStructure);
$ M# h' c; R* r; q8 T! j* P+ ^ - //初始化TIM5的捕获通道2//, l/ |3 G2 n/ y, R* K# }
- TIM5_ICInitStructure.TIM_Channel = TIM_Channel_2; //CC1S=01 选择输入端 IC2映射到TI5上
' f* g& ~4 Z$ h$ ?5 I - TIM5_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; //上升沿捕获/ k1 x7 j6 _7 Q6 @. x# o- g
- TIM5_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; 4 J1 x+ x* ~# A0 N, s
- TIM5_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; //配置输入分频,不分频
5 z5 }: O, B. M# ] - TIM5_ICInitStructure.TIM_ICFilter = 0x03; //IC2F=0011 配置输入滤波器 8个定时器时钟周期滤波
( w) ?, u. E. `+ p- T - TIM_ICInit(TIM5, &TIM5_ICInitStructure);* X) g7 g% Q8 e5 `) j( d
- //使能定时器5//& J3 i6 o) J- B7 E5 `
- TIM_Cmd(TIM5,ENABLE ); ) x# {# z) o" W
- }</i></i></i></i></i></i>
复制代码 , h2 a. ]9 H1 P$ n
5.3 main.c文件
. k0 ]; e# F! u! q, ]; _; w* U v7 g
3 o3 p$ l0 @/ m: s7 v) e/ v' M- #include "led.h"$ [- E" d: l F) g K0 s
- #include "delay.h"& G' O$ y6 n) I* a+ W! U# g
- #include "key.h"
1 ]+ K9 J5 Q2 K - #include "sys.h"
" H$ P C3 e" D$ X) o! O - #include "usart.h"
8 ?9 T! {, H H4 J - #include "tpad.h"
F; r8 m. W# W0 h5 }( D. ?* ^4 G - int main(void), d. {4 _* L8 }& r( j! r
- {
3 ]( ?4 E/ G8 |0 x% b. ?! j - u8 t=0;
4 m r! L, k$ m3 Z* J' \3 | - delay_init(); //延时函数初始化
8 J; f ]1 T8 @( t - NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置NVIC中断分组2:2位抢占优先级,2位响应优先级
! ~. S/ K( u' K" b - uart_init(115200); //串口初始化为1152003 c/ b i& _; P- R
- LED_Init(); //LED端口初始化 E J% p. R# N; J2 m" v+ G, P
- TPAD_Init(6); //初始化触摸按键# Q2 t" S- F3 W2 ^; ^' I
- while(1)
3 Y! c* H# g0 p - { 1 P2 V- `4 \$ V. o' c' I' L
- //TPAD_Scan(1)支持连续触发,TPAD_Scan(0)不支持连续触发//
+ N' o; T& J7 N" j - if(TPAD_Scan(1)) //如果成功捕获到了一次上升沿,if返回1% v$ }: z5 t3 g: O
- {
8 A! R v7 `# g/ M - LED1=!LED1; //LED1取反//
; F1 `9 v, M& n8 z3 U - }
% A2 T* n5 f& B! J* Y& }+ D6 p - t++;5 H, u. G" W' Q9 N5 q \
- if(t==15)
! t2 p- p' ]! u0 p' @ - {
1 ^: w8 U6 |- W8 r - t=0;7 m( J, o4 v, m. ?
- LED0=!LED0; //LED0取反,提示程序正在运行4 H! }. c% W, R& S
- }
3 k' f' E$ o7 `0 ^# E: X - delay_ms(10);$ l& P0 }* D+ D& b6 c$ }' c
- }* l" t' B1 ~4 z! E; {
- }
复制代码
# q! R$ s; }/ ^
0 D- J6 _) Y! x% d0 L& M————————————————
]# U" }! d) p- G版权声明:天亮继续睡/ _7 H6 F6 h, \+ F
1 |- D( O- e' H7 m( Z
& s$ t7 a) n" x+ \; H- ]
|