|
第二章:STM32CubeMxGPIO基本使用方法 第一点:生成一个工程后,需要注意事项: 在STM32CubeMx软件本身生成的源文件中;用户的代码只可以写在以下区域,自己建立的源码文件不受影响: - //写在前面或后面在下次从STM32CubeMx 生成工程时会被清空掉!/ H v% f4 s" j
- //包含库文件,所以尽量不要试图尝试修改库文件来达到功能需求!
" g8 U% K! N5 b/ S$ [; L0 \' }' C& } - USER CODE BEGIN0 g5 x% I+ I0 a7 S+ R7 N
- 1 b" V' x7 l# p% M) {4 g2 a ]
- //只有这写在有编辑权限的代码区域中编写代码,才不会被清空掉,这里要注意一下!6 S& X/ u6 m. \, s' l# w* x# s
- 用户可编写的代码区0 X% }5 x. o% d8 z; {+ T2 p4 X1 R' m; c
- * P" }, f" k) B0 B3 H% K
- USER CODE END
复制代码- /* Private includes ----------------------------------------------------------*/+ |8 N$ z& v4 R- l6 |
- /* USER CODE BEGIN Includes */! h( J- p! T% ], _" W' I7 r
- 用户可编写的代码区8 b. s+ m* R8 ^. \' B7 c
- /* USER CODE END Includes */
: {3 s& y1 m" q2 I3 _5 } o - ) s' F8 k- D) ?8 u0 M& `/ n& Z- _
- /* Private typedef -----------------------------------------------------------*// k8 |; a2 B+ D; t, z4 d7 L
- /* USER CODE BEGIN PTD */4 c7 e' {. }5 ^$ a0 o H! {
- 用户可编写的代码区
/ i7 o/ L# h% E8 W$ h: ? ~) L - /* USER CODE END PTD */+ G! x+ H9 o+ ^$ o
- /* Private define ------------------------------------------------------------*/: l! s8 z- r- H" r# I9 y- w& q$ T
- /* USER CODE BEGIN PD */
' p" W7 G/ e6 p. _( u% R X - 用户可编写的代码区3 g$ d% {8 t1 n; T+ Z
0 X# i9 x. d, h- #define KEY1_Pin GPIO_PIN_11 //宏定义GPIO_PIN_11 为 KEY1_Pin
' q2 t+ r. d! x: C2 h% B6 o0 v - #define KEY1_GPIO_Port GPIOA //宏定义GPIOA 为 KEY1_GPIO_Port + q, ]/ ]7 a( @+ y
- #define LED1_Pin GPIO_PIN_12 //宏定义GPIO_PIN_12 为 LED1_Pin 1 c( P% x; L6 G) |. A
- #define LED1_GPIO_Port GPIOA //宏定义GPIOA 为 KEY1_GPIO_Port
& p6 \/ t8 T* F; z
& d6 L4 y* G3 W6 Z/ r! T, K- /* USER CODE END PD */9 z' @" I% L* b/ \# D& f- [
- ( N" ]* G. Z& U4 _& q
- /* Private macro -------------------------------------------------------------*/% u: j3 X/ e- r4 L. Z* k# ^
- /* USER CODE BEGIN PM */
; q1 U# z: ~( \8 m - 用户可编写的代码区
8 |$ j, g2 D. S7 A - /* USER CODE END PM */3 X6 A( l/ G& r
- . K n! o, L# r
- /* Private variables ---------------------------------------------------------*/- d( U# y/ k. C6 P; V9 U( o
- 0 l& n+ s3 R* I& S$ `
- /* USER CODE BEGIN PV */3 G5 Y l* t, E) m( q3 q9 Q
- 用户可编写的代码区
* Z! R6 M d1 N7 _" L7 e6 b - /* USER CODE END PV */
复制代码
0 E+ q/ V) x3 Q2 G$ O' K$ s - int main(void)
6 B) O( U' b ?/ {% } - {9 I. c5 h* `/ K7 G+ w$ C
- /* USER CODE BEGIN 1 */& `1 ?! W* G6 f' ]
- 用户可编写的代码区" z; ~$ B4 E# j1 I& [0 n
- /* USER CODE END 1 */
* b- [" A8 @/ Z4 y; j4 J - # `1 O5 d @( K @: {& E' e
- ' l+ @2 s" U. J- e$ W
- /* MCU Configuration--------------------------------------------------------*/
0 E/ ]7 _$ `2 p - 5 c& ^, f- g5 j$ W; [* N
- /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
4 o- a; W* B3 ]- ?# q( a - HAL_Init();) ^5 l/ W3 v$ v% d5 y6 P
# B6 u, v! d1 Z; p" [8 r- /* USER CODE BEGIN Init */
# t {( N( L5 E/ C - 用户可编写的代码区& ? {. t4 ]+ B* _( s! H
- /* USER CODE END Init */8 p X- W- M. n; @/ z/ b: t
- 3 c- C' T1 D% Q6 b) C
- /* Configure the system clock */; e$ w4 S3 p F7 i( Z
- SystemClock_Config();5 `( y, P+ m& r8 N; k- n1 k3 X
) N, `* L y$ D q- /* USER CODE BEGIN SysInit */
$ N/ H5 g7 H3 {- F D - 用户可编写的代码区 g" m# ~" G0 `2 |% |3 w
- /* USER CODE END SysInit */
% `) e' e& Z5 q/ x) v' {: V8 J* h4 U
0 P* ?* J Y: S7 M! `) `, ?3 {- /* Initialize all configured peripherals */' m3 u! g8 r/ a: F- l
- MX_GPIO_Init();$ j/ s; C- x: f2 g* {) \5 B! C. ^
- /* USER CODE BEGIN 2 */! v3 k2 o# A+ _7 n7 I0 K0 z
- 用户可编写的代码区: w$ G8 Y6 z0 Q+ k; z& o+ b: G/ |0 W
- /* USER CODE END 2 */$ j# J/ ~3 P7 q# c, C
- o4 n& M7 I3 H" A U- /* Infinite loop */
/ F' x" B8 t# ]4 U3 W+ l# } - /* USER CODE BEGIN WHILE */; _- V6 _8 P) {0 u# G" O
- while (1)% q# F0 H& U! y$ r5 p9 o t; X
- {2 x1 I: o3 \& C+ |& X- N3 g
- 用户可编写的代码区
2 z0 U, a2 Y: H( y' c3 j5 a - /* USER CODE END WHILE */- E" k5 O* M" [9 Z. A& l0 w- L3 N
! y4 j4 ]7 V5 K. w- /* USER CODE BEGIN 3 */( Y1 I2 _$ O$ u* ?
- }
# B9 I! _5 }9 ^8 [3 I - /* USER CODE END 3 */6 _! E9 L1 x9 E* ?+ Q
- }
复制代码 第二点:关于GPIO 的几个库函数使用说明: - //这是上一节讲到IO口初始化代码,该代码由STM32CubeMx 自动生成 Y8 C, m- B. l' y0 J
- static void MX_GPIO_Init(void): q7 r1 X8 i, d% @/ ?: j: t9 y+ l
- {" c6 j7 x4 l( Q
- GPIO_InitTypeDef GPIO_InitStruct = {0};1 @, N/ z( H; m, q
- , f8 W! D+ C% U
- /* GPIO Ports Clock Enable */ b( T1 O+ B4 U# q$ X& U$ S
- __HAL_RCC_GPIOA_CLK_ENABLE();+ c* r4 `/ c1 R0 `/ V$ V
- ; `4 m s. R. ^
- /*Configure GPIO pin Output Level */( K; u/ }' v; x# g
- HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_SET);//默认输出高
" [$ K2 ^, I, e4 ? - # ?- [9 L& |! V0 j
- /*Configure GPIO pin : KEY1_Pin */ : _' @! {+ B1 d$ K* j J+ H
- //这是我们之前在上位机配置的参数,生成代码后就这是这样了- W$ i" g: j2 y
- GPIO_InitStruct.Pin = KEY1_Pin; //初始化KEY1引脚! P* ?9 q# L% h0 t' I
- GPIO_InitStruct.Mode = GPIO_MODE_INPUT; //配置为输入模式: _/ V X& Z+ w, j4 |. S
- GPIO_InitStruct.Pull = GPIO_PULLUP; //上拉输入" |) u7 M1 u" I+ s- A( c6 f
- HAL_GPIO_Init(KEY1_GPIO_Port, &GPIO_InitStruct);4 {' T/ j3 Z4 e( |# L
- ; f: H- w& Z8 a" I
- /*Configure GPIO pin : LED1_Pin */) h3 u7 H/ I0 C9 P" U! ?
- GPIO_InitStruct.Pin = LED1_Pin; //初始化LED1引脚' U# Y9 {" ?3 r; X& s
- GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; //配置为输出模式
0 [" B6 m, X% ^8 D3 o& c4 G - GPIO_InitStruct.Pull = GPIO_PULLUP;//默认上拉输出% l! w4 ?% N" E. b7 Q Y5 k
- GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;//低速模式3 w; [4 ~( j4 `5 i3 s
- HAL_GPIO_Init(LED1_GPIO_Port, &GPIO_InitStruct);
5 G0 @0 t1 p+ s- {5 G5 { d - }
复制代码- /* HAL_GPIO_DeInit 重置IO口,恢复为默认状态
d/ T% k3 T% B/ B - . HAL_GPIO_ReadPin 读取IO口状态函数,需要把IO口配置为输入模式才可以读取到,这里注意一下( o" \0 {6 v# K1 Q7 M) u4 R, w
- · HAL_GPIO_WritePin 输出IO口状态函数,即对IO输出高电平/低电平( i9 D' z4 K9 T
- . HAL_GPIO_TogglePin 输出IO口翻转函数,即对IO口取反
1 _% d0 o- Z$ D( w0 W7 J - . HAL_GPIO_LockPin 锁定IO口函数,读管脚值使用锁定,当这个管脚电平变化时保持锁定的值。
) {$ L' E6 r! _4 [ - . HAL_GPIO_EXTI_IRQHandler 外部中断服务函数,详细使用,下期讲到!! r6 q5 ~5 {3 ?% n/ `
- . HAL_GPIO_EXTI_Callback 中断回调函数,详细使用,下期讲到!: K# u' Z' s0 L8 k6 U3 h' V
- */
3 K- f! N0 k' R. ^% o7 G. w3 j - void HAL_GPIO_DeInit(GPIO_TypeDef *GPIOx, uint32_t GPIO_Pin); K! L: H7 p/ e a% k9 `
- GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin);
0 \' r2 Z0 y' a$ {$ e4 d - void HAL_GPIO_WritePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState);
+ u4 E" |0 c* W b% a0 F - void HAL_GPIO_TogglePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin);* r' @7 z& A6 R3 f- j9 S
- HAL_StatusTypeDef HAL_GPIO_LockPin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin);
* p4 T2 f6 R, @$ i q, I' g9 b - void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin);1 [9 `, m8 ?9 m# b& ~- R- X
- void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin);
- a6 W) n2 z, `0 i3 z
' n8 u g8 I4 ^5 {- a8 X7 A# A- u, v- //搞清楚每个功能函数的功能后,我们只需要直接调用即可:
& l9 D" B8 A7 u- M - //例:
; C2 [; J7 v( P& X; e - if(!HAL_GPIO_ReadPin(KEY1_GPIO_Port,KEY1_Pin)) //如果KEY1 脚为低电平
& P$ v. D: N: |6 @. e A# p - {) w7 b, N" v. Y$ k+ v/ o
- HAL_GPIO_WritePin(LED1_GPIO_Port,LED1_Pin,GPIO_PIN_SET); //LED1输出高电平, y& _# U9 B9 ~ b
- HAL_Delay(1000); //延时函数1S
- g, {, C- a6 B: S" j5 m4 B - HAL_GPIO_WritePin(LED1_GPIO_Port,LED1_Pin,GPIO_PIN_RESET); //LED1输出低电平9 i& f6 o. v1 h! M- _2 g
- HAL_Delay(1000); //延时函数1S1 l: t7 \0 l+ T
- HAL_GPIO_TogglePin(LED1_GPIO_Port,LED1_Pin); // LED1 翻转输出电平- O, b, t! M& C1 r; X* z5 N# J! `, c
- }
复制代码
. E; F& n* q5 F如果能理解到这里,恭喜你已经学会了IO的基本操作! 文章出处: 电子爱好者 0 \) ?9 v- Z: D" q8 {) d9 Z
|