寄存器结构体
- 通过寄存器结构体和变量占位可以实现地址偏移的效果
- 将基地址强制转换为结构体的指针
示例:定义了寄存器结构体的头文件
//用来存放STM32寄存器映射的代码
//外设 perirhral
# define PERI_BASE ((unsigned int)0x40000000)
# define APB1_PERI_BASE PERI_BASE
# define APB2_PERI_BASE (PERI_BASE + 0X10000)
# define AHB_PERI_BASE (PERI_BASE + 0X20000)
# define RCC_BASE (AHB_PERI_BASE + 0X1000)
# define GPIOB_BASE (APB2_PERI_BASE + 0X0C00)
typedef unsigned int uint32_t;
typedef unsigned short unint16_t;
typedef struct
{
uint32_t CRL;
uint32_t CRH;
uint32_t IDR;
uint32_t ODR;
uint32_t BSRR;
uint32_t BRR;
uint32_t LCKR;
} GPIO_Typedef;
#define GPIOB ((GPIO_Typedef *)GPIOB_BASE)
typedef struct
{
uint32_t CR;
uint32_t CFGR;
uint32_t CIR;
uint32_t APB2RSTR;
uint32_t APB1RSTR;
uint32_t AHBENR;
uint32_t APB2ENR;
uint32_t APB1ENR;
uint32_t BDCR;
uint32_t CSR;
} RCC_Typedef;
#define RCC ((RCC_Typedef *)RCC_BASE)
函数实现
添加相应的外设的头文件和函数
为了防止重复包含,每一个头文件里先添加:
#indef __STM32F10X_H
#define __STM32F10X_H
#endif
编写置位跟清除的固件库函数
# include "stm32f10x_GPIO.h"
void GPIO_SetBits(GPIO_Typedef * GPIOx,uint16_t GPIO_Pin)
{
GPIOx->BSRR |= GPIO_Pin;
}
void GPIO_ResetBits(GPIO_Typedef * GPIOx,uint16_t GPIO_Pin)
{
GPIOx->BRR |= GPIO_Pin;
}
编写GPIO初始化的固件库函数
讲解固件库里的GPIO_INIT函数
示例:头文件中增加枚举和结构体以及函数声明
typedef enum
{
GPIO_Speed_10MHz =1, //10MHz (01)b
GPIO_Speed_2MHz, //2MHz (10)b
GPIO_Speed_50MHz, //50MHz (11)b
} GPIO_Speed_Typedef;
typedef enum
{
GPIO_Mode_AIN = 0x0, // 模拟输入 (00000000)b
GPIO_Mode_IN_FLOATING = 0x04, // 浮空输入 (00000100)b
GPIO_Mode_IPD = 0x28, // 下拉输入 (00101000)b
GPIO_Mode_IPU = 0x48, // 上拉输入 (01001000)b
GPIO_Mode_OUT_OD = 0x14, // 开漏输出 (00010100)b
GPIO_Mode_OUT_PP = 0x10, // 推挽输出 (00010000)b
GPIO_Mode_AF_OD = 0x1C, // 复用开漏输出 (00011100)b
GPIO_Mode_AF_PP = 0x18, // 复用推挽输出 (00011000)b
} GPIO_Mode_Typedef;
typedef struct
{
uint16_t GPIO_Pin;
uint16_t GPIO_Speed;
uint16_t GPIO_Mode;
} GPIO_Init_Typedef;
void GPIO_Init(GPIO_Typedef * GPIOx,GPIO_Init_Typedef * GPIO_Init );
初始化具体实现参考固件库函数。
总结及提高程序可移植性
- 将变量通过宏进行定义,后续如果需要修改只用修改宏定义就可以