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

本文介绍了C语言中如何利用位域节省内存,通过位段设置特定位,例如在SPI寄存器操作中,用1bit表示状态。同时讲解了枚举的使用,包括枚举常量的赋值和枚举变量的限制。枚举常量默认按0递增,且不能在定义后单独赋值。位域从bit0开始,按照顺序分配。
摘要由CSDN通过智能技术生成

位域(位段)
对于位域(位段)的使用可以节约内存的开支,使某些变量可以仅用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 */
//将仍是立即数的外设地址转换为结构体指针(相应外设地址)

写法一:

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;

写法二:

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;
};
.
.
.
//如上
//省略其他寄存器;

枚举用法

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

spiStatusVar = SpiIf;
spiStatusVar2 = SpiTxe;

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SUR0608

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值