库函数实现结构体访问寄存器地址原理

访问寄存器是基地址加偏移
ADC1—>DR访问DR寄存器,&ADC1—>DR访问DR寄存器地址

#define ADC1                ((ADC_TypeDef *) ADC1_BASE)
//把ADC1_BASE(ADC1的基地址)强转为ADC_TypeDef型的指针

#define ADC1_BASE             (APB2PERIPH_BASE + 0x2400)
//等于APB2外设基地址加0x2400

#define APB2PERIPH_BASE       (PERIPH_BASE + 0x10000)
//等于外设基地址加0x10000

#define PERIPH_BASE           ((uint32_t)0x40000000)
//外设基地址等于0x40000000(4*8=32位)
/*补充:
  #define FLASH_BASE            ((uint32_t)0x08000000) 
  #define SRAM_BASE             ((uint32_t)0x20000000)
*/

此时ADC1基地址有了,等于40012400,再加一个偏移就能得到DR寄存器的地址,库函数巧妙地使用结构体实现偏移。

跳转到ADC_TypeDef结构体定义

typedef struct
{
  __IO uint32_t SR;
  __IO uint32_t CR1;
  __IO uint32_t CR2;
  __IO uint32_t SMPR1;
  __IO uint32_t SMPR2;
  __IO uint32_t JOFR1;
  __IO uint32_t JOFR2;
  __IO uint32_t JOFR3;
  __IO uint32_t JOFR4;
  __IO uint32_t HTR;
  __IO uint32_t LTR;
  __IO uint32_t SQR1;
  __IO uint32_t SQR2;
  __IO uint32_t SQR3;
  __IO uint32_t JSQR;
  __IO uint32_t JDR1;
  __IO uint32_t JDR2;
  __IO uint32_t JDR3;
  __IO uint32_t JDR4;
  __IO uint32_t DR;
} ADC_TypeDef;

在结构体里,寄存器个数以及排列顺序与实际的硬件上完全一致。结构体成员正好映射对应寄存器。

把ADC1的基地址ADC1_BASE强转为ADC_TypeDef结构体类型的指针,ADC1此时是ADC_TypeDef结构体的首地址,使用ADC1—>DR就能访问该寄存器。

结构体可以类比到数组,数组名array就是指针,array[0]就能访问array数组的第一个元素

结构体名在这里ADC1就是结构体名(经过强制类型转换)也是结构体首地址也是ADC1外设基地址,ADC1—>DR就能访问该寄存器。

&ADC1—>DR得到DR寄存器地址,等于4001244c

实际上上面的套娃等价于:

#define ADC1_DR   (uint_32 *)0x4001244c
//把0x4001244c强转为32位的int型指针也就是地址

*ADC1_DR访问寄存器
&*ADC1_DR得到DR寄存器地址

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值