一:寄存器结构体定义
声明结构体,结构体成员类型顺序与寄存器排列顺序一致,再找到它的基地址,将基地址强制类型转换为结构体指针,就可以指向结构体成员。
typedef unsigned int uint32_t;
typedef unsigned short uint16_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;
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;
//强制类型转换 ((GPIO_TypeDef *)转换为结构体类型指针,再定义为宏,GPIOB即为GPIO_TypeDef类型指针,指向GPIOB
#define GPIOB ((GPIO_TypeDef *)GPIOB_BASE)
#define RCC ((RCC_TypeDef *)RCC_BASE)
二:编写端口置位复位函数
提高可读性,不使用ODR寄存器,而编写端口置位复位,方便阅读;
添加stm32f10x_gpio.c和stm32f10x_gpio.h文件,用于将外设相关函数放在这两个文件中;
在stm32f10x_gpio.h文件中为防止重复定义,用条件宏套娃;
#ifndef _STM32F10X_GPIO_H
#define _STM32F10X_GPIO_H
#include "stm32f10x.h"
#endif /*_STM32F10X_GPIO_H*/
在stm32f10x.h文件中同理;
#ifndef _STM32F10X_H
#define _STM32F10X_H
#endif /*STM32F10X_H*/
在main.c文件中同时引用两个头文件不会出现重复定义
3.在stm32f10x_gpio.c文件中写端口置位复位函数,且由于BSRR和BRR低16位写1有效,只需在. h文件提前定义16个IO口直接调用即可,注意要在.h文件中声明该函数方便调用。
#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;
}
main.c文件中即可使用BSRR和BRR函数控制LED 灯
GPIO_SetBits(LED_GPIO_PORT , LED_B_GPIO_PIN);
GPIO_ResetBits(LED_GPIO_PORT ,LED_B_GPIO_PIN);