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);
	    }
	}
相关推荐
金戈鐡馬6 小时前
定时器+中断优化单总线通信
stm32·单片机·嵌入式硬件
cici158746 小时前
STM32 + VS1003/VS1053 MP3播放器SD卡读取程序
stm32·单片机·嵌入式硬件
念一不念二7 小时前
[SSD]SSD主控
嵌入式硬件
xiangw@GZ7 小时前
DDR3 颗粒信号定义解析
单片机·嵌入式硬件
小+不通文墨7 小时前
在树莓派中部署emqx
经验分享·笔记·单片机·学习
Deitymoon7 小时前
STM32——oled显示字符串和数字
stm32·单片机·嵌入式硬件
深圳市晨芯阳科技有限公司7 小时前
带延时功能的电压检测系列晨芯阳HC809
单片机·嵌入式硬件·电源芯片·深圳市晨芯阳科技有限公司
xiangw@GZ7 小时前
DDR2 / DDR3 / DDR4 颗粒信号差异对照表
单片机·嵌入式硬件
科芯创展7 小时前
1A,60VIN,1MHz,XZ4116,降压恒流LED驱动芯片 输入电压:5V-60V
stm32·单片机·嵌入式硬件
振浩微433射频芯片8 小时前
工业环境下的“硬核”选择:如何科学评估国产433芯片的可靠性?
网络·人工智能·科技·单片机·物联网·学习