【STM32 HAL库学习】一、HAL库中GPIO初始化中指针和结构体理解

一、封装总线和外设基地址

#define FLASH_BASE            0x08000000UL /*!< FLASH(up to 1 MB)                             */
#define PERIPH_BASE           0x40000000UL /*!< Peripheral base address in the alias region                                */


/*!< Peripheral memory map */
#define APB1PERIPH_BASE       PERIPH_BASE
#define APB2PERIPH_BASE       (PERIPH_BASE + 0x00010000UL)
#define AHB1PERIPH_BASE       (PERIPH_BASE + 0x00020000UL)
#define AHB2PERIPH_BASE       (PERIPH_BASE + 0x10000000UL)

/*!< AHB1 peripherals */
#define GPIOA_BASE            (AHB1PERIPH_BASE + 0x0000UL)
#define GPIOB_BASE            (AHB1PERIPH_BASE + 0x0400UL)
#define GPIOC_BASE            (AHB1PERIPH_BASE + 0x0800UL)
#define GPIOD_BASE            (AHB1PERIPH_BASE + 0x0C00UL)
#define GPIOE_BASE            (AHB1PERIPH_BASE + 0x1000UL)
#define GPIOF_BASE            (AHB1PERIPH_BASE + 0x1400UL)
#define GPIOG_BASE            (AHB1PERIPH_BASE + 0x1800UL)
#define GPIOH_BASE            (AHB1PERIPH_BASE + 0x1C00UL)
#define GPIOI_BASE            (AHB1PERIPH_BASE + 0x2000UL)

二、用结构体对GPIO寄存器进行封装

    定义一个 GPIO_TypeDef类型的结构体,结构体成员是GPIO的寄存器
typedef struct
{
  __IO uint32_t MODER;    /*!< GPIO port mode register,               Address offset: 0x00      */
  __IO uint32_t OTYPER;   /*!< GPIO port output type register,        Address offset: 0x04      */
  __IO uint32_t OSPEEDR;  /*!< GPIO port output speed register,       Address offset: 0x08      */
  __IO uint32_t PUPDR;    /*!< GPIO port pull-up/pull-down register,  Address offset: 0x0C      */
  __IO uint32_t IDR;      /*!< GPIO port input data register,         Address offset: 0x10      */
  __IO uint32_t ODR;      /*!< GPIO port output data register,        Address offset: 0x14      */
  __IO uint32_t BSRR;     /*!< GPIO port bit set/reset register,      Address offset: 0x18      */
  __IO uint32_t LCKR;     /*!< GPIO port configuration lock register, Address offset: 0x1C      */
  __IO uint32_t AFR[2];   /*!< GPIO alternate function registers,     Address offset: 0x20-0x24 */
} GPIO_TypeDef;

三、定义GPIO端口首地址

在这里把GPIO的基地址由数字强制转换成为GPIO_TypeDef类型的指针(地址),并且命名为相应的GPIO,例如GPIOA,GPIOA是一个指向端口A的结构体指针,对于这个结构体指针,读写操作如下实现:
temp=(*GPIOA).MODER;
(*GPIOA).MODER=temp;
C语言允许把P->NUM代替(*P).NUM,所以对于可以采用以下方式操作
temp=GPIOA->MODER;
GPIOA->MODER=temp;
因为结构体指针GPIOA中的地址是端口A的结构体基地址,所以操作GPIOA->成员,就是对端口A结构体成员寄存器的操作。

#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)

四、GPIO端口初始化

通过两个结构体变量实现对GPIO端口的初始化。第一个GPIO_TypeDef类型结构体变量是具体哪一个端口的地址,例如GPIOA,第二个GPIO_InitTypeDef初始化定义结构体是对GPIOA端口具体引脚输入输出、速率、上下拉、是否复用等功能的初始化定义。
通过两个结构体把需要设置的内容传入到 HAL_GPIO_Init函数中,函数经过运算把需要设置参数写入到的寄存器,例如:
GPIOx->OSPEEDR = temp; 设置速率
GPIOx->OTYPER = temp; 设置输入输出类型
这样就完成了GPIO的HAL初始化操作

void HAL_GPIO_Init(GPIO_TypeDef  *GPIOx, GPIO_InitTypeDef *GPIO_Init)

五、GPIO引脚在主函数中的读写操作

void HAL_GPIO_WritePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState)  **// 写GPIO引脚**
GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)               **//读GPIO引脚**
void HAL_GPIO_TogglePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
                       **//输出翻转GPIO引脚**
发布了3 篇原创文章 · 获赞 0 · 访问量 47
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 数字20 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览