接上篇:第一讲:GPIO输出实验——点亮三色LED
" O( F- S" U- [4 c: p* `
# V/ O1 Q. V$ _' ?# [, T一、概述
$ ~7 D( R x' X' q0 W i0 L1、按键简介
7 Z3 |; V! {& I+ V3 D" [ 按键是一种机械器件,按键两端分别对应某电路的两个断点,我们可以通过按键接通和断开控制该电路的电压等参数,我们利用按键做的应用通常有控制继电器、键盘、复位等。随着应用的扩展,按键已成为电路板上不可或缺的一部分。% q: ?, Z9 G; K7 d4 p
如下图是常开按键: 2、按键类别简介 按键主要有四种类型:常开带复位、常开不带复位、常闭带复位、常闭不带复位。(本次实验使用的是常开带复位按键) 按键主要有以下4种工作模式: - 常开带复位:初始默认状态是开路,当受力按下时按键使电路连通,受力结束后其自动返回开路状态。
- 常开带不复位:初始默认状态是开路,每按下一次按键改变一次开闭状态。
- 常闭带复位:初始默认状态是连通,当受力按下时按键使电路开路,受力结束后其自动返回连通状态。
- 常闭不带复位:初始默认状态是连通,每按下一次按键改变一次开闭状态。
* W6 I* X, p# z; T) G# O. D 3、按键消抖
1 [! |& x/ O8 o 使用手动按键的时候, 由于机械抖动可能造成按键的错误识别。一般手动按下按键然后释放, 按键两片金属膜接触的时间大约为50ms,按键松开到稳定的时间为5-10ms。因此,如果在首次检测到按键被按下后延时20ms 左右再次检测,即可确认是否真的有按键被按下,从而消除按键抖动造成的错误识别。本实验通过给于一定延时后再进行检测,从而有效的避免了按键抖动带来的误判。
3 u# l. M4 Y, F' }
+ ~9 I, [8 B" d* m! t( z二、硬件电路" C% C! L0 J1 d# c
" S8 h# _. ] ]) Q7 ~# E
1 C2 @# F" J, h
% R, u" s: U6 s$ X1 N' O
在iCore3双核心开发板中,采用一个独立的按键与STM32F407的PH15相连,限流电阻为1K。
4 _* z. w: a. o4 A: L) \
三、实验原理 按键的一端与STM32的GPIO(PH15)相连,另外一端接地,且PH15外接一个1K电流大小的上拉电阻。初始化时把PH15设置成输入模式,当按键弹起时,PH15由于上拉电阻的作用呈高电平(3.3V);当按键按下时,PH15直接被按键短接到GND,呈低电平。因此判断PH15的电平变化,可得到按键状态。
/ T$ A$ p- L$ _/ n+ y5 S9 `
四、源代码 1、主函数 - /*
s v( r1 ?( n3 p - * Name : main6 \# m+ ]# W0 z- u1 [) C, T
- * Description : ---
, H/ `4 ^+ G+ a% A; r - * Author : ysloveivy.
8 @. W' n8 `" ]/ B - *
# `. w V; o0 M! N" c* g - * History" w8 j2 z9 x( P s9 b/ i" `
- * --------------------
) v" E" F" E. a' y% D# @ - * Rev : 0.006 X3 G C# ]& n4 K! g+ o7 A
- * Date : 11/21/20157 K! `% v/ D1 n: x
- *
5 a1 G2 {' k$ ?" s* { - * create.
5 Q/ S0 v1 F/ e* } - * --------------------
1 x( f% u6 C( L7 \: c - */1 {5 U3 }7 T6 F! Y; D1 i b
- int main(void). s/ H- K8 u1 l) u
- {
) |' A0 o6 K) A- l' d2 n- k - int i;+ B* o1 ]4 O' b" }
- static int work_status = 0; //三色LED灯工作状态
& c0 ?9 |; V! s) t - static int key_status = 1; //按键松开标置
; l% G* M! O' D1 O' d2 [% n! y - led.initialize(); //三色LED灯端口初始化3 `/ t( j4 y3 Y1 g8 w
- key.initialize(); }8 Q% V6 l* ?. |9 t* S% A4 H
- while(1){5 B8 b4 ~' }) |6 T
- if(KEY_INPUT)key_status = 1;
# X/ c I) P7 c! Q3 |) k# W5 c S - if(key_status == 1){: c1 s' S( i) _* l5 w6 P
- if(!KEY_INPUT){$ M2 k, n7 h* n8 A9 L
- for(i = 0;i < 10000;i++); //按键防抖动
# P* Q7 Y" N. x* c - if(!KEY_INPUT){1 _+ M4 H$ b* K7 b
- key_status = 0;4 L, ?% J% C4 D5 f
- work_status += 1;$ M6 x) C! D4 p+ U
- if(work_status > 2)work_status = 0;8 B: q q+ r; r; o* Y3 E0 b
- //操作 LED4 ?0 Q5 e+ r) o/ A
- switch(work_status){' m) X9 L/ c+ k `7 i6 s' D
- case 0:
" ~: H3 g, P* V5 S( |2 k% _ - LED_RED_ON;
) n! O" }% i. N/ x3 A - LED_GREEN_OFF;; z4 A0 b7 B' |8 J, |4 |9 v3 G
- LED_BLUE_OFF;; x8 t+ ?; I. Q% V
- break;% y3 p0 E3 o b
- case 1: {9 v/ \: S% o+ m; \9 V
- LED_RED_OFF;* ? \# F, ^" ?. q$ N3 T0 J% A' v
- LED_GREEN_ON;
- W+ m0 J& W. d8 y6 b' k( i3 T - LED_BLUE_OFF;
$ [ l Q' X; w - break;
" p ?" t- F/ o - case 2:
0 |) w9 n' a0 q) n0 f7 R1 H - LED_RED_OFF;
6 Z# V% |& p( Y/ C2 m; G: m - LED_GREEN_OFF;" q$ U# n# P o9 i1 ]
- LED_BLUE_ON;6 i' M9 o3 ?# i' |9 \4 J/ @" _; x# K
- break;: R }5 ]0 d& Z5 C2 y3 L
- default:
' ~/ Z0 a7 e# F# T# R0 P# }. F - * U$ @, V- Q+ E) {4 x) y/ i
- break;! u9 W8 \, Q5 u- i
- }; u, m% o& P1 J; t. d
- ) M6 I; r2 r9 d' y0 j9 D
- }1 W6 j; t* \9 v; b: y
- }
6 K& Y; y/ I8 Z4 U - }2 h3 `: K( ~* f; D' C
- }% I; E7 O* U$ ]3 \$ f" {5 m
- }
% f% l4 m$ _, g" j$ X. `7 B
复制代码 2、GPIO初始化LED的GPIO初始化配置方式与上一讲一致,以下是按键的GPIO初始化程序 - /*% h3 b8 h; e- S/ C& l7 Q1 Z
- * Name : initialize) p* x# C @( f( q$ F+ m8 v: e4 o1 K' O
- * Description : --- H; W/ i) _/ F* |' Q
- * Author : ysloveivy.4 @6 x$ O+ B; {+ w
- *
* S- v8 V8 |1 T - * History$ F; Q! d+ a' ]8 B
- * --------------------- g9 Q, \2 ]9 Q4 J9 g( g. }
- * Rev : 0.00 m6 X: ?( G( q& r# E$ w
- * Date : 11/21/2015
7 X. t4 y: F$ C. i - * $ N# |8 p! p, a" o" d
- * create./ |. {& q) L, C3 n( g
- * --------------------
: ^3 ], t7 p6 L& z( B# X9 o6 ] - */$ I- h9 A: t d# o
- static int initialize(void)
. M! t0 h8 T# P& n% e( K - {8 R1 g1 s3 h. V3 ^& t
- GPIO_InitTypeDef GPIO_uInitStructure;
) k/ S7 b! F$ z# } i - , r( y9 v' t' e% w# D* D0 y
- RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOH,ENABLE);: D- L( l, ]+ [/ ~
- //设置连接按键的IO端口
7 ]2 m9 v6 Q- l! Y7 J( R6 }( O - GPIO_uInitStructure.GPIO_Pin = GPIO_Pin_15; w& {- {$ r5 O7 A
- //设置端口为输入模式
0 a4 T6 K3 l" q0 m' E$ u - GPIO_uInitStructure.GPIO_Mode = GPIO_Mode_IN; ! D6 P9 W' v9 v! D( L0 o
- //设置速度为第三级
/ w/ g( [ E6 P4 D/ s% T. C. z - GPIO_uInitStructure.GPIO_Speed = GPIO_Speed_100MHz; - e; A4 b; `/ {5 A# J4 l
- //设置输入端口不变化
8 Z' {; B9 m3 O& C - GPIO_uInitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
9 t* @- m+ A+ a - //把设置的参数用到结构体& i1 g, G9 v$ q4 A
- GPIO_Init(GPIOH, &GPIO_uInitStructure); * { q0 s- X/ i2 k2 l r; o4 ?
- . z* Y( ~4 |) ` h
- return 0;
# V$ p1 }( U- @ - }
- p( [- L. n) K2 l+ N
复制代码3、小知识 void RCC_AHB1PeriphClockCmd (uint32_t RCC_AHB1Periph,FunctionalState NewState) 此函数为外设使能函数,第一个参数为需要被使能的外设,第二个参数为使能与否。可能很多读者看到这函数不知道如何入手,不知道参数填啥子好,别急,咱先查看一下他的定义:
å¾2_4
1 ~: T; O: @- ?5 }
查看定义方法:双击函数名选中,右击再点GO TODefinition of ...就可以查看咯。 RCC_AHB1PeriphClockCmd函数定义如下: - void RCC_AHB1PeriphClockCmd(uint32_t RCC_AHB1Periph, FunctionalState NewState)
/ H9 V9 g5 _2 j# F$ \( Y. i0 E% b/ L - {
" q: _( H. {% J, c - /* Check the parameters */
2 p8 s* D; z* o - assert_param(IS_RCC_AHB1_CLOCK_PERIPH(RCC_AHB1Periph));
! [/ b% b3 h. K/ ?4 N/ G - assert_param(IS_FUNCTIONAL_STATE(NewState));! I' p* o: b% a; d r2 B# _
- if (NewState != DISABLE)! X |/ W9 X$ q1 ?1 ^" g: n5 J3 x r
- {# `5 ?5 }8 b. }' Y* |% R7 Q! A$ N# _
- RCC->AHB1ENR |= RCC_AHB1Periph;, V* J8 L# L4 Q# A) t3 V8 y
- }. [7 | S ~! t& z: K* |% I; r% n
- else
. C6 t) k" \5 M9 R4 |: ^ - {0 ?) [% |+ Z2 V% l, {
- RCC->AHB1ENR &= ~RCC_AHB1Periph;
0 J- @, \7 |+ v% n - }
1 O2 u5 Y' ~6 n) ~, R - }
2 D7 m7 |/ T3 X7 S3 _& q2 V% i: Z
复制代码
7 z8 B9 ?7 h4 n6 S+ V8 [3 ]* h2 o注意被我标红的字符串,按照刚刚查定义的方法,它会告诉我们函数的参数可以填啥。如查看IS_FUNCTIONAL_STATE: - #define IS_FUNCTIONAL_STATE(STATE)
4 t+ m- z7 a1 v - (((STATE) == DISABLE) || ((STATE) == ENABLE))
" Z) H* g3 V: M2 c9 k8 f% G
复制代码我们可以看出第二个参数可填写DISABLE(使能)和ENABLE(不使能)。
' _# t' w5 S7 O4 }) e0 R# E小结:上面用外设的使能函数为大家介绍了查看函数的方法,此方法在实际应用经常可以用到,当我们在阅读、修改程序的时候,遇到哪些不太清楚的函数,就可以用这种方法查看。
, m5 d( Q' H: @
五、实验现象 按键每按下一次,ARM·LED颜色变换(红色、绿色、蓝色轮流交换)一次。
/ g6 c/ O" D7 s
六、代码包下载 复制网址到浏览器可下载pan.baidu.com/s/1sjrHnM9
7 Y9 B! z; {8 {* {4 L! v2 U& @8 O% \9 l! ?
, g, [, S8 M- x' Q
$ _+ W2 ]$ v) r3 o
7 F3 E$ O. p1 }6 ^ |
https://www.stmcu.org.cn/module/forum/thread-614550-1-1.html
感谢