接上篇:第一讲:GPIO输出实验——点亮三色LED0 u: [5 i+ N! v. E" o
; V* b @: [1 J0 l
一、概述
* D: R d: k0 c! G% Y1、按键简介+ j8 c" E' e0 r) _0 V! K5 Z) B
按键是一种机械器件,按键两端分别对应某电路的两个断点,我们可以通过按键接通和断开控制该电路的电压等参数,我们利用按键做的应用通常有控制继电器、键盘、复位等。随着应用的扩展,按键已成为电路板上不可或缺的一部分。
: r9 o8 D) x& I5 }" |如下图是常开按键: 2、按键类别简介 按键主要有四种类型:常开带复位、常开不带复位、常闭带复位、常闭不带复位。(本次实验使用的是常开带复位按键) 按键主要有以下4种工作模式: - 常开带复位:初始默认状态是开路,当受力按下时按键使电路连通,受力结束后其自动返回开路状态。
- 常开带不复位:初始默认状态是开路,每按下一次按键改变一次开闭状态。
- 常闭带复位:初始默认状态是连通,当受力按下时按键使电路开路,受力结束后其自动返回连通状态。
- 常闭不带复位:初始默认状态是连通,每按下一次按键改变一次开闭状态。1 e: i& c, |8 H! q; D
3、按键消抖
' y c7 ~. |" m7 _+ C 使用手动按键的时候, 由于机械抖动可能造成按键的错误识别。一般手动按下按键然后释放, 按键两片金属膜接触的时间大约为50ms,按键松开到稳定的时间为5-10ms。因此,如果在首次检测到按键被按下后延时20ms 左右再次检测,即可确认是否真的有按键被按下,从而消除按键抖动造成的错误识别。本实验通过给于一定延时后再进行检测,从而有效的避免了按键抖动带来的误判。
) {$ M3 V5 ]% q
4 h& V. D( k7 `. D4 j1 @, q二、硬件电路$ {) {0 O( L; o& m6 @
; g6 F4 J( ]% N0 L0 Y
6 P3 B! z9 H1 ^& w
) S5 y+ d) E# ?- d6 O9 y在iCore3双核心开发板中,采用一个独立的按键与STM32F407的PH15相连,限流电阻为1K。 & Z& T: B/ E5 X- ?
三、实验原理 按键的一端与STM32的GPIO(PH15)相连,另外一端接地,且PH15外接一个1K电流大小的上拉电阻。初始化时把PH15设置成输入模式,当按键弹起时,PH15由于上拉电阻的作用呈高电平(3.3V);当按键按下时,PH15直接被按键短接到GND,呈低电平。因此判断PH15的电平变化,可得到按键状态。 3 K- W( g3 X1 C) M" y: T
四、源代码 1、主函数 - /*
* I$ n6 l- u% w. u5 x3 N - * Name : main
8 N8 x+ |0 g$ r; E: x9 ~( L- D9 G - * Description : ---
0 D! S x/ z! r2 h - * Author : ysloveivy.
u; H, V- [+ J8 k5 U/ j3 c# e - *
8 X2 N* V& A$ k( N( d - * History
4 C5 f3 b! H6 K3 m- u! g - * --------------------1 j8 v$ Y& K. F' H
- * Rev : 0.007 F' M6 t: a/ Y0 h1 q4 \& a
- * Date : 11/21/2015
/ n+ R& c4 u: F* l: z+ C6 \ - * 4 I5 z0 w6 Q# G J8 g3 Z
- * create.
! F! B# t3 J4 ]. j; q. Z2 C - * --------------------
( h/ }- V8 L4 B2 S* u h - */9 F8 o' k, D$ p( B% I# A* v
- int main(void); W" |- O! `- r: N
- {
! I5 R$ l; G6 F* H" g3 ~0 D. q - int i;6 Z, s; m8 R9 D9 n( e* p
- static int work_status = 0; //三色LED灯工作状态4 V% W, |( t& k# O* s5 t. D! `
- static int key_status = 1; //按键松开标置
* q) h1 V# M: N9 C5 q - led.initialize(); //三色LED灯端口初始化) j# L) P# v; T& p7 n
- key.initialize();
/ D4 n! h# e% L2 v - while(1){' t# K7 q+ @0 V
- if(KEY_INPUT)key_status = 1;$ k, {& G9 V/ Y" q9 \2 Y
- if(key_status == 1){
. n& A# Y6 A, y" L: \" J - if(!KEY_INPUT){" O W5 J ?: B+ _8 s
- for(i = 0;i < 10000;i++); //按键防抖动. E5 t V# ~ c1 `, e; F
- if(!KEY_INPUT){# c1 v5 e: v) Z/ o. @7 k
- key_status = 0;
7 b3 z- b2 ~6 B( s& g8 E) Q9 c+ C) S - work_status += 1;6 t7 z$ s- y) h8 N0 ~' U) ~
- if(work_status > 2)work_status = 0;
/ v, U+ Q, o, W( {( b$ p! V" g - //操作 LED
( K1 ?1 n+ c+ z+ H2 { - switch(work_status){
5 |+ G$ E( O d8 X- J - case 0:+ L% b2 j5 f0 C& H+ T7 o% H
- LED_RED_ON;
0 j% [9 |( U! p0 K - LED_GREEN_OFF;
3 w! @$ N M2 _+ R$ J; k, N - LED_BLUE_OFF;
& y6 H/ `& Q+ w5 Y/ }( x5 n - break;
& Y2 ^# y- ?( H6 V# z$ \) c/ Y - case 1:: L8 N e4 h0 {8 u
- LED_RED_OFF;- e8 | a. P2 ~; ?
- LED_GREEN_ON;: g S) N! R6 z, ~
- LED_BLUE_OFF;3 |( e( r$ k- d( e
- break;
2 `& p; r( b. i2 ]3 V; B - case 2:; m8 N1 w5 C) H; c6 O( |% h
- LED_RED_OFF;
9 |# i1 ~% K- W1 l# A8 o- n, d; Z - LED_GREEN_OFF;
4 i7 q) l9 C$ s. ]2 @2 { - LED_BLUE_ON;7 o5 [- Y( F: E7 ~
- break;, Q3 e; _' j! D; l. l( |
- default:
0 c7 ^# i) D3 C, m( K6 T# y- l - ! ?/ c9 @1 }' `% e* D: G
- break;
- t5 K5 c% Q6 n - }
" ^* W/ ?. `1 ?5 G/ A9 m - 1 L! _* v) W7 Q$ U9 @
- }
* p3 Q0 p7 z: h+ G - }
) @8 }6 W6 t% E2 D8 Y6 n' D, W/ q - }
* ]3 `( J: m/ K4 W) U4 r6 X - }" E' v! w4 y2 {. I* c: d+ r
- }
0 n3 K) Y! O1 T l4 q0 u! L
复制代码 2、GPIO初始化LED的GPIO初始化配置方式与上一讲一致,以下是按键的GPIO初始化程序 - /*( g& j- V! z; }
- * Name : initialize' F" s3 Z/ r& w0 w$ l$ q9 R
- * Description : ---
" \, w0 q9 y1 { - * Author : ysloveivy.
; E T9 G) a3 C4 O3 K5 E - *! w j: ^# a ?5 Z
- * History9 T( x; `5 a- g( Q# r: J# U8 b2 }
- * --------------------
9 \+ l7 H% Q: A2 q. V% { - * Rev : 0.00
" B0 Y+ q3 }; o9 n - * Date : 11/21/2015" f* ~% I* F% j5 a' ^ C
- *
' k6 v( j# l$ t+ e; r' v) q( T+ ?& a - * create.3 E; A$ w4 _3 |: ?4 q
- * --------------------" j+ G) A2 G. e5 N
- */& ^) R7 c- f/ }" E B- b
- static int initialize(void)+ Z! D. \5 ~9 V: v% N5 G2 @
- {
2 r+ c$ A" {/ L4 o - GPIO_InitTypeDef GPIO_uInitStructure;
) ?; B: Q0 H7 l( g
! m5 U: Z8 c% X9 R- RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOH,ENABLE);8 w& R' `! ~$ S( u4 O5 ? c; _/ D
- //设置连接按键的IO端口6 j3 ?6 l! y# }
- GPIO_uInitStructure.GPIO_Pin = GPIO_Pin_15; ' d& H; t, [: U4 i0 q0 ~1 W8 U
- //设置端口为输入模式( ?% p& Q0 ~* b$ M" X) X8 C4 Q
- GPIO_uInitStructure.GPIO_Mode = GPIO_Mode_IN; ; J! b- G1 F! [5 C
- //设置速度为第三级
0 Y3 }! X0 N- z5 [& T9 y/ K& u, e - GPIO_uInitStructure.GPIO_Speed = GPIO_Speed_100MHz; ) K' |5 I: k- [7 y& t
- //设置输入端口不变化
9 J' f/ A9 z0 U$ A - GPIO_uInitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
: e o/ }2 b" Y - //把设置的参数用到结构体
1 q3 X6 Q( W" h( i. t! o# N; a* C - GPIO_Init(GPIOH, &GPIO_uInitStructure); " U/ ]# R1 M M! Z& j6 b: d
- ; r; P' A9 `6 h; G$ b7 @3 G
- return 0;
8 Z: O, [3 n4 x - }" ?/ u! J$ P3 |- Z5 s% ^
复制代码3、小知识 void RCC_AHB1PeriphClockCmd (uint32_t RCC_AHB1Periph,FunctionalState NewState) 此函数为外设使能函数,第一个参数为需要被使能的外设,第二个参数为使能与否。可能很多读者看到这函数不知道如何入手,不知道参数填啥子好,别急,咱先查看一下他的定义:
å¾2_4
7 V" g) A' }/ \8 z% x
查看定义方法:双击函数名选中,右击再点GO TODefinition of ...就可以查看咯。 RCC_AHB1PeriphClockCmd函数定义如下: - void RCC_AHB1PeriphClockCmd(uint32_t RCC_AHB1Periph, FunctionalState NewState)
8 |6 S% @, V6 o: x, Z - {
y: h+ B( m A H. j - /* Check the parameters */8 Y% X; }$ M! N4 o$ v' W
- assert_param(IS_RCC_AHB1_CLOCK_PERIPH(RCC_AHB1Periph));
. [) a$ K: n0 N( _, o | - assert_param(IS_FUNCTIONAL_STATE(NewState));- x$ D! q; b' }& N1 G" Z: @$ l: R; N
- if (NewState != DISABLE)
N% q1 v1 U' ^& p+ |. N( O+ @. ^ - {
0 S, t! A4 `' g. y - RCC->AHB1ENR |= RCC_AHB1Periph;
4 Y6 t8 s/ {3 T - } X8 c9 i, ^' P* D6 e1 o3 O9 l2 |& @
- else
& T$ I; `8 @ n - {$ W: I5 ^; |" ]7 T& Q1 E, m
- RCC->AHB1ENR &= ~RCC_AHB1Periph;
7 W% W) G X: D7 {& C - }; w7 ^7 Q; R8 C/ R( O' E9 c0 `
- }
: {% e8 U* l9 ]+ U! `
复制代码
9 z; V! w7 U! Q( P: R( F4 t6 X注意被我标红的字符串,按照刚刚查定义的方法,它会告诉我们函数的参数可以填啥。如查看IS_FUNCTIONAL_STATE: - #define IS_FUNCTIONAL_STATE(STATE)
6 c* e' }: Z1 H6 C7 h9 O: O - (((STATE) == DISABLE) || ((STATE) == ENABLE))
: h, P3 @, |5 S6 V
复制代码我们可以看出第二个参数可填写DISABLE(使能)和ENABLE(不使能)。 & w8 d' S/ _4 j2 }4 [
小结:上面用外设的使能函数为大家介绍了查看函数的方法,此方法在实际应用经常可以用到,当我们在阅读、修改程序的时候,遇到哪些不太清楚的函数,就可以用这种方法查看。 9 H5 K+ i# z& H1 S. s& a, K0 r2 r( G
五、实验现象 按键每按下一次,ARM·LED颜色变换(红色、绿色、蓝色轮流交换)一次。 ! b( M0 {" p O$ W. z. [( ^6 ^# I- [, C
六、代码包下载 复制网址到浏览器可下载pan.baidu.com/s/1sjrHnM9 ! l( W9 b% K9 s' F t0 k' H
5 w8 h0 s/ v1 J9 }5 |
8 P/ ?; ]. `* A8 r9 ~% h( N% J( O0 [( g
) M6 W% V+ o' E7 ~, T |
https://www.stmcu.org.cn/module/forum/thread-614550-1-1.html
感谢