GPIO简介
GPIO是通用输入输出端口,IO端口里面拥有寄存器控制IO端口的输入输出工作。
GPIO驱动步骤
- 使能时钟 _HAL_RCC_GPIOx_CLK_ENABLE():x表A,B,C,D…F1:RCC_APB2ENR()
- 设置工作模式 :HAL_GPIO_Init():操作寄存器,F1:CRL、CRH、ODR
- 设置输出状态:HAL_GPIO_WritePin() ,HAL_GPIO_TogglePin(),操作寄存器BSRR,通过操作BSRR寄存器操作ODR寄存器。
- 读取输入状态:HAL_GPIO_ReadPin(),操作寄存器IDR
typedef struct
{
uint32_t Pin; /* 引脚号 */
uint32_t Mode; /* 模式设置 */
uint32_t Pull; /* 上拉下拉设置 */
uint32_t Speed; /* 速度设置 */
} GPIO_InitTypeDef;
HAL_GPIO_Init()函数
HAL_GPIO_Init()函数,在stm32f1xx_gpio.c中。
//GPIOx中的x表示A,B,C,D,E,F,G;
void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init){}
//GPIO_TypeDef是IO所有寄存器得到结构体
typedef struct
{
__IO uint32_t CRL;
__IO uint32_t CRH;
__IO uint32_t IDR;
__IO uint32_t ODR;
__IO uint32_t BSRR;
__IO uint32_t BRR;
__IO uint32_t LCKR;
} GPIO_TypeDef//定义在stm32f103xe.h
//GPIOB的定义在stm32f103xe.h中,他表示外设的基地址强制转化为结构体GPIO_TypeDef。这个就可以以结构体的方式操作。寄存器地址。
//#define GPIOB ((GPIO_TypeDef *)GPIOB_BASE)
//define GPIOA_BASE (APB2PERIPH_BASE + 0x00000800UL)
//此结构体在stm32f1xx_hal_gpio.h中。
typedef struct
{
uint32_t Pin; /* 引脚号 */
uint32_t Mode; /* 模式设置 */
uint32_t Pull; /* 上拉下拉设置 */
uint32_t Speed; /* 速度设置 */
} GPIO_InitTypeDef;
HAL_GPIO_WritePin()
void HAL_GPIO_WritePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState)
{
/* Check the parameters */
assert_param(IS_GPIO_PIN(GPIO_Pin));
assert_param(IS_GPIO_PIN_ACTION(PinState));
if (PinState != GPIO_PIN_RESET)//GPIO_PIN_RESET±íʾ0£¬¸´Î»
{
//BSSR是32位寄存器,低16位位设置端口x的位y(y=0...15)
GPIOx->BSRR = GPIO_Pin;
}
else
{
GPIOx->BSRR = (uint32_t)GPIO_Pin << 16u;
}
}
BSRR寄存器介绍
HAL_GPIO_ReadPin()
是操作寄存器IDR
GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
{
GPIO_PinState bitstatus;
/* Check the parameters */
assert_param(IS_GPIO_PIN(GPIO_Pin));
if ((GPIOx->IDR & GPIO_Pin) != (uint32_t)GPIO_PIN_RESET)
{
bitstatus = GPIO_PIN_SET;
}
else
{
bitstatus = GPIO_PIN_RESET;
}
return bitstatus;
}
#编程实战1 点亮一个LED灯
LED灯引脚
main.c
int main(void)
{
HAL_Init(); /*初始化Hal库 */
sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */
delay_init(72); /* 延时初始化 */
led_init(); /* LED初始化 */
while(1)
{
// HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_SET); /* PB5ÖÃ1 */
// delay_ms(200);
// HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_RESET); /* PB5ÖÃ0 */
// delay_ms(200);
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_5);
delay_ms(200);
}
}
led.h
/******************************************************************************************/
#define LED0_GPIO_PORT GPIOB
#define LED0_GPIO_PIN GPIO_PIN_5
#define LED0_GPIO_CLK_ENABLE() do{ __HAL_RCC_GPIOB_CLK_ENABLE(); }while(0)
#define LED1_GPIO_PORT GPIOE
#define LED1_GPIO_PIN GPIO_PIN_5
#define LED1_GPIO_CLK_ENABLE() do{ __HAL_RCC_GPIOE_CLK_ENABLE(); }while(0)
#define LED0(x) do{ x ? \
HAL_GPIO_WritePin(LED0_GPIO_PORT, LED0_GPIO_PIN, GPIO_PIN_SET) : \
HAL_GPIO_WritePin(LED0_GPIO_PORT, LED0_GPIO_PIN, GPIO_PIN_RESET); \
}while(0) /* LED0·×ª */
#define LED1(x) do{ x ? \
HAL_GPIO_WritePin(LED1_GPIO_PORT, LED1_GPIO_PIN, GPIO_PIN_SET) : \
HAL_GPIO_WritePin(LED1_GPIO_PORT, LED1_GPIO_PIN, GPIO_PIN_RESET); \
}while(0) /* LED1·×ª */
/* */
#define LED0_TOGGLE() do{ HAL_GPIO_TogglePin(LED0_GPIO_PORT, LED0_GPIO_PIN); }while(0) /* ·×ªLED0 */
#define LED1_TOGGLE() do{ HAL_GPIO_TogglePin(LED1_GPIO_PORT, LED1_GPIO_PIN); }while(0) /* ·×ªLED1 */
/******************************************************************************************/
/* */
void led_init(void); /* */
#endif
led_Init();在led.c中。
void led_init(void)
{
GPIO_InitTypeDef gpio_init_struct;
__HAL_RCC_GPIOB_CLK_ENABLE();
gpio_init_struct.Pin = GPIO_PIN_5;
gpio_init_struct.Mode = GPIO_MODE_OUTPUT_PP;
gpio_init_struct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOB, &gpio_init_struct);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_SET);
}
使用寄存器方式
led.c
void led_init(void)
{
LED0_GPIO_CLK_ENABLE(); /* LED0ʱÖÓʹÄÜ */
LED1_GPIO_CLK_ENABLE(); /* LED1ʱÖÓʹÄÜ */
sys_gpio_set(LED0_GPIO_PORT, LED0_GPIO_PIN,SYS_GPIO_MODE_OUT, SYS_GPIO_OTYPE_PP, SYS_GPIO_SPEED_MID, SYS_GPIO_PUPD_PU); /* LED0Òý½ÅģʽÉèÖà */
sys_gpio_set(LED1_GPIO_PORT, LED1_GPIO_PIN,SYS_GPIO_MODE_OUT, SYS_GPIO_OTYPE_PP, SYS_GPIO_SPEED_MID, SYS_GPIO_PUPD_PU); /* LED1Òý½ÅģʽÉèÖà */
LED0(1); /* ¹Ø±Õ LED0 */
LED1(1); /* ¹Ø±Õ LED1 */
}
led.h
#ifndef __LED_H
#define __LED_H
#include "./SYSTEM/sys/sys.h"
/******************************************************************************************/
/* Òý½Å ¶¨Òå */
#define LED0_GPIO_PORT GPIOB
#define LED0_GPIO_PIN SYS_GPIO_PIN5
#define LED0_GPIO_CLK_ENABLE() do{ RCC->APB2ENR |= 1 << 3; }while(0) /* PB¿ÚʱÖÓʹÄÜ */
#define LED1_GPIO_PORT GPIOE
#define LED1_GPIO_PIN SYS_GPIO_PIN5
#define LED1_GPIO_CLK_ENABLE() do{ RCC->APB2ENR |= 1 << 6; }while(0) /* PE¿ÚʱÖÓʹÄÜ 91Ò³Óвο¼¡£*/
/******************************************************************************************/
/* LED¶Ë¿Ú¶¨Òå */
#define LED0(x) sys_gpio_pin_set(LED0_GPIO_PORT, LED0_GPIO_PIN, x) /* LED0 */
#define LED1(x) sys_gpio_pin_set(LED1_GPIO_PORT, LED1_GPIO_PIN, x) /* LED1 */
/* LEDÈ¡·´¶¨Òå¡£ÕâÀïûÓп´Ì«¶®¡£ */
#define LED0_TOGGLE() do{ LED0_GPIO_PORT->ODR ^= LED0_GPIO_PIN; }while(0) /* LED0 = !LED0 */
#define LED1_TOGGLE() do{ LED1_GPIO_PORT->ODR ^= LED1_GPIO_PIN; }while(0) /* LED1 = !LED1 */
void led_init(void); /* ³õʼ»¯ */
#endif