• STM32——HAL库中寄存器地址名称映射分析


    前言

    本篇文章是为了明白HAL 库中那些结构体是怎么与寄存器地址对应起来的。部分知识参考正点原子资料。

    一、HAL库中寄存器地址名称映射分析

    最根本的单片机开发就是直接操作寄存器的值,给这些位赋值,但是32单片机的寄存器太多,所以MDK就使用结构体将这些寄存器组织在一起。那么只要我们修改结构体的变量就可以修改对应寄存器的值。这些结构体的关联组织是在stm32f1xx.h 的头文件中完成的。
    每个寄存器的地址都是偏移过来的,以GPIO为例,它的基地址是由 APB2 总线的基地址+GPIOA 在 APB2 总线上的偏移地址决定的。同理依次类推,我们便可以算出 GPIOA 基地址。
    GIPO的结构体是根据GPIO的地址来定义的,GPIO的地址是从GPIO基地址偏移过来的,GPIO的基地址是从时钟线的基地址偏移过来的,时钟线的地址是由PERIPH基地址偏移的,如下所示:

    typedef struct 
    { 
    __IO uint32_t CRL; 
    __IO uint32_t CRH; 
    __IO uint32_t IDR; 
    __IO uint32_t ODR; 
    __IO uint32_t BSRR; 
    __IO uint32_t BRR; 
    __IO uint32_t LCKR; 
    } GPIO_TypeDef;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    我们跳转GPIOA的定义

    #define GPIOA ((GPIO_TypeDef *) GPIOA_BASE)
    
    • 1

    这个宏是将GPIOA的基地址强转为结构体指针,我们继续跳转GPIOA_BASE

    #define GPIOA_BASE (APB2PERIPH_BASE + 0x0800) 
    
    • 1

    这个宏是将APB2时钟线的地址偏移0x0800得到的GPIOA基地址,我们以此类推依次跳转

    #define APB2PERIPH_BASE (PERIPH_BASE + 0x10000) 
    #define PERIPH_BASE ((uint32_t)0x40000000)
    
    • 1
    • 2

    最后得到始终总线的基地址
    其他外设也是一样。

    二、计算寄存器地址

    计算寄存器的地址:(以GPIOA为例)
    GPIOA 的寄存器的地址=GPIOA 基地址+寄存器相对 GPIOA 基地址的偏移值
    这个偏移值在上面的寄存器地址映像表中可以查到。

    我们对应好第一个地址,结构体的地址是连续的,而GPIOA的类型是结构体指针,每个成员变量偏移0x04,寄存器地址映像顺序与结构体中的IO口的成员变量的顺序是一样的,加上偏移,那么结构体中的成员变量的地址都一一对应。

    后面关于MDK如何组织代码我们就不总结了,在这里简单说一下,对于变量、函数等我们选中右键GO TO DEFINED就可以跳转到定义处和引用处,然后根据定义范围来赋值或使用,其他的软件小妙招之后可以简单总结如debug、configuration等应用和配置。

  • 相关阅读:
    设计模式-装饰器模式
    GDB 调试错误解决
    逻辑运算与按位运算
    解决Apache Tomcat “Request header is too large“ 异常 ‍
    (9)点云数据处理学习——Global registration(全局注册)
    DC电源模块具有不同的安装方式和安全规范
    优思学院|六西格玛黑带的个人成功特质
    .Net开发的音频分离桌面应用,可用于提取背景音乐
    Facebook的预填问题默认可以设定哪些类型。
    软件版本控制系统VCS工具——cvs vss svn git
  • 原文地址:https://blog.csdn.net/whhcsdn233/article/details/134337994