实验原理
只要是对硬件操作,就要首先查看原理图。查看外设是和模块的 MCU 的哪个引脚相连。FS-MP1A 开发平台上的 LED 的亮灭状态,与芯片上的引脚 I/O 输出电平有关。
FS-MP1A 开发平台上 LED 的 I/O:
![](https://i-blog.csdnimg.cn/blog_migrate/ee0a197bd97699c8e464dc3bb3a980fb.png)
IO 操作重要结构体:GPIO_InitTypeDef
/**
* @brief GPIO Init structure definition
*/
typedef struct
{
uint32_t Pin; /*!< Specifies the GPIO pins to be configured.This parameter can be any value of @ref GPIO_pins_define */
uint32_t Mode; /*!< Specifies the operating mode for the selected pins.This parameter can be a value of @ref GPIO_mode_define */
uint32_t Pull; /*!< Specifies the Pull-up or Pull-Down activation for the selected pins.This parameter can be a value of @ref GPIO_pull_define */
uint32_t Speed; /*!< Specifies the speed for the selected pins.This parameter can be a value of @ref GPIO_speed_define */
uint32_t Alternate; /*!< Peripheral to be connected to the selected pins.This parameter can be a value of @ref GPIO_Alternate_function_selection */
}GPIO_InitTypeDef;
第一个成员变量 Pin 是所操作的管脚,第二个 Mode 是模式选择,第三个 Pull 是上拉下拉,或者都不加,第四个 Speed 是速度选择,第五个是管脚复用功能。一般我们只操作前四个。
IO 口可以由软件配置成 4 种模式,其实操作的是 GPIO 的端口模式寄存器:
输入(复位状态)/input(reset state)
通用输出模式 / general purpose output mode
复用功能模式 / alternate function mode
模拟模式 / analog mode
#define GPIO_MODE_INPUT ((uint32_t)0x00000000U) /*!< Input Floating Mode */
#define GPIO_MODE_OUTPUT_PP ((uint32_t)0x00000001U) /*!< Output Push Pull Mode */
#define GPIO_MODE_OUTPUT_OD ((uint32_t)0x00000011U) /*!< Output Open Drain Mode */
#define GPIO_MODE_AF_PP ((uint32_t)0x00000002U) /*!< Alternate Function Push Pull Mode */
#define GPIO_MODE_AF_OD ((uint32_t)0x00000012U) /*!< Alternate Function Open Drain Mode */
上面给两个寄存器赋值了,1~4 位是 GPIO 端口模式寄存器,5~8 位是端口输出类型寄存器(决定是推挽输出还是开漏输出)。
STM32 的 GPIO 端口在作为输出时,可以软件配置端口最大支持的时钟速率,下图是端口输出速度寄存器,有以下几种速度选择:
![](https://i-blog.csdnimg.cn/blog_migrate/a037017facf0e294d0cd4afa050c4e7e.png)
/** @defgroup GPIO_speed_define GPIO speed define
* @brief GPIO Output Maximum frequency
* @{
*/
#define GPIO_SPEED_FREQ_LOW ((uint32_t)0x00000000U) /*!< Low speed */
#define GPIO_SPEED_FREQ_MEDIUM ((uint32_t)0x00000001U) /*!< Medium speed */
#define GPIO_SPEED_FREQ_HIGH ((uint32_t)0x00000002U) /*!< Fast speed */
#define GPIO_SPEED_FREQ_VERY_HIGH ((uint32_t)0x00000003U) /*!< High speed */
GPIO 调用的 HAL 函数:
void HAL_GPIO_WritePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, GPIO_PinState
PinState);
该函数其实是对 BSRR 寄存器进行操作。
第一个参数传的是 GPIO 所在的组,第二个是该组的几号管脚,第三个是对管脚进行置位。
实验步骤
打开 STM32CubeIDE->File->New->STM32 Project
![](https://i-blog.csdnimg.cn/blog_migrate/b6c9d2426e9fe837dffaa74748d61361.png)
可以在左侧搜索框内输入芯片型号 STM32MP157A进行搜索,选择对应芯片,点击 Next
![](https://i-blog.csdnimg.cn/blog_migrate/b91c7b4f914552d790a3ebec1de09775.png)
填写工程名,点击 Finsh
![](https://i-blog.csdnimg.cn/blog_migrate/5e8b14450f2c31c100b32a1611ee1ca1.png)
点击 Yes 打开配置页面
![](https://i-blog.csdnimg.cn/blog_migrate/5cc2212b45fe3b6e0b41262434c44ada.png)
![](https://i-blog.csdnimg.cn/blog_migrate/af58e290089eb592ecb838f1fd9b6b43.png)
搜索框内搜索 LED 对应 GPIO 引脚 PZ5、PZ6、PZ7,左键点击设置为 GPIO_Output
![](https://i-blog.csdnimg.cn/blog_migrate/4b0125e47f5af1eae2536f28291f63fc.png)
这里我们需要注意一下,和其他单片机不同,还需要继续设置“ Pin Reservation”给“ Cortex-M4”,否则 STM32CubeMX 不会生生成 GPIO 初始化相关代码。具体操作:在刚才选择的引脚上,鼠标右键选择“ Pin Reservation”->“ Cortex-M4”。
![](https://i-blog.csdnimg.cn/blog_migrate/48780e55df068ab4248abb2fc786db9d.png)
在 Code Generator 处选择为每个外设生成单独的 C 和 H 文件,这样设置方便阅读代码
![](https://i-blog.csdnimg.cn/blog_migrate/3fe10238837e63251fff086125458347.png)
完成以上设置后,Ctrl+S 保存,会提示是否需要生成代码,选择 Yes 即可自动生成代码。系统会自动生成 System Clock 代码
![](https://i-blog.csdnimg.cn/blog_migrate/94170fcc84e1a7c82134c73b479ff254.png)
添加 GPIO 函数说明:
我们需要在 main.c 中添加 GPIO 相关函数, GPIO 引脚输出电平高低函数
void bsp_led_on(void)
{
HAL_GPIO_WritePin(GPIOZ, GPIO_PIN_5,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOZ, GPIO_PIN_6,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOZ, GPIO_PIN_7,GPIO_PIN_SET);
}
void bsp_led_off(void)
{
HAL_GPIO_WritePin(GPIOZ, GPIO_PIN_5,GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOZ, GPIO_PIN_6,GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOZ, GPIO_PIN_7,GPIO_PIN_RESET);
}
在 main.c 中调用函数改变 GPIO 引脚高低电平来改变 LED 灯的状态
![](https://i-blog.csdnimg.cn/blog_migrate/c45080fa3435fb36fe00bd5cc44e9723.png)
bsp_led_on();
HAL_Delay(500);
bsp_led_off();
HAL_Delay(500);
实验现象
可看到 LED 灯循环亮灭
![](https://i-blog.csdnimg.cn/blog_migrate/7a43e89589f7ea1f6397f7d76b2a8ddb.png)