C#中实现按位域操作

在C语言中按位域操作如下:

cs 复制代码
typedef struct {
FIELD GY_CDG_SL         : 4; /* 0.. 3,         0x0000000F */
FIELD GY_CDG_OFST         : 8; /* 4..11,         0x00000FF0 */
FIELD GY_CDG_RAT         : 5; /* 12..16,     0x0001F000 */
FIELD GY_CD_KNL         : 1; /* 17..17,     0x00020000 */
FIELD rsv_18             : 10; /* 18..28,     0x1FFC0000 */
FIELD GY_BIN_EO_SEL     : 1; /* 28..28,     0x1FFC0000 */
FIELD GY_BIN_MODE         : 1; /* 29..29,     0x20000000 */
FIELD GY_BYP             : 1; /* 30..30,     0x40000000 */
FIELD GY_MN_MODE         : 1; /* 31..31,     0x80000000 */
} AN_GY_INTP_CRS_T;


typedef union {
typedef AN_GY_INTP_CRS_T reg_t;
reg_t bits;
MUINT32 val;
} AN_NVRAM_GY_INTP_CRS_T;

即对一个MUINT32类型的数据按位域操作。

而在C#中是没有C语言这种语法格式的,故无法按照上面的格式进行位域操作。若是实现C#中的位域操作,具体方法如下:

cs 复制代码
#region AN_NVRAM_GY_INTP_CRS_T
[StructLayout(LayoutKind.Explicit, Size = 1 * 4)]
public struct AN_NVRAM_GY_INTP_CRS_T
{
    [FieldOffset(0)] public AN_GY_INTP_CRS_T bits;
    [FieldOffset(0)] public UInt32 val;
}

[StructLayout(LayoutKind.Sequential, Pack = 4)]

public struct AN_GY_INTP_CRS_T
{
    private UInt32 raw;
    //有两种方案可以实现set的功能,此处注释掉的属于第二种方案,没有注释掉的属于第一种方案;无论采用哪种方案其实质都是将要设置的数据匹配到具体的位域上,否则就会数据发生错乱,这一点尤其要注意;
    //特别要说明的是第二种方案在测试的时候还有些问题,需要后期优化;
    //第一种方案的设计思路是:由于所有要设定的值都是按照bit位分的,即要设定的值是32位Uint32中的某几个bit位,假设GY_CDG_SL要将原来的值6更改为13,该GY_CDG_SL占4位,十进制最大值为15,要设置的值不能超过max值,
    //若是GY_CDG_SL=13,即value值为13,若不按照bit将13对应到低4位上,则该Uint32对应的所有值都会发生改变,故设定某个值时要匹配到对应的bit上,且不能影响其他bit位上的值;
    //value是关键词,网上的参考示例也是这样使用的,使用value前要先将其转为Uint32类型,这里以GY_CDG_SL举例说明:第一步:先将对应的低4位bit变为0,其余bit位保持1,这样做的目的是保证不修改的bit位值不发生变化,修改哪几个bit位就
    //将哪几个bit位先置0,即"raw & 0xFFFFFFF0";第二步:将值左移到起始的bit位上,与其对应的bit位上的1进行"&"操作,其余bit位为0,这样做是保证要操作的bit位上的值就是要修改的值;第三步:将前两步进行"|"操作,这样就组成了一个新的
    //Uint32值,即修改的bit位为要修改的值,不修改的bit位值保持不变。
    //第一种方案
    public UInt32 GY_CDG_SL { get { return (UInt32)((raw >> 0) & 0xF); } set { raw = (UInt32)(raw & 0xFFFFFFF0 | ((UInt32)value << 0 & 0x0000000F)); } } //: 4; /* 0.. 3, 0x0000000F */
    public UInt32 GY_CDG_OFST { get { return (UInt32)((raw >> 4) & 0xFF); } set { raw = (UInt32)(raw & 0xFFFFF00F | ((UInt32)value << 4 & 0x00000FF0)); } } //: 8; /* 4..11, 0x00000FF0 */
    public UInt32 GY_CDG_RAT { get { return (UInt32)((raw >> 12) & 0x1F); } set { raw = (UInt32)(raw & 0xFFFE0FFF | ((UInt32)value << 12 & 0x0001F000)); } } //: 5; /* 12..16, 0x0001F000 */
    public UInt32 GY_CD_KNL { get { return (UInt32)((raw >> 17) & 0x1); } set { raw = (UInt32)(raw & 0xFFFDFFFF | ((UInt32)value << 17 & 0x00020000)); } } //: 1; /* 17..17, 0x00020000 */
    public UInt32 rsv_18 { get { return (UInt32)((raw >> 18) & 0x3FF); } set { raw = (UInt32)(raw & 0xE003FFFF | ((UInt32)value << 18 & 0x1FFC0000)); } } //: 10; /* 18..28, 0x1FFC0000 */
    public UInt32 GY_BIN_EO_SEL { get { return (UInt32)((raw >> 28) & 0x1); } set { raw = (UInt32)(raw & 0xEFFFFFFF | ((UInt32)value << 28 & 0x10000000)); } } //: 1; /* 28..28, 0x10000000 */
    public UInt32 GY_BIN_MODE { get { return (UInt32)((raw >> 29) & 0x1); } set { raw = (UInt32)(raw & 0xDFFFFFFF | ((UInt32)value << 29 & 0x20000000)); } } //: 1; /* 29..29, 0x20000000 */
    public UInt32 GY_BYP { get { return (UInt32)((raw >> 30) & 0x1); } set { raw = (UInt32)(raw & 0xBFFFFFFF | ((UInt32)value << 30 & 0x40000000)); } } //: 1; /* 30..30, 0x40000000 */
    public UInt32 GY_MN_MODE { get { return (UInt32)((raw >> 31) & 0x1); } set { raw = (UInt32)(raw & 0x7FFFFFFF | ((UInt32)value << 31 & 0x80000000)); } } //: 1; /* 31..31, 0x80000000 */
    
    //第二种方案
    //public UInt32 GY_CDG_SL { get { return (UInt32)((raw >> 0) & 0xF); } set { raw = (UInt32)(raw & ~(0xF << 0)) | (value & 0xF) << 0; } } //: 4; /* 0.. 3, 0x0000000F */
    //public UInt32 GY_CDG_OFST { get { return (UInt32)((raw >> 4) & 0xFF); } set { raw = (UInt32)(raw | ((raw & ~(0xFF << 4)) | (value & 0xFF) << 4)); } } //: 8; /* 4..11, 0x00000FF0 */
    //public UInt32 GY_CDG_RAT { get { return (UInt32)((raw >> 12) & 0x1F); } set { raw = (UInt32)(raw | ((raw & ~(0x1F << 12)) | (value & 0x1F) << 12)); } } //: 5; /* 12..16, 0x0001F000 */
    //public UInt32 GY_CD_KNL { get { return (UInt32)((raw >> 17) & 0x1); } set { raw = (UInt32)(raw | ((raw & ~(0x1 << 17)) | (value & 0x1) << 17)); } } //: 1; /* 17..17, 0x00020000 */
    //public UInt32 rsv_18 { get { return (UInt32)((raw >> 18) & 0x3FF); } set { raw = (UInt32)(raw | ((raw & ~ (0x3FF << 18)) | (value & 0x3FF) << 18)); } } //: 10; /* 18..28, 0x1FFC0000 */
    //public UInt32 GY_BIN_EO_SEL { get { return (UInt32)((raw >> 28) & 0x1); } set { raw = (UInt32)(raw | ((raw & ~(0x1 << 28)) | (value & 0x1) << 28)); } } //: 1; /* 28..28, 0x10000000 */
    //public UInt32 GY_BIN_MODE { get { return (UInt32)((raw >> 29) & 0x1); } set { raw = (UInt32)(raw | ((raw & ~(0x1 << 29)) | (value & 0x1) << 29)); } } //: 1; /* 29..29, 0x20000000 */
    //public UInt32 GY_BYP { get { return (UInt32)((raw >> 30) & 0x1); } set { raw = (UInt32)(raw | ((raw & ~ (0x1 << 30)) | (value & 0x1) << 30)); } } //: 1; /* 30..30, 0x40000000 */
    //public UInt32 GY_MN_MODE { get { return (UInt32)((raw >> 31) & 0x1); } set { raw = (UInt32)(raw | ((raw & ~(0x1 << 31)) | (value & 0x1) << 31)); } } //: 1; /* 31..31, 0x80000000 */
    public AN_GY_INTP_CRS_T(UInt32 VALUE)
    {
        raw = VALUE;
    }
}
#endregion
相关推荐
hanlin032 分钟前
刷题笔记:力扣第32题-最长有效括号
笔记·算法·leetcode
All for pursuit.23 分钟前
【动态规划-21】312.戳气球
数据结构·c++·算法·leetcode·动态规划
栈帧之外35 分钟前
【C++】STL之set
开发语言·c++
catchadmin1 小时前
免费可商用 PHP 管理后台 CatchAdmin V5.4.1 发布,新增 MCP 支持
开发语言·php
阿松爱学习2 小时前
【Unity开发】监听Scene场景事件
unity·c#
jimy13 小时前
c++的 Type Traits (二、更详细版本)
开发语言·c++
碧海银沙音频科技研究院3 小时前
基于炬芯ATS3089X自研AEC声学回声消除算法
算法
狗凯之家源码网3 小时前
纯 PHP+MySQL 应用市场系统源码实测!
开发语言·mysql·php
dishugj3 小时前
系统架构风险点、敏感点和权衡点的概念和区分
java·开发语言
通问AI3 小时前
在两台 Mac Studio 上跑 800B 模型:MLX + RDMA over Thunderbolt 实测与四道门选型法
算法