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
相关推荐
Am心若依旧4095 分钟前
[c++11(二)]Lambda表达式和Function包装器及bind函数
开发语言·c++
明月看潮生7 分钟前
青少年编程与数学 02-004 Go语言Web编程 20课题、单元测试
开发语言·青少年编程·单元测试·编程与数学·goweb
大G哥16 分钟前
java提高正则处理效率
java·开发语言
AC使者19 分钟前
#B1630. 数字走向4
算法
冠位观测者23 分钟前
【Leetcode 每日一题】2545. 根据第 K 场考试的分数排序
数据结构·算法·leetcode
VBA633727 分钟前
VBA技术资料MF243:利用第三方软件复制PDF数据到EXCEL
开发语言
轩辰~29 分钟前
网络协议入门
linux·服务器·开发语言·网络·arm开发·c++·网络协议
小_太_阳38 分钟前
Scala_【1】概述
开发语言·后端·scala·intellij-idea
向宇it38 分钟前
【从零开始入门unity游戏开发之——unity篇02】unity6基础入门——软件下载安装、Unity Hub配置、安装unity编辑器、许可证管理
开发语言·unity·c#·编辑器·游戏引擎
古希腊掌管学习的神1 小时前
[搜广推]王树森推荐系统笔记——曝光过滤 & Bloom Filter
算法·推荐算法