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
相关推荐
至暗时刻darkest几秒前
go mod文件 项目版本管理
开发语言·后端·golang
小码编匠4 分钟前
WinForm 中也可以这样做数据展示
windows·后端·c#
sakoba26 分钟前
spring IOC(实现原理)
java·开发语言
MZWeiei27 分钟前
Scala:在哪里写类的属性?类的属性必须私有吗?类的必须初始化吗?
开发语言·scala
闯闯桑28 分钟前
Scala 中的访问修饰符
大数据·开发语言·scala
我不是代码教父28 分钟前
[原创](Modern C++)现代C++的关键性概念: 非常独特的std::sentinel_for概念(哨兵概念)
开发语言·c++·sentinel
不爱学习的小枫33 分钟前
scala函数的至简原则
开发语言·scala
commonbelive43 分钟前
考研机试常见基本题型
c语言·c++·算法
YGGP1 小时前
【每日八股】Golang篇(二):关键字(上)
开发语言·后端·golang
꧁坚持很酷꧂1 小时前
QT登录系统界面
开发语言·qt