打印
[其他ST产品]

STM32-GPIO输入输出(hal库)

[复制链接]
282|23
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
1、GPIO功能概述
(1)概述
STM32F407ZG有8个16引脚的GPIO端口。还有一个12引脚的PI端口。

GPIO端口都连接在AHB1总线上,自高时钟频率168MHz。

GPIO引脚能承受5V电压.

每个GPIO端口有4个32位寄存器,用于配置GPIO引脚的工作模式;1个32位输入数据寄存器和1个32位输出数据寄存器,还有复用功能选择寄存器等。

(2)GPIO引脚可以配置多种工作模式:
输入浮空(input floating):作为GPIO输入引脚,不使用上拉或下拉电阻。

输入上拉(input pull-up),作为GPIO输入引脚,使用内部上拉电阻。当没有外部输入时,引脚输入电平为高电平。

输入下拉(input pull-down):作为GPIO输入引脚,使用内部下拉电阻。当没有外部输入时,引脚输入电平为低电平。

模拟(analog):作为GPIO模拟引脚,用于ADC输入引脚或DAC输出引脚。

具有上拉或下拉的开漏输出(output open-drain):如果不使用上拉或下拉电阻,开漏输出1时引脚为高阻态,输出0时引脚是低电平。这种模式可用于共用总线的信号。

具有上拉或下拉的推挽输出(output push-pull):如果不使用上拉或下拉电阻,推挽输出1时引脚是高电平,输出0时引脚为低电平。若需要增强引脚输出驱动能力,就可以使用上拉。例如需要GPIO引脚输出高电平点亮LED时。

具有上拉或下拉的复用功能推挽(afternate function push-pull)。

具有上拉或下拉的复用功能开漏(afternate function open-drain)。

使用特权

评论回复
沙发
原来是wjc|  楼主 | 2023-12-27 16:20 | 只看该作者
2、GPIO的HAL驱动程序
HAL_GPIO_Init() GPIO引脚初始化

void HAL_GPIO_Init(GPIO_TypeDef *GPIOx,GPIO_InitTypeDef *GPIO_Init);
参数1 GPIO_TypeDef *GPIOx,定义了各个端口的各个寄存器的偏移地址,实际调用HAL_GPIO_Init()时使用端口的基地址作为参数GPIOx的值。在stm32f407xx.h中定义了各个端口的基地址。
#define GPIOA               ((GPIO_TypeDef *) GPIOA_BASE)
#define GPIOB               ((GPIO_TypeDef *) GPIOB_BASE)
#define GPIOC               ((GPIO_TypeDef *) GPIOC_BASE)
#define GPIOD               ((GPIO_TypeDef *) GPIOD_BASE)
#define GPIOE               ((GPIO_TypeDef *) GPIOE_BASE)
#define GPIOF               ((GPIO_TypeDef *) GPIOF_BASE)
#define GPIOG               ((GPIO_TypeDef *) GPIOG_BASE)
#define GPIOH               ((GPIO_TypeDef *) GPIOH_BASE)
#define GPIOI               ((GPIO_TypeDef *) GPIOI_BASE)

使用特权

评论回复
板凳
原来是wjc|  楼主 | 2023-12-27 16:20 | 只看该作者
参数2GPIO_InitTypeDef *GPIO_Init,定义了GPIO引脚的属性。

//定义GPIO属性的结构体
typedef struct
{
  uint32_t Pin;
  uint32_t Mode;
  uint32_t Pull;
  uint32_t Speed;
  uint32_t Alternate;
}GPIO_InitTypeDef;

使用特权

评论回复
地板
原来是wjc|  楼主 | 2023-12-27 16:20 | 只看该作者
//Pin定义GPIO的引脚
#define GPIO_PIN_0                 ((uint16_t)0x0001)
#define GPIO_PIN_1                 ((uint16_t)0x0002)
#define GPIO_PIN_2                 ((uint16_t)0x0004)
#define GPIO_PIN_3                 ((uint16_t)0x0008)
#define GPIO_PIN_4                 ((uint16_t)0x0010)
#define GPIO_PIN_5                 ((uint16_t)0x0020)
#define GPIO_PIN_6                 ((uint16_t)0x0040)
#define GPIO_PIN_7                 ((uint16_t)0x0080)
#define GPIO_PIN_8                 ((uint16_t)0x0100)
#define GPIO_PIN_9                 ((uint16_t)0x0200)
#define GPIO_PIN_10                ((uint16_t)0x0400)
#define GPIO_PIN_11                ((uint16_t)0x0800)
#define GPIO_PIN_12                ((uint16_t)0x1000)
#define GPIO_PIN_13                ((uint16_t)0x2000)
#define GPIO_PIN_14                ((uint16_t)0x4000)
#define GPIO_PIN_15                ((uint16_t)0x8000)
#define GPIO_PIN_All               ((uint16_t)0xFFFF)

#define GPIO_PIN_MASK              0x0000FFFFU

使用特权

评论回复
5
原来是wjc|  楼主 | 2023-12-27 16:21 | 只看该作者
//Mode定义引脚功能模式设置
#define  GPIO_MODE_INPUT     MODE_INPUT
    /*!<输入浮空模式*/
#define  GPIO_MODE_OUTPUT_PP    (MODE_OUTPUT | OUTPUT_PP)
    /*!<推挽输出模式*/
#define  GPIO_MODE_OUTPUT_OD    (MODE_OUTPUT | OUTPUT_OD)
    /*!<开漏输出模式*/
#define  GPIO_MODE_AF_PP   (MODE_AF | OUTPUT_PP)            
    /*!<复用功能推挽模式*/
#define  GPIO_MODE_AF_OD   (MODE_AF | OUTPUT_OD)
    /*!<复用功能开漏模式*/
#define  GPIO_MODE_ANALOG   MODE_ANALOG
    /*!<带上升沿触发检测的外部中断模式*/
#define GPIO_MODE_IT_RISING 0x10110000U
    /*!<带上升沿触发检测的外部中断模式*/
#define GPIO_MODE_IT_FALLING 0x10210000U
    /*!<带下降沿触发检测的外部中断模式*/
#define GPIO_MODE_IT_RISING_FALLING 0x10310000U
    /*!<带上升沿/下降沿触发检测的外部中断模式*/

#define  GPIO_MODE_EVT_RISING 0x10120000u   
    /*!<具有上升沿触发器检测的外部事件模式*/
#define  GPIO_MODE_EVT_FALLING 0x10220000u   
    /*!< 具有下降沿触发器检测的外部事件模式*/
#define  GPIO_MODE_EVT_RISING_FALLING 0x10320000u   
    /*!< 具有下降沿/下降沿触发器检测的外部事件模式*/

使用特权

评论回复
6
原来是wjc|  楼主 | 2023-12-27 16:21 | 只看该作者
//pull定义是否使用内部上拉或下拉电阻
#define  GPIO_NOPULL        0x00000000U /*!< 无上拉或下拉*/
#define  GPIO_PULLUP        0x00000001U /*!< 上拉*/
#define  GPIO_PULLDOWN      0x00000002U /*!< 下拉*/

使用特权

评论回复
7
原来是wjc|  楼主 | 2023-12-27 16:21 | 只看该作者
//Speed定义输出模式引脚的最高输出频率
#define  GPIO_SPEED_FREQ_LOW       0x00000000U //2MHz
#define  GPIO_SPEED_FREQ_MEDIUM    0x00000001U //12.5-50MHz
#define  GPIO_SPEED_FREQ_HIGH      0x00000002U //25-100MHz
#define  GPIO_SPEED_FREQ_VERY_HIGH 0x00000003U //50-200MHz

使用特权

评论回复
8
原来是wjc|  楼主 | 2023-12-27 16:21 | 只看该作者
//Alternate定义引脚复用功能
#define GPIO_AF1_TIM1          ((uint8_t)0x01)
#define GPIO_AF1_TIM2          ((uint8_t)0x01)
#define GPIO_AF4_I2C1          ((uint8_t)0x04)
#define GPIO_AF4_I2C2          ((uint8_t)0x04)
#define GPIO_AF4_I2C3          ((uint8_t)0x04)
#define GPIO_AF5_SPI1          ((uint8_t)0x05)
#define GPIO_AF5_SPI2          ((uint8_t)0x05)
#define GPIO_AF5_SPI3          ((uint8_t)0x05)
#define GPIO_AF7_USART1        ((uint8_t)0x07)  
#define GPIO_AF7_USART2        ((uint8_t)0x07)
#define GPIO_AF7_USART3        ((uint8_t)0x07)

使用特权

评论回复
9
原来是wjc|  楼主 | 2023-12-27 16:21 | 只看该作者

HAL_GPIO_DeInit() GPIO引脚反初始化,恢复为复位后的状态。

HAL_GPIO_WritePin() 使引脚输出0或1


void HAL_GPIO_WritePin(GPIO_TypeDef* GPIOx,uint16_t GPIO_Pin,GPIO_PinState PinState);

使用特权

评论回复
10
原来是wjc|  楼主 | 2023-12-27 16:22 | 只看该作者
PinState是引脚输出电平,是枚举类型GPIO_PinState,.
typedef enum
{
    GPIO_PIN_RESET = 0,
    GPIO_PIN_SET
}GPIO_PinState;

使用特权

评论回复
11
原来是wjc|  楼主 | 2023-12-27 16:22 | 只看该作者
例如,要使PF9和PF10输出低电平,使用下面代码:

HAL_GPIO_WritePin(GPIOF,GPIO_PIN_9|GPIO_PIN_10,GPIO_PIN_RESET);

使用特权

评论回复
12
原来是wjc|  楼主 | 2023-12-27 16:22 | 只看该作者
如果要输出高电平,使用下面代码:
HAL_GPIO_WritePin(GPIOF,GPIO_PIN_9|GPIO_PIN_10,GPIO_PIN_SET);

使用特权

评论回复
13
原来是wjc|  楼主 | 2023-12-27 16:23 | 只看该作者
HAL_GPIO_ReadPin() 读取引脚输入电平

GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef* GPIOx,uint16_t GPIO_PIN);

使用特权

评论回复
14
原来是wjc|  楼主 | 2023-12-27 16:23 | 只看该作者
HAL_GPIO_TogglePin() 反转引脚的输出

void HAL_GPIO_TogglePin(GPIO_TypeDef* GPIOx,uint16_t,GPIO_PIN);

使用特权

评论回复
15
原来是wjc|  楼主 | 2023-12-27 16:23 | 只看该作者
HAL_GPIO_LockPin() 锁定引脚配置,而不是锁定引脚的输入或输出状态

使用特权

评论回复
16
原来是wjc|  楼主 | 2023-12-27 16:23 | 只看该作者
3、GPIO使用示例
(1)电路资源
资源:

2个LED灯:由+3.3V电源驱动,当GPIO引脚输出为0时,LED点亮。当GPIO引脚输出为1时,LED熄灭。与LED连接的引脚PF9和PF10要设置为推挽输出。

4个按键:KeyUp键,外端接+3.3V,在按键按下时,输入PA0的是高电平,所以引脚PA0应该被设置为输入下拉。在按键未按下时,输入0;

另外3个按键,连接在PE2/PE3/PE4上,外端接地。按键按下时,输入低电平,所以使用输入上拉。

1个有源蜂鸣器:控制端在PF8,应设置为推挽输出。当PF8输出0时,蜂鸣器响,输出为1时,蜂鸣器不响。

使用特权

评论回复
17
原来是wjc|  楼主 | 2023-12-27 16:23 | 只看该作者
原理图:

使用特权

评论回复
18
原来是wjc|  楼主 | 2023-12-27 16:23 | 只看该作者
(2)功能要求
按下KeyLeft键时,使LED1的输出翻转。

按下KeyRight键时,使LED2的输出翻转。

按下KeyUp键时,使LED1和LED2的输出都翻转。

按下KeyDown键时,使蜂鸣器的输出翻转。

使用特权

评论回复
19
原来是wjc|  楼主 | 2023-12-27 16:24 | 只看该作者
(3)软件配置
SYS组件中,设置Debug接口为Serial Wire。

RCC组件中,设置HSE为Crystal/Ceramic Resonator。

在时钟树上,设置HSE频率8MHz,实际开发板就是8MHz,主锁相环选择HSE作为时钟源,设置HCLK频率168MHz,软件自动配置时钟树。

使用特权

评论回复
20
原来是wjc|  楼主 | 2023-12-27 16:24 | 只看该作者
根据3.3.2配置GPIO引脚。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

77

主题

985

帖子

0

粉丝