你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【零基础学习STM32】第二讲:GPIO输入实验——读取按键状态

[复制链接]
heart蓝色CD 发布时间:2018-1-27 13:11
接上篇:第一讲:GPIO输出实验——点亮三色LED6 }% u$ G0 g/ y0 w( E2 M# \1 p
- S+ ]5 e1 C  j6 g* P
一、概述
- @/ r% G, z) e1、按键简介
$ \& s# W& j; l9 I( b. P      按键是一种机械器件,按键两端分别对应某电路的两个断点,我们可以通过按键接通和断开控制该电路的电压等参数,我们利用按键做的应用通常有控制继电器、键盘、复位等。随着应用的扩展,按键已成为电路板上不可或缺的一部分。
# r( K5 n5 L. j: D9 O
如下图是常开按键:
2_0.png
2、按键类别简介
      按键主要有四种类型:常开带复位、常开不带复位、常闭带复位、常闭不带复位。(本次实验使用的是常开带复位按键)
按键主要有以下4种工作模式:
  • 常开带复位:初始默认状态是开路,当受力按下时按键使电路连通,受力结束后其自动返回开路状态。
  • 常开带不复位:初始默认状态是开路,每按下一次按键改变一次开闭状态。
  • 常闭带复位:初始默认状态是连通,当受力按下时按键使电路开路,受力结束后其自动返回连通状态。
  • 常闭不带复位:初始默认状态是连通,每按下一次按键改变一次开闭状态。
    ; z$ {7 b3 S! x! e
3、按键消抖
4 q; U: }6 K) j1 G5 g  {* ^# T4 u      使用手动按键的时候, 由于机械抖动可能造成按键的错误识别。一般手动按下按键然后释放, 按键两片金属膜接触的时间大约为50ms,按键松开到稳定的时间为5-10ms。因此,如果在首次检测到按键被按下后延时20ms 左右再次检测,即可确认是否真的有按键被按下,从而消除按键抖动造成的错误识别。本实验通过给于一定延时后再进行检测,从而有效的避免了按键抖动带来的误判。
6 t* F4 R' c, a$ t! l8 x7 D+ N+ X
二、硬件电路
: t3 x: A9 z% W: b( S8 q" f 2_1.png - N$ @8 D$ o# A. @  a+ ^2 K8 V6 H
2_2.png " B( i. b9 M( u+ I8 x
$ X. I4 A; u$ h3 A7 U
在iCore3双核心开发板中,采用一个独立的按键与STM32F407的PH15相连,限流电阻为1K。

8 C$ J+ r' F, r" `) s* V
三、实验原理
2_3.png
      按键的一端与STM32GPIOPH15)相连,另外一端接地,且PH15外接一个1K电流大小的上拉电阻。初始化时把PH15设置成输入模式,当按键弹起时,PH15由于上拉电阻的作用呈高电平(3.3V);当按键按下时,PH15直接被按键短接到GND,呈低电平。因此判断PH15的电平变化,可得到按键状态。
7 p$ Z% k4 `4 y. H$ U+ |0 O
四、源代码
1、主函数
  1. /*
    % {" R  c, m, A: I. D5 ^
  2. * Name                : main
    2 X) ^* s" |' T% r, }4 V
  3. * Description         : ---
    + s. u; {. s2 Y- Y1 k
  4. * Author              : ysloveivy.( u! o4 {; s/ Y9 O5 [
  5. *' _* {$ E/ k+ v7 u
  6. * History' k. \# J1 j$ H( R0 T+ v
  7. * --------------------: b0 Q. @) G4 O! I/ i
  8. * Rev                 : 0.00
    ; J9 t5 Q; D. q" X
  9. * Date                : 11/21/2015+ v1 R( f( ^6 e9 b7 W2 I5 Y
  10. *
    1 P8 c5 C9 J/ m7 h& {1 j) C
  11. * create.
    0 k! Z$ z( J) @2 m  A6 w0 s. ?1 B; T+ F
  12. * --------------------
    8 _6 q8 _2 T6 C' _
  13. */
    3 R; D( l* O$ W/ x9 T% z* q
  14. int main(void)7 z- _6 a2 Y; H( _. S  j
  15. {
    " r- A, ]/ S/ }; g* O% T! V2 t5 V
  16.         int i;
    ! F. ]6 {8 E. Q3 G0 x' b5 d3 p
  17.         static int work_status = 0;                         //三色LED灯工作状态
    ; I1 T$ u1 `, u& N- Q6 p. K
  18.         static int key_status = 1;                          //按键松开标置
    8 d4 x  W! U. [! R9 p# O9 u
  19.         led.initialize();                                   //三色LED灯端口初始化) Y( x% G$ ]3 E, a
  20.         key.initialize();     
    + [4 @- o2 i6 P; [) U7 ]/ h' M
  21.         while(1){- H1 S' c3 ]" U$ U  n% ]# ~
  22.                 if(KEY_INPUT)key_status = 1;1 g; D! |! S; \
  23.                 if(key_status == 1){
    . H; D1 F8 ]1 B
  24.                         if(!KEY_INPUT){
    3 h! P: e: V1 G0 L1 s5 Q; r4 G
  25.                                 for(i = 0;i < 10000;i++);     //按键防抖动
    9 V% T6 }: A/ |7 K
  26.                                 if(!KEY_INPUT){8 ?) d3 u1 M1 l3 j
  27.                                         key_status = 0;
    ; Z/ a4 s5 {$ F( ^3 y
  28.                                         work_status += 1;: k9 c4 r% D" q9 f, G; `) n  h
  29.                                         if(work_status > 2)work_status = 0;
    " `6 w+ s5 n; R; f( [5 X5 N) f
  30.                                         //操作 LED
    & N! X! e) D8 X
  31.                                         switch(work_status){
    3 `( r$ i* g/ p" y; L- e% {
  32.                                                 case 0:# k% X# I- R! S) ]* j; m
  33.                                                         LED_RED_ON;- L4 U. L& Q: w  E
  34.                                                         LED_GREEN_OFF;
    & c. G2 s, l4 l+ U* y( V2 @
  35.                                                         LED_BLUE_OFF;
    5 o8 @- F7 c  e9 F! h4 l( j: n% N
  36.                                                         break;/ |2 u7 c1 a$ b! _& \6 b7 Z
  37.                                                 case 1:
    6 H7 p2 s+ N. z- w* {9 Q( R
  38.                                                         LED_RED_OFF;
    2 W0 i! x( r: a
  39.                                                         LED_GREEN_ON;
      w$ s7 Z+ ~* R, s) K$ U
  40.                                                         LED_BLUE_OFF;' G' e- A0 P6 c1 r& [3 |
  41.                                                         break;
    ; M# s, F  |" l0 {
  42.                                                 case 2:+ I2 I; K0 ^: U0 F
  43.                                                         LED_RED_OFF;9 W4 t9 }& ~/ ]2 s! r' n3 J
  44.                                                         LED_GREEN_OFF;
    5 ]' }, R6 j5 o) M2 Q# ?+ [
  45.                                                         LED_BLUE_ON;
    / ]4 d% d- N7 S: M4 @
  46.                                                         break;
    ; ^; N6 J* `+ X4 H$ a
  47.                                                 default:
    " w% f* f' A$ w9 z$ T' o/ |/ |
  48. ( j9 k: j2 E1 H
  49.                                                         break;
    . U7 ?; R/ r$ `% Z; M
  50.                                         }. c" N8 M$ u. M9 i) R
  51. 8 h' \: X4 ?# h9 p( r+ i& V
  52.                                 }
    . x! o4 }" c. q$ F2 L, r
  53.                         }
    " k3 J( u# P2 }. k* o: X
  54.                 }
    & v/ s& t. j0 n' @
  55.         }7 K$ ~" G8 B9 s6 h
  56. }
    # t3 ^* U" M* ?1 L( K) \; U
复制代码
2、GPIO初始化
LED的GPIO初始化配置方式与上一讲一致,以下是按键的GPIO初始化程序
  1. /*
    * z# k0 O1 h+ A6 i' w  \- c2 }5 r
  2. * Name                : initialize
    , h6 r1 f: x3 L( s
  3. * Description         : ---. a+ E: m, n3 h" N! `1 K
  4. * Author              : ysloveivy.
    ) ^7 T# [) d! v% C7 S
  5. *3 O5 l/ m7 e6 U6 t! r( H! z2 q
  6. * History
    8 |  g8 S, L! C/ n$ N# W7 ^: P
  7. * --------------------7 W( C* L, b! X+ M4 u* R7 c
  8. * Rev                 : 0.00: |( L- H9 v- B) G% L* X$ ~
  9. * Date                : 11/21/2015
    1 z5 B' l" r3 X$ K9 b7 r
  10. * 5 p; g6 j* A5 a' K5 e
  11. * create.
    + F' r# x' M" Q, i7 T+ y
  12. * --------------------
    " B1 d- K5 F. d4 O. H3 ^
  13. */& T; W. ~" m' U6 H" @8 `" Y
  14. static int initialize(void)
    ' w; O9 ]1 I& ~& m( D
  15. {
    , H/ {9 v7 t! k. ?/ R' o/ r
  16.         GPIO_InitTypeDef   GPIO_uInitStructure;
    & W4 S- D  T' ?

  17. 0 T( @: [0 |  [
  18.         RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOH,ENABLE);# i2 @8 S) M! L3 ]" L, j5 U
  19.         //设置连接按键的IO端口
    7 J/ T  W/ J5 t) s; O- Z
  20.         GPIO_uInitStructure.GPIO_Pin = GPIO_Pin_15;                           
    0 F7 s5 E9 S& d. g4 L* m7 a
  21.         //设置端口为输入模式0 J% F% o  _% m
  22.         GPIO_uInitStructure.GPIO_Mode = GPIO_Mode_IN;                          
    " A6 _, \, B# V. G5 G
  23.         //设置速度为第三级& W  S& x& z3 D: V2 k: L" D& |' I$ d, h
  24.         GPIO_uInitStructure.GPIO_Speed = GPIO_Speed_100MHz;                    . a4 O% S+ K) ^0 }" B" y4 }: R, ~
  25.         //设置输入端口不变化
    / g5 ^! o- t5 p) K% Z
  26.         GPIO_uInitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;                      8 Z- v3 l3 C# t
  27.         //把设置的参数用到结构体; z6 b( Y7 V; D5 q( ~4 `+ i' q
  28.         GPIO_Init(GPIOH, &GPIO_uInitStructure);                                  C" W1 }) m0 w9 s3 v0 i- F

  29. $ E3 C3 H9 w8 o, I/ i% Y6 t
  30.         return 0;6 e* l1 \/ o8 Y  w: f
  31. }
    , H+ K0 S7 l  }) O" Q+ w7 T& j
复制代码
3、小知识
void RCC_AHB1PeriphClockCmd
(uint32_t RCC_AHB1Periph,FunctionalState NewState)
此函数为外设使能函数,第一个参数为需要被使能的外设,第二个参数为使能与否。可能很多读者看到这函数不知道如何入手,不知道参数填啥子好,别急,咱先查看一下他的定义:

图2_4

图2_4

% n* {+ ?$ L$ Y4 T2 ^4 q
查看定义方法:双击函数名选中,右击再点GO TODefinition of ...就可以查看咯。
RCC_AHB1PeriphClockCmd函数定义如下:
  1. void RCC_AHB1PeriphClockCmd(uint32_t RCC_AHB1Periph, FunctionalState NewState)6 g% |2 |$ H; _5 a' E, L6 r9 g
  2. {
    - A; d- ]- i6 q1 l
  3.   /* Check the parameters */
    7 l) P" }3 y3 u$ V1 f! ?
  4.   assert_param(IS_RCC_AHB1_CLOCK_PERIPH(RCC_AHB1Periph));4 v- V0 }3 D( s/ t  ]7 M0 ]9 W2 J
  5.   assert_param(IS_FUNCTIONAL_STATE(NewState));% |- M1 p8 V: U
  6.   if (NewState != DISABLE); u, k9 v  I7 _  z
  7.   {! B3 E0 f5 x* w3 I
  8.     RCC->AHB1ENR |= RCC_AHB1Periph;
    * E$ n, S7 ~$ P7 E
  9.   }0 v  _  p3 p" u* O# l9 y
  10.   else9 ~3 w; p9 p6 d
  11.   {
    & p5 x% b. o  B& z% A9 j3 v9 _! x
  12.     RCC->AHB1ENR &= ~RCC_AHB1Periph;6 `. j+ ^/ _0 m7 r% Q5 A. H
  13.   }
    & @0 R" v7 i* n! y- x' i0 p; R
  14. }
    : e" S) i' ~/ t% _; y2 ^. p
复制代码

. x. ]: G4 G0 A. `' z
注意被我标红的字符串,按照刚刚查定义的方法,它会告诉我们函数的参数可以填啥。如查看IS_FUNCTIONAL_STATE:
  1. #define IS_FUNCTIONAL_STATE(STATE) 6 l2 ]; E- }0 i
  2. (((STATE) == DISABLE) || ((STATE) == ENABLE))* y. {. D( @" K+ j9 ]7 J
复制代码
我们可以看出第二个参数可填写DISABLE(使能)和ENABLE(不使能)。
9 H  Q2 h6 M0 h/ u/ \7 x( m
小结:上面用外设的使能函数为大家介绍了查看函数的方法,此方法在实际应用经常可以用到,当我们在阅读、修改程序的时候,遇到哪些不太清楚的函数,就可以用这种方法查看。
+ ?2 y- N7 g' Q! G5 Q
五、实验现象
按键每按下一次,ARM·LED颜色变换(红色、绿色、蓝色轮流交换)一次。

6 _: y& m7 _9 Q
六、代码包下载
复制网址到浏览器可下载pan.baidu.com/s/1sjrHnM9
/ e7 k/ g- e' m) r# _; }* a
8 q5 B9 D/ M# O# j# Q

1 ^1 P4 k& }& h5 M( I! h# i3 O, E8 G2 `2 D3 i( c3 y
2 w* E$ u5 N% `! O7 O

评分

参与人数 1 ST金币 +2 收起 理由
MrJiu + 2 赞一个!

查看全部评分

收藏 评论4 发布时间:2018-1-27 13:11

举报

4个回答
Inc_brza 回答时间:2018-1-27 15:06:38
顶CD哥
努力的人 回答时间:2018-1-28 16:27:22
这个写的很详细,应该画了很多心思弄的,按键应该属于GPIO输入吧,你看看题目是不是改下
zero99 回答时间:2018-2-1 09:25:00
感谢支持,已汇总到1月技术原创! B8 j% g. p. S4 j- N7 o" ]
https://www.stmcu.org.cn/module/forum/thread-614550-1-1.html
heart蓝色CD 回答时间:2018-2-2 14:10:29
zero99 发表于 2018-2-1 09:25
" S' u; {0 e/ h3 \4 }: _感谢支持,已汇总到1月技术原创
6 n7 [5 H$ |5 l" S* y0 ~) rhttps://www.stmcu.org.cn/module/forum/thread-614550-1-1.html ...
! _) O& S! ~; u$ t" P4 p/ |
感谢

所属标签

相似分享

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版