STM32_GPIO_寄存器操作

一、端口配置低寄存器(GPIOx_CRL)(Port Configuration Register Low)

偏移地址:0x00
  复位值:0x4444 4444

二、端口配置高寄存器(GPIOx_CRH)(Port Configuration Register High)

偏移地址:0x04
  复位值:0x4444 4444

三、端口输入数据寄存器(GPIOx_IDR)(Intput Data Register)

地址偏移:0x08
  复位值:0x0000 XXXX

四、端口输出数据寄存器(GPIOx_ODR)(Output Data Register)

地址偏移:0Ch
  复位值:0x0000 0000

五、端口位设置/清除寄存器(GPIOx_BSRR)( Bit Setting/Reset Register)

地址偏移:0x10
  复位值:0x0000 0000

六、端口位清除寄存器(GPIOx_BRR)( Bit Reset Register)

地址偏移:0x14
  复位值:0x0000 0000

七、端口配置锁定寄存器(GPIOx_LCKR)(Port configuration LOCK Register)

地址偏移:0x18
  复位值:0x0000 0000

八、C语言的封装

stm32F103_gpio_reg.h

c 复制代码
	#ifndef __STM32F103_GPIO_REG_H
	#define __STM32F103_GPIO_REG_H
	
	#include <stdint.h>  // 引入标准整数类型(uint32_t等),替代unsigned int更规范
	
	// ===================== 1. 总线基地址定义 =====================
	#define PERIPH_BASE           ((uint32_t)0x40000000)  // 外设基地址
	#define APB2PERIPH_BASE       (PERIPH_BASE + 0x00010000)  // APB2总线基地址
	#define AHBPERIPH_BASE        (PERIPH_BASE + 0x00020000)  // AHB总线基地址
	
	// ===================== 2. RCC时钟寄存器(GPIO依赖) =====================
	#define RCC_BASE              (AHBPERIPH_BASE + 0x1000)  // RCC基地址
	// APB2外设时钟使能寄存器 (RCC_APB2ENR)
	#define RCC_APB2ENR           (*(volatile uint32_t *)(RCC_BASE + 0x18))
	// GPIO时钟使能位定义
	#define RCC_APB2ENR_IOPAEN    ((uint32_t)0x00000004)  // GPIOA时钟使能
	#define RCC_APB2ENR_IOPBEN    ((uint32_t)0x00000008)  // GPIOB时钟使能
	#define RCC_APB2ENR_IOPCEN    ((uint32_t)0x00000010)  // GPIOC时钟使能
	#define RCC_APB2ENR_IOPDEN    ((uint32_t)0x00000020)  // GPIOD时钟使能
	#define RCC_APB2ENR_IOPEEN    ((uint32_t)0x00000040)  // GPIOE时钟使能
	#define RCC_APB2ENR_IOPFEN    ((uint32_t)0x00000080)  // GPIOF时钟使能
	#define RCC_APB2ENR_IOPGEN    ((uint32_t)0x00000100)  // GPIOG时钟使能
	
	// ===================== 3. GPIO寄存器基地址 =====================
	#define GPIOA_BASE            (APB2PERIPH_BASE + 0x0800)  // GPIOA基地址
	#define GPIOB_BASE            (APB2PERIPH_BASE + 0x0C00)  // GPIOB基地址
	#define GPIOC_BASE            (APB2PERIPH_BASE + 0x1000)  // GPIOC基地址
	#define GPIOD_BASE            (APB2PERIPH_BASE + 0x1400)  // GPIOD基地址
	#define GPIOE_BASE            (APB2PERIPH_BASE + 0x1800)  // GPIOE基地址
	#define GPIOF_BASE            (APB2PERIPH_BASE + 0x1C00)  // GPIOF基地址
	#define GPIOG_BASE            (APB2PERIPH_BASE + 0x2000)  // GPIOG基地址
	
	// ===================== 4. GPIO寄存器偏移量(所有GPIO通用) =====================
	#define GPIO_CRL_OFFSET       ((uint32_t)0x00)  // 端口配置低寄存器(Pin0~7)
	#define GPIO_CRH_OFFSET       ((uint32_t)0x04)  // 端口配置高寄存器(Pin8~15)
	#define GPIO_IDR_OFFSET       ((uint32_t)0x08)  // 输入数据寄存器
	#define GPIO_ODR_OFFSET       ((uint32_t)0x0C)  // 输出数据寄存器
	#define GPIO_BSRR_OFFSET      ((uint32_t)0x10)  // 位设置/复位寄存器
	#define GPIO_BRR_OFFSET       ((uint32_t)0x14)  // 位复位寄存器
	#define GPIO_LCKR_OFFSET      ((uint32_t)0x18)  // 配置锁定寄存器
	
	// ===================== 5. 通用GPIO寄存器宏定义(核心,一键访问任意端口寄存器) =====================
	// 示例:GPIO_REG(GPIOA, CRL) 等价于 GPIOA的CRL寄存器地址
	#define GPIO_REG(PORT, REG)   (*(volatile uint32_t *)(PORT##_BASE + GPIO_##REG##_OFFSET))
	
	// ===================== 6. 简化操作的宏(可选,提升代码可读性) =====================
	// 置位某引脚(通过BSRR,原子操作,无需关中断)
	#define GPIO_SET_PIN(PORT, PIN)    (GPIO_REG(PORT, BSRR) = (1 << PIN))
	// 复位某引脚(通过BSRR的高16位)
	#define GPIO_RESET_PIN(PORT, PIN)  (GPIO_REG(PORT, BSRR) = (1 << (PIN + 16)))
	// 读取某引脚电平
	#define GPIO_READ_PIN(PORT, PIN)   ((GPIO_REG(PORT, IDR) & (1 << PIN)) ? 1 : 0)
	
	#endif /* __STM32F103_GPIO_REG_H */

main.c

c 复制代码
	#include "stm32f103_GPIO_REG_H"
	
	// 简单延时函数
	void Delay_ms(uint32_t ms)
	{
	    uint32_t i, j;
	    for(i = 0; i < ms; i++)
	        for(j = 0; j < 1141; j++);
	}
	
	int main(void)
	{
	    // 步骤1:开启GPIOB和GPIOA时钟
	    RCC_APB2ENR |= RCC_APB2ENR_IOPBEN | RCC_APB2ENR_IOPAEN;
	
	    // 步骤2:配置PB0为推挽输出(50MHz)
	    // 清空PB0的CRL位(0~3位)
	    GPIO_REG(GPIOB, CRL) &= ~((uint32_t)0x0000000F);
	    // 配置MODE0=11(50MHz输出),CNF0=00(推挽输出)
	    GPIO_REG(GPIOB, CRL) |= ((uint32_t)0x00000003);
	
	    // 步骤3:配置PA0为上拉输入
	    // 清空PA0的CRL位(0~3位)
	    GPIO_REG(GPIOA, CRL) &= ~((uint32_t)0x0000000F);
	    // MODE0=00(输入模式),CNF0=10(上拉/下拉输入)
	    GPIO_REG(GPIOA, CRL) |= ((uint32_t)0x00000008);
	    // 上拉:ODR置1,下拉置0
	    GPIO_REG(GPIOA, ODR) |= (1 << 0);
	
	    // 主循环
	    while(1)
	    {
	        // 如果PA0为高电平,PB0亮;否则灭
	        if(GPIO_READ_PIN(GPIOA, 0))
	        {
	            GPIO_SET_PIN(GPIOB, 0);      // PB0置1(亮)
	        }
	        else
	        {
	            GPIO_RESET_PIN(GPIOB, 0);    // PB0置0(灭)
	        }
	        Delay_ms(100);
	    }
	}
相关推荐
AI+程序员在路上2 小时前
STM32L0单片机低功耗用法
stm32·单片机·嵌入式硬件
LCG元2 小时前
以太网通信实战:STM32F407+LAN8720A+LwIP,TCP/IP协议栈应用
stm32·嵌入式硬件·tcp/ip
笨笨没好名字2 小时前
# 单片机入门:51单片机与开发板介绍
单片机·嵌入式硬件·51单片机
我在人间贩卖青春2 小时前
认识MCU
单片机·嵌入式硬件
WYH2873 小时前
STM32无感无刷电调实现方法
stm32·单片机·嵌入式硬件
风痕天际3 小时前
ESP32-S3开发教程9:扣子智能体快速搭建与API调用例程使用讲解
单片机·esp32-s3·esp-idf·智能体·扣子
三佛科技-134163842124 小时前
HN15N10DA_TO-252封装100V 15A 增强MOSFET场效应管详细分析(HN15N10DA在小家电的应用)
嵌入式硬件·物联网·智能家居·pcb工艺
逐步前行4 小时前
STM32_时钟树
stm32·单片机·嵌入式硬件
lljss20204 小时前
ADC通道切换在GD32和PY32(STM32)区别
stm32·单片机·嵌入式硬件