进阶篇 I [GPIO]

项目&教程仓库-STM32-RoboMaster-


0.0 一点点声明

  • 本文以及以后的所有属于RoboMaster主题STM32系列的文章,均以RoboMaster开发板A型为说明和测试目标,其芯片代号为STM32F427IIHx,如果您的芯片代号不同,则不能直接使用本教程代码和引脚配置,请酌情修改!

1.0 什么是GPIO?

  • General Purpose Input Output 通用输入/输出端口

GPIO接脚可以供使用者由程控自由使用,PIN脚依现实考量可作为通用输入 ( GPI ) 或通用输出 ( GPO ) 或通用输入与输出 ( GPIO ) 。在嵌入式系统中,经常需要控制许多结构简单的外部设备或者电路,这些设备有的需要通过CPU控制,有的需要CPU提供输入信号。对设备的控制,使用传统的串口或者并口就显得比较复杂,所以,在嵌入式微控制器上通常提供了一种“通用可编程I/O端口”,也就是GPIO。一个GPIO端口至少需要两个寄存器,一个做控制用的“通用IO端口控制寄存器”,还有一个是存放数据的“通用I/O端口数据寄存器”。数据寄存器的每一位是和GPIO的硬件引脚对应的,而数据的传递方向是通过控制寄存器设置的,通过控制寄存器可以设置每一位引脚的数据流向。

2.0 GPIO在哪里?

  1. 在开发板A型中,提供了18个用户自定义GPIO

RoboMaster-_A_-11.jpg

​ 上图中,26即为GPIO,位于开发板A型的中间位置

GPIO Pin.png

​ 这是GPIO的具体引脚图,在配置芯片引脚时请务必核实引脚号是否正确

  1. RoboMaster同样也非常体贴地预先将一些GPIO接到了用户自定义LED上,在2.1图中的位置为10和18,10的LED×8皆为绿色,而18的LED×2则是一绿一红,在用户自定义按键附近。只能设置为GPIO_Output模式。

GPIO LED.png

  1. 用户自定义按键(白色按键,黑色按键是STM32重启按键)。可以设置为GPIO_Input模式,或者GPIO_EXTI2模式(用于Interrupt 中断,现在不用理解这个,下个教程会讲)

GPIO Button.png

3.0 如何使用GPIO?

在下文中,几乎任何HAL函数的参数都需要外设和引脚,但是在比如Arduino的平台上,只需要引脚即可。其原因在于,对于STM32,一个外设可以连接众多引脚,在配置的时候,这些引脚都使用同一份外设配置,但是实际使用的时候,可以分别控制。

1
GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
  • 参数
    • GPIOx:想要读取的GPIO所属的外设
    • GPIO_Pin:想要读取的GPIO的引脚
  • 返回值
    • GPIO_PinState:当I/O为低 ( 0 ) 时,返回GPIO_PIN_RESET;当I/O为高 ( 1 ) 时,返回GPIO_PIN_SET

1
void HAL_GPIO_WritePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState)
  • 参数
    • GPIOx:想要写入的GPIO所属的外设
    • GPIO_Pin:想要写入的GPIO的引脚
    • PinState:想要写入的GPIO状态【GPIO_PIN_RESET / GPIO_PIN_SET

1
void HAL_GPIO_TogglePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
  • 参数
    • GPIOx:想要反转的GPIO所属的外设
    • GPIO_Pin:想要反转的GPIO的引脚

如果GPIO状态为GPIO_PIN_RESET,则改为GPIO_PIN_SET
如果GPIO状态为GPIO_PIN_SET,则改为GPIO_PIN_RESET


1
HAL_StatusTypeDef HAL_GPIO_LockPin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
  • 参数
    • GPIOx:想要锁死的GPIO所属的外设
    • GPIO_Pin:想要锁死的GPIO的引脚

锁死的是该GPIO的配置,而不是状态。任何尝试修改其配置的操作都会失败,除非重置GPIO。


1
void HAL_GPIO_DeInit(GPIO_TypeDef *GPIOx, uint32_t GPIO_Pin)
  • 参数
    • GPIOx:想要重置的GPIO所属的外设
    • GPIO_Pin:想要重置的GPIO的引脚

重置GPIO到默认的配置(Input Floating模式)。用于当我们不再使用某个外设时,节约电量,避免额外的消耗。

4.0 练习项目

4.1 项目简介

  • 按键版流水灯:按下白色按键后,依次让自带的LED灯按顺序亮起,或者依次熄灭

4.2 芯片配置

  • 芯片视角

Chip.png

  • GPIO配置列表

Config.png

4.3 项目代码

  • 一点有必要的说明

    • 主要看Src/main.cint main(void)函数里while (1)部分的代码,其余部分没看懂不用担心,不是本篇章的重点

    • 我只放了main.c,完整的工程文件可以在这里找到!

    • 完整的工程目录

RM01Tree.png

  • Src/main.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : main.c
* @brief : Main program body
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2020 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
*/
/* USER CODE END Header */

/* Includes ------------------------------------------------------------------*/
#include "main.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */

/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */

/* USER CODE END 1 */

/* MCU Configuration--------------------------------------------------------*/

/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();

/* USER CODE BEGIN Init */

/* USER CODE END Init */

/* Configure the system clock */
SystemClock_Config();

/* USER CODE BEGIN SysInit */

/* USER CODE END SysInit */

/* Initialize all configured peripherals */
MX_GPIO_Init();
/* USER CODE BEGIN 2 */

/* USER CODE END 2 */

/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
if(HAL_GPIO_ReadPin(Button_GPIO_Port,Button_Pin) == GPIO_PIN_SET){
HAL_Delay(500);
HAL_GPIO_TogglePin(LD_RED_GPIO_Port,LD_RED_Pin);
HAL_Delay(100);
HAL_GPIO_TogglePin(LD_GREEN_GPIO_Port,LD_GREEN_Pin);
HAL_Delay(100);
HAL_GPIO_TogglePin(LD1_GPIO_Port,LD1_Pin);
HAL_Delay(100);
HAL_GPIO_TogglePin(LD2_GPIO_Port,LD2_Pin);
HAL_Delay(100);
HAL_GPIO_TogglePin(LD3_GPIO_Port,LD3_Pin);
HAL_Delay(100);
HAL_GPIO_TogglePin(LD4_GPIO_Port,LD4_Pin);
HAL_Delay(100);
HAL_GPIO_TogglePin(LD5_GPIO_Port,LD5_Pin);
HAL_Delay(100);
HAL_GPIO_TogglePin(LD6_GPIO_Port,LD6_Pin);
HAL_Delay(100);
HAL_GPIO_TogglePin(LD7_GPIO_Port,LD7_Pin);
HAL_Delay(100);
HAL_GPIO_TogglePin(LD8_GPIO_Port,LD8_Pin);
}
/* USER CODE END WHILE */

/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}

/**
* @brief System Clock Configuration
* @retval None
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

/** Configure the main internal regulator output voltage
*/
__HAL_RCC_PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE3);
/** Initializes the CPU, AHB and APB busses clocks
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB busses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
{
Error_Handler();
}
}

/**
* @brief GPIO Initialization Function
* @param None
* @retval None
*/
static void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};

/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOG_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOE_CLK_ENABLE();
__HAL_RCC_GPIOF_CLK_ENABLE();

/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOG, LD8_Pin|LD7_Pin|LD6_Pin|LD5_Pin
|LD4_Pin|LD3_Pin|LD2_Pin|LD1_Pin, GPIO_PIN_RESET);

/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(LD_RED_GPIO_Port, LD_RED_Pin, GPIO_PIN_RESET);

/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(LD_GREEN_GPIO_Port, LD_GREEN_Pin, GPIO_PIN_RESET);

/*Configure GPIO pins : LD8_Pin LD7_Pin LD6_Pin LD5_Pin
LD4_Pin LD3_Pin LD2_Pin LD1_Pin */
GPIO_InitStruct.Pin = LD8_Pin|LD7_Pin|LD6_Pin|LD5_Pin
|LD4_Pin|LD3_Pin|LD2_Pin|LD1_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);

/*Configure GPIO pin : Button_Pin */
GPIO_InitStruct.Pin = Button_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(Button_GPIO_Port, &GPIO_InitStruct);

/*Configure GPIO pin : LD_RED_Pin */
GPIO_InitStruct.Pin = LD_RED_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(LD_RED_GPIO_Port, &GPIO_InitStruct);

/*Configure GPIO pin : LD_GREEN_Pin */
GPIO_InitStruct.Pin = LD_GREEN_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(LD_GREEN_GPIO_Port, &GPIO_InitStruct);

}

/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

/**
* @brief This function is executed in case of error occurrence.
* @retval None
*/
void Error_Handler(void)
{
/* USER CODE BEGIN Error_Handler_Debug */
/* User can add his own implementation to report the HAL error return state */

/* USER CODE END Error_Handler_Debug */
}

#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file: pointer to the source file name
* @param line: assert_param error line source number
* @retval None
*/
void assert_failed(uint8_t *file, uint32_t line)
{
/* USER CODE BEGIN 6 */
/* User can add his own implementation to report the file name and line number,
tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

4.4 效果展示