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
相关推荐
hopetomorrow1 分钟前
学习路之PHP--使用GROUP BY 发生错误 SELECT list is not in GROUP BY clause .......... 解决
开发语言·学习·php
小牛itbull11 分钟前
ReactPress vs VuePress vs WordPress
开发语言·javascript·reactpress
广煜永不挂科19 分钟前
Devexpress.Dashboard的调用二义性
c#·express
请叫我欧皇i20 分钟前
html本地离线引入vant和vue2(详细步骤)
开发语言·前端·javascript
闲暇部落22 分钟前
‌Kotlin中的?.和!!主要区别
android·开发语言·kotlin
GIS瞧葩菜31 分钟前
局部修改3dtiles子模型的位置。
开发语言·javascript·ecmascript
chnming198736 分钟前
STL关联式容器之set
开发语言·c++
带多刺的玫瑰40 分钟前
Leecode刷题C语言之统计不是特殊数字的数字数量
java·c语言·算法
爱敲代码的憨仔41 分钟前
《线性代数的本质》
线性代数·算法·决策树
熬夜学编程的小王1 小时前
【C++篇】深度解析 C++ List 容器:底层设计与实现揭秘
开发语言·数据结构·c++·stl·list