IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    C 的结构体成员在内存中的存储顺序以及对硬件的描述能力

    Hacper\'s Blog发表于 2023-07-19 00:05:17
    love 0

    c 语言结构体成员和位域在内存中的存储方式

    在小端存储的机器上,C编译器对结构体的成员按它们的声明顺序从低到高的地址进行存储,先定义的成员存储在内存的低地址,使用位域的时候也是类似,先定义的成员先占用低比特位。

    c 语言怎么描述硬件寄存器?

    通常硬件寄存器会映射到一段特定的内存地址,我们可以通过指针来访问和修改寄存器的内容。每个寄存器的功能不一定相同,需要根据硬件手册来具体定义。下面以某个芯片平台的 pwm 控制寄存器为例,说明如何使用 c 语言描述硬件寄存器。

    这个平台有 4 个 pwm 外设,控制寄存器的基址分别是 0xD401A000,0xD401A400,0xD401A800 ,0xD401AC00,然后每个 pwm 有三个 32 位 的寄存器,分别是 PWM_CRx,PWM_DCR,PWM_PCR。在这三个寄存器里面,不同的 bit 范围之间又控制着不同的功能。在 c 语言里面,可通过联合体、结构体和位域来定义这些寄存器的功能。

    三个 pwm 控制寄存器的基地址:

    1
    2
    3
    4
    5
    
    #include <stdint.h>
    #define  PWM0_BASE (0xD401A000)
    #define  PWM1_BASE (0xD401A400)
    #define  PWM2_BASE (0xD401A800)
    #define  PWM3_BASE (0xD401AC00)
    

    每个 pwm 有三个寄存器, PWM_CRx,PWM_DCR,PWM_PCR,与偏移地址对应,4字节递增:

    1
    2
    3
    4
    5
    6
    
    typedef volatile struct 
    {
        uint32_t PWM_CRx;   /*Offset: 0x00*/
        uint32_t PWM_DCR ;  /*Offset: 0x04*/
        uint32_t PWM_PCR ;  /*Offset: 0x08*/
    }PWM_HW_T;
    

    将 pwm 寄存器地址转换为 PWM_HW_T * 类型的指针,方便通过指针对数据进行读写:

    1
    2
    3
    4
    
    #define HW_PWM0 ((PWM_HW_T *)(PWM0_BASE))
    #define HW_PWM1 ((PWM_HW_T *)(PWM1_BASE))
    #define HW_PWM2 ((PWM_HW_T *)(PWM2_BASE))
    #define HW_PWM3 ((PWM_HW_T *)(PWM3_BASE))
    

    每个寄存器的功能定义:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    
    // PWM_CRx 寄存器定义
    typedef union 
    {
        uint32_t v;
        struct 
        {
            uint32_t PRESCALE : 6;  //[5:0]
            uint32_t SD : 1;        //[6]
            uint32_t Reserved :25;  //[31:7]
        }d;
    }REG_PWM_CRx_T;
    
    // PWM_DCR 寄存器定义
    typedef union 
    {
        uint32_t v;
        struct 
        {
            uint32_t DCYCLE : 10;   //[9:0]
            uint32_t FD :1;         //[10]
            uint32_t Reserved :21;  //[31:11]
        }d;
    }REG_PWM_DCR_T;
    
    // PWM_PCR 寄存器定义
    typedef union 
    {
        uint32_t v;
        struct 
        {
            uint32_t PV : 10;     	//[9:0]
            uint32_t Reserved :22;  //[31:10]
        }d;
    }REG_PWM_PCR_T;
    

    操作 pwm 寄存器示例,读和写寄存器都可以通过指针操作实现:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    
    void PWM0_Init(void)
    {
        PWM_HW_T *PWM = HW_PWM0;
        REG_PWM_CRx_T PWM_CRx = {0};
        REG_PWM_DCR_T PWM_DCR = {0};
        REG_PWM_PCR_T PWM_PCR = {0};
    
    
        PWM_CRx.d.PRESCALE = 0x3F;
        PWM_CRx.d.SD = 0;
        PWM_CRx.d.Reserved = 0;
        // 写  pwm0 的 PWM_CRx 寄存器
        PWM->PWM_CRx = PWM_CRx.v;
    	
        // 读 pwm0 的 PWM_DCR 寄存器
        PWM_DCR.v = PWM->PWM_DCR;
    
        PWM_PCR.d.PV = 0x3FF;
        PWM_PCR.d.Reserved = 0;
        PWM->PWM_PCR = PWM_PCR.v; 
    }
    


沪ICP备19023445号-2号
友情链接