• 位域(位段)/枚举常量用法官方库例程


    位域(位段)
    对于位域(位段)的使用可以节约内存的开支,使某些变量可以仅用1bit位来区分和表示;参考华大官方库的代码来解释;
    【示例】实现如下两行代码:
    M0P_SPI0->CR_f.SPEN = 1;
    M0P_SPI0->CR = 0x00000080;
    //仅对spen位置1,在32位寄存器中位于bit7,以上两行作用等价;

    #define M0P_GPIO_BASE                          (M0P_PERIPH_BASE + 0x00020C00UL)
    #define M0P_SPI0_BASE                          (M0P_PERIPH_BASE + 0x00000800UL)
    #define M0P_SPI1_BASE                          (M0P_PERIPH_BASE + 0x00004800UL)
    .
    .
    .
    #define M0P_GPIO                               ((M0P_GPIO_TypeDef *)0x40020C00UL)
    #define M0P_SPI0                               ((M0P_SPI_TypeDef *)0x40000800UL)
    #define M0P_SPI1                               ((M0P_SPI_TypeDef *)0x40004800UL)
    
    #define     __IO    volatile             /*!< Defines 'read / write' permissions */
    //将仍是立即数的外设地址转换为结构体指针(相应外设地址)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    写法一:

    typedef struct
    {
        union
        {
            __IO uint32_t CR;    //32bit
            stc_spi_cr_field_t CR_f;   //32bit
        };
        union
        {
            __IO uint32_t SSN;
            stc_spi_ssn_field_t SSN_f;
        };
        union
        {
            __IO uint32_t STAT;
            stc_spi_stat_field_t STAT_f;
        };
        union
        {
            __IO uint32_t DATA;
            stc_spi_data_field_t DATA_f;
        };
        union
        {
            __IO uint32_t CR2;
            stc_spi_cr2_field_t CR2_f;
        };
        union
        {
            __IO uint32_t ICLR;
            stc_spi_iclr_field_t ICLR_f;
        };
    }M0P_SPI_TypeDef;
    
    typedef struct
    {
        __IO uint32_t SPR0                      : 1;
        __IO uint32_t SPR1                      : 1;
        __IO uint32_t CPHA                      : 1;
        __IO uint32_t CPOL                      : 1;
        __IO uint32_t MSTR                      : 1;
        uint32_t RESERVED5                      : 1;
        __IO uint32_t SPEN                      : 1;
        __IO uint32_t SPR2                      : 1;
        uint32_t RESERVED8                      :23;
        __IO uint32_t RSV                       : 1;
    } stc_spi_cr_field_t;
    
    • 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
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47

    写法二:

    typedef struct
    {
    	   __IO uint32_t CR;
    	   __IO uint32_t SSN;
    	   __IO uint32_t STAT;
    	   __IO uint32_t DATA;
    	   __IO uint32_t CR2;
    	   __IO uint32_t ICLR;
    }M0P_SPI_TypeDef;
    
    union
    {
       __IO uint32_t CR;
       stc_spi_cr_field_t CR_f;
    };
    .
    .
    .
    //如上
    //省略其他寄存器;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    枚举用法

    typedef enum en_spi_status
    {
        SpiIf              = 0x80u,   ///<传输结束中断标志       
        SpiSserr           = 0x20u,   ///<从机模式错误标志    
        SpiMdf             = 0x10u,   ///<主机模式错误标志 
        SpiBusy            = 0x08u,   ///
        SpiTxe             = 0x04u,   ///<发送缓冲器器空标志
        SpiRxne            = 0x02u,   ///<接受缓冲器非空标志
    }en_spi_status_t; 
    
    en_spi_status_t   spiStatusVar = SpiIf;
    
    //或
    enum en_spi_status
    {
        SpiIf              = 0x80u,   ///<传输结束中断标志       
        SpiSserr           = 0x20u,   ///<从机模式错误标志    
        SpiMdf             = 0x10u,   ///<主机模式错误标志 
        SpiBusy            = 0x08u,   ///
        SpiTxe             = 0x04u,   ///<发送缓冲器器空标志
        SpiRxne            = 0x02u,   ///<接受缓冲器非空标志
    }spiStatusVar,spiStatusVar2;
    
    spiStatusVar = SpiIf;
    spiStatusVar2 = SpiTxe;
    
    • 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

    1、枚举元素SpiIf(枚举常量)等只能在定义的时候赋值,不能单独拿出来赋值;
    2、枚举元素不赋值时,编译器默认自动设为0,1,2…,枚举变量spiStatusVar的值仅限于花括号里的;
    【注意】而结构体中各元素成员,如未被初始化的数值型被系统初始化为0,;字符型被系统初始化为‘/0’;指针型成员被系统初始化为NULL;
    3、枚举名字en_spi_status可以不声明;
    enum
    {
    SpiIf = 0x80u, ///<传输结束中断标志
    SpiSserr = 0x20u, ///<从机模式错误标志
    SpiMdf = 0x10u, ///<主机模式错误标志
    SpiBusy = 0x08u, /// SpiTxe = 0x04u, ///<发送缓冲器器空标志
    SpiRxne = 0x02u, ///<接受缓冲器非空标志
    }spiStatusVar,spiStatusVar2;

    4、C语言结构体定义位域,从bit0开始,依次到最高bit位
    【ref】https://www.cnblogs.com/risunlee/p/11507103.html

  • 相关阅读:
    网盟广告定位条件以及所需素材
    elasticsearch创建索引和mapping
    java面试题-设计模式基础
    「动态规划」如何求乘积最大子数组?
    Java8特性-Lambda表达式
    Vue3中diff算法的优化和乱序比对的实现-详细步骤(包看包会)
    看门狗定时器
    JavaSE进阶21天---第二十天---JavaSE(​​日志、logback日志、添加模板、类加载器、ressources文件夹)
    渗透测试之Web安全系列教程(二)
    torch.nn.functional
  • 原文地址:https://blog.csdn.net/SUR0608/article/details/127835086