|
在上一篇文章中,我们介绍了搭建Keil开发环境,并建立了第一个LED例程。现在我们来看看这个例程是怎么工作的。
根据NUCLEO-L476RG的原理图,可以看出LD2二极管连接到PA5,USER按键连接到PC13。 使用GPIO的第一步时使能时钟。该功能通过RCC(Reset and clock control)寄存器控制。所有的GPIO连接到AHB2总线。HAL库提供了专门的函数来启用GPIOA的时钟: - __HAL_RCC_GPIOA_CLK_ENABLE
复制代码该函数定义可在文件stm32l4xx_hal_rcc.h找到,其实现函数如下: - #define __HAL_RCC_GPIOA_CLK_ENABLE() do { \
- __IO uint32_t tmpreg; \
- SET_BIT(RCC->AHB2ENR, RCC_AHB2ENR_GPIOAEN); \
- /* Delay after an RCC peripheral clock enabling */ \
- tmpreg = READ_BIT(RCC->AHB2ENR, RCC_AHB2ENR_GPIOAEN); \
- UNUSED(tmpreg); \
- } while(0)
复制代码通过实现函数可知,主要方式是通过RCC_AHB2ENR寄存器的第0位(GPIOA EN)置位来实现。
接下来我们需要定义一个GPIO_InitTypeDef结构体来设置GPIO的参数设置。 - GPIO_InitTypeDef GPIO_InitStruct;
复制代码该结构体有5个参数: 1. Pin 选择引脚编号 2. Mode 设置GPIO的工作模式 3. Pull 设置引脚的上拉/下拉 4. Speed 设置GPIO输出的最大频率 5. Alternate 设置选择引脚的复用功能 其中每项都有自己的选项 ■ Pin:指定需要配置的GPIO管脚,该选项可以是以下的任何值: ■ GPIO_PIN_0: 选择引脚0; ■ GPIO_PIN_1: 选择引脚1; ■ GPIO_PIN_2: 选择引脚2; ■ GPIO_PIN_3: 选择引脚3; ■ GPIO_PIN_4: 选择引脚4; ■ GPIO_PIN_5: 选择引脚5; ■ GPIO_PIN_6: 选择引脚6; ■ GPIO_PIN_7: 选择引脚7; ■ GPIO_PIN_8: 选择引脚8; ■ GPIO_PIN_9: 选择引脚9; ■ GPIO_PIN_10: 选择引脚10; ■ GPIO_PIN_11: 选择引脚11; ■ GPIO_PIN_12: 选择引脚12; ■ GPIO_PIN_13: 选择引脚13; ■ GPIO_PIN_14: 选择引脚14; ■ GPIO_PIN_15: 选择引脚15; ■ GPIO_PIN_All: 选择所有的引脚; ■ GPIO_PIN_MASK:引脚掩码; ■ Mode:指定选择引脚的工作模式 ■ GPIO_MODE_INPUT:悬浮输入模式 ■ GPIO_MODE_OUTPUT_PP:推挽输出模式 ■ GPIO_MODE_OUTPUT_OD:漏极开路输出模式 ■ GPIO_MODE_AF_PP:复用功能推挽模式 ■ GPIO_MODE_AF_OD:复用功能漏极开路模式 ■ GPIO_MODE_ANALOG:模拟模式 ■ GPIO_MODE_ANALOG_ADC_CONTROL:模拟模式,用于ADC转换 ■ GPIO_MODE_IT_RISING:上升沿触发检测的外部中断模式 ■ GPIO_MODE_IT_FALLING:下降沿触发检测的外部中断模式 ■ GPIO_MODE_IT_RISING_FALLING:上升/下降沿触发检测的外部中断模式 ■ GPIO_MODE_EVT_RISING:上升沿触发检测的外部事件模式 ■ GPIO_MODE_EVT_FALLING:下降沿触发检测的外部事件模式 ■ GPIO_MODE_EVT_RISING_FALLING:上升/下降沿触发检测的外部事件模式 ■ Pull:指定引脚的上拉/下拉 ■ GPIO_NOPULL:无上拉/下拉电阻 ■ GPIO_PULLUP:带有上拉电阻 ■ GPIO_PULLDOWN:带有下拉电阻 ■ Speed:指定引脚的输出频率: ■ GPIO_SPEED_FREQ_LOW:输出频率最大为5MHz ■ GPIO_SPEED_FREQ_MEDIUM:输出频率范围5MHz-25MHz ■ GPIO_SPEED_FREQ_HIGH:输出频率范围25MHz-50MHz ■ GPIO_SPEED_FREQ_VERY_HIGH::输出频率范围50MHz-80MHz
HAL库提供了GPIO的初始化函数HAL_GPIO_Init()。该函数声明位于stm32l4xx_hal_gpio.h文件中。 - void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init)
复制代码我们需要将连接LD2的引脚PA5设置成推挽输出模式、带上拉电阻和输出频率最大为80MHz。具体代码如下: - GPIO_InitTypeDef GPIO_InitStruct;
- __HAL_RCC_GPIOA_CLK_ENABLE();
- GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
- GPIO_InitStruct.Pull = GPIO_PULLUP;
- GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
- GPIO_InitStruct.Pin = GPIO_PIN_5;
- HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
复制代码这样Led的配置就算完成了。我们可以使用以下代码点亮该Led: - HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET);
复制代码使用以下代码熄灭Led灯: - HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);
复制代码也可以实现闪烁Led的效果: - HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5);
复制代码
现在我们来设置USER按键。根据上面的藐视,我们需要将USER用户按钮设置成悬浮输入模式、带上拉和最大输出80MHz。代码如下: - __HAL_RCC_GPIOC_CLK_ENABLE();
- GPIO_InitDef.Pin = GPIO_PIN_13;
- GPIO_InitDef.Mode = GPIO_MODE_INPUT;
- GPIO_InitDef.Pull = GPIO_PULLUP;
- GPIO_InitDef.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
- //Initialize pins
- HAL_GPIO_Init(GPIOC, &GPIO_InitDef);
复制代码我们可以使用以下函数来读取输入引脚的当前状态: - HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_13))
复制代码以下是程序所有的代码: - #include "stm32l4xx.h"
- #include "stm32l4xx_hal_rcc.h"
- #include "stm32l4xx_hal_gpio.h"
- int main(void) {
- GPIO_InitTypeDef GPIO_InitDef;
-
- __HAL_RCC_GPIOA_CLK_ENABLE();
- GPIO_InitDef.Pin = GPIO_PIN_5;
- GPIO_InitDef.Mode = GPIO_MODE_OUTPUT_PP;
- GPIO_InitDef.Pull = GPIO_NOPULL;
- GPIO_InitDef.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
- //Initialize pins
- HAL_GPIO_Init(GPIOA, &GPIO_InitDef);
- __HAL_RCC_GPIOC_CLK_ENABLE();
- GPIO_InitDef.Pin = GPIO_PIN_13;
- GPIO_InitDef.Mode = GPIO_MODE_INPUT;
- GPIO_InitDef.Pull = GPIO_PULLDOWN;
- GPIO_InitDef.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
- //Initialize pins
- HAL_GPIO_Init(GPIOC, &GPIO_InitDef);
- while (1) {
- if (HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_13)) {
- HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET);
- } else {
- HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);
- }
- }
- }
复制代码下载到NUCLEO-L476开发板。开发板上的LD2点亮。当按下蓝色的USER按键时,LD2熄灭。
|