实验原理
只要是对硬件操作,就要首先查看原理图。查看外设是和模块的 MCU 的哪个引脚相连。FS-MP1A 开发平台上的 LED 的亮灭状态,与芯片上的引脚 I/O 输出电平有关。
FS-MP1A 开发平台上 LED 的 I/O:
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 端口在作为输出时,可以软件配置端口最大支持的时钟速率,下图是端口输出速度寄存器,有以下几种速度选择:
/** @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
可以在左侧搜索框内输入芯片型号 STM32MP157A进行搜索,选择对应芯片,点击 Next
填写工程名,点击 Finsh
点击 Yes 打开配置页面
搜索框内搜索 LED 对应 GPIO 引脚 PZ5、PZ6、PZ7,左键点击设置为 GPIO_Output
这里我们需要注意一下,和其他单片机不同,还需要继续设置“ Pin Reservation”给“ Cortex-M4”,否则 STM32CubeMX 不会生生成 GPIO 初始化相关代码。具体操作:在刚才选择的引脚上,鼠标右键选择“ Pin Reservation”->“ Cortex-M4”。
在 Code Generator 处选择为每个外设生成单独的 C 和 H 文件,这样设置方便阅读代码
完成以上设置后,Ctrl+S 保存,会提示是否需要生成代码,选择 Yes 即可自动生成代码。系统会自动生成 System Clock 代码
添加 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 灯的状态
bsp_led_on();
HAL_Delay(500);
bsp_led_off();
HAL_Delay(500);
实验现象
可看到 LED 灯循环亮灭