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);
	    }
	}
相关推荐
蹊黎3 小时前
Linux 下用 C 语言实现进度条
linux·c语言·单片机
Zw-awa7 小时前
从 CPU 搬运到自动搬运:DMA、空闲中断和两块缓冲
stm32
无敌贵点大王7 小时前
从寄存器层面重学STM32(6)——串口USART实战部分
stm32·单片机·嵌入式硬件
庙堂龙吟奈我何7 小时前
二进制和十六进制
stm32·单片机
国科安芯9 小时前
长期在轨的计算底座:商业空间站与在轨服务飞行器健康管理中的抗辐射MCU—— 面向可维护空间平台的分层容错与安全通信综述
人工智能·单片机·嵌入式硬件·安全·低轨卫星·抗辐射
TST-魚爷9 小时前
小型视频会议室音频踩坑:一体化拾音扩音方案实测分享(易视讯)
stm32·电脑·音视频·钉钉·腾讯会议·zoom会议
不昀11 小时前
RMII切到10Mbps,50MHz参考时钟也要降到5MHz吗?
单片机·嵌入式硬件·硬件设计·以太网接口
路上有只喵12 小时前
认识元器件 · 单片机(MCU/MPU/SOC) · 实战篇6
单片机·嵌入式硬件
国科安芯12 小时前
核电站蒸汽发生器传热管在役无损检测模拟前端的低噪声供电研究
嵌入式硬件·ldo·低压差线性稳压器·无损检测·核电站·蒸汽发生器·传热管
集芯微电科技有限公司13 小时前
40V/24A高频率增强型GaN HEMT功率开关管/高频DC转换/电动工具/GaN充电器 方案首选
人工智能·科技·单片机·嵌入式硬件·深度学习·神经网络·生成对抗网络