按位操作外部设备的寄存器:方法一

来源:互联网 发布:ubuntu用户组权限设置 编辑:程序博客网 时间:2024/06/09 19:16

方法介绍:


利用联合体的特点:各union成员共享同一块大内存,对某一个成员赋值,会影响其它成员的值 。
为每一个寄存器逐个都定义一个union联合体变量,

每个联合体包括一个寄存器宽的byte/word变量,和一个根据寄存器内容按bits(1bit或多bit)定义的结构体变量。

例如某寄存器有有三组内容,定义如下:

typedef union {    unsigned char byte;    struct {        unsigned Value:6;        unsigned Control:1;        unsigned Status:1;       };} register_A;


读寄存器,整个寄存器读取、内容保存到byte/word变量,可以根据bit/bits使用读取的寄存器值,
写寄存器,先更新bit/bits变量,然后按整个byte/word变量写入寄存器。

注:常见外设寄存器是8bit / 16bit。


方法特点:


利用联合体思想,实现简单易懂。


适用场景:


寄存器较少。否则寄存器过多,定义联合体就累了。


使用举例:


1、定义联合体寄存器:

按byte/word定义一寄存器变量, 按bit/bits定义定义寄存器变量,形成联合体。

typedef union {
FSC_U8 byte;
struct {
unsigned REVISION_ID:2;
unsigned PRODUCT_ID:2;
unsigned VERSION_ID:4;
};
} regDeviceID_t;


typedef union {
FSC_U16 word;
FSC_U8 byte[2] __PACKED;
struct {
// Switches0
unsigned PDWN1:1;
unsigned PDWN2:1;
unsigned MEAS_CC1:1;
unsigned MEAS_CC2:1;
unsigned VCONN_CC1:1;
unsigned VCONN_CC2:1;
unsigned PU_EN1:1;
unsigned PU_EN2:1;
// Switches1
unsigned TXCC1:1;
unsigned TXCC2:1;
unsigned AUTO_CRC:1;
unsigned:1;
unsigned DATAROLE:1;
unsigned SPECREV:2;
unsigned POWERROLE:1;
};
} regSwitches_t;


typedef union {
FSC_U8 byte;
struct {
unsigned MDAC:6;
unsigned MEAS_VBUS:1;
unsigned:1;
};
} regMeasure_t;


typedef union {
FSC_U8 byte;
struct {
unsigned SDAC:6;
unsigned SDAC_HYS:2;
};
} regSlice_t;


typedef union {
FSC_U32 dword;
FSC_U8 byte[4] __PACKED;
struct {
// Control0
unsigned TX_START:1;
unsigned AUTO_PRE:1;
unsigned HOST_CUR:2;
unsigned LOOPBACK:1;
unsigned INT_MASK:1;
unsigned TX_FLUSH:1;
unsigned:1;
// Control1
unsigned ENSOP1:1;
unsigned ENSOP2:1;
unsigned RX_FLUSH:1;
unsigned:1;
unsigned BIST_MODE2:1;
unsigned ENSOP1DP:1;
unsigned ENSOP2DB:1;
unsigned:1;
// Control2
unsigned TOGGLE:1;
unsigned MODE:2;
unsigned WAKE_EN:1;
unsigned WAKE_SELF:1;
unsigned TOG_RD_ONLY:1;
unsigned:2;
// Control3
unsigned AUTO_RETRY:1;
unsigned N_RETRIES:2;
unsigned AUTO_SOFTRESET:1;
unsigned AUTO_HARDRESET:1;
unsigned BIST_TMODE:1;// 302B Only
unsigned SEND_HARDRESET:1;
unsigned:1;
};
} regControl_t;


typedef union {
FSC_U8 byte;
struct {
unsigned M_BC_LVL:1;
unsigned M_COLLISION:1;
unsigned M_WAKE:1;
unsigned M_ALERT:1;
unsigned M_CRC_CHK:1;
unsigned M_COMP_CHNG:1;
unsigned M_ACTIVITY:1;
unsigned M_VBUSOK:1;
};
} regMask_t;


typedef union {
FSC_U8 byte;
struct {
unsigned PWR:4;
unsigned PD_RCVR_DIS:1;
unsigned:3;
};
} regPower_t;


typedef union {
FSC_U8 byte;
struct {
unsigned SW_RES:1;
unsigned:7;
};
} regReset_t;


typedef union {
FSC_U8 byte;
struct {
unsigned OCP_CUR:3;
unsigned OCP_RANGE:1;
unsigned:4;
};
} regOCPreg_t;


typedef union {
FSC_U16 word;
FSC_U8 byte[2] __PACKED;
struct {
// Maska
unsigned M_HARDRST:1;
unsigned M_SOFTRST:1;
unsigned M_TXSENT:1;
unsigned M_HARDSENT:1;
unsigned M_RETRYFAIL:1;
unsigned M_SOFTFAIL:1;
unsigned M_TOGDONE:1;
unsigned M_OCP_TEMP:1;
// Maskb
unsigned M_GCRCSENT:1;
unsigned:7;
};
} regMaskAdv_t;


typedef union {
FSC_U8 byte;
struct {
unsigned TOG_USRC_EXIT:1;
unsigned:7;
};
} regControl4_t;


typedef union {
FSC_U8 byte[7] __PACKED;
struct {
FSC_U16 StatusAdv;
FSC_U16 InterruptAdv;
FSC_U16 Status;
FSC_U8 Interrupt1;
};
struct {
// Status0a
unsigned HARDRST:1;
unsigned SOFTRST:1;
unsigned POWER23:2;
unsigned RETRYFAIL:1;
unsigned SOFTFAIL:1;
unsigned TOGDONE:1;
unsigned M_OCP_TEMP:1;
// Status1a
unsigned RXSOP:1;
unsigned RXSOP1DB:1;
unsigned RXSOP2DB:1;
unsigned TOGSS:3;
unsigned:2;
// Interrupta
unsigned I_HARDRST:1;
unsigned I_SOFTRST:1;
unsigned I_TXSENT:1;
unsigned I_HARDSENT:1;
unsigned I_RETRYFAIL:1;
unsigned I_SOFTFAIL:1;
unsigned I_TOGDONE:1;
unsigned I_OCP_TEMP:1;
// Interruptb
unsigned I_GCRCSENT:1;
unsigned:7;
// Status0
unsigned BC_LVL:2;
unsigned WAKE:1;
unsigned ALERT:1;
unsigned CRC_CHK:1;
unsigned COMP:1;
unsigned ACTIVITY:1;
unsigned VBUSOK:1;
// Status1
unsigned OCP:1;
unsigned OVRTEMP:1;
unsigned TX_FULL:1;
unsigned TX_EMPTY:1;
unsigned RX_FULL:1;
unsigned RX_EMPTY:1;
unsigned RXSOP1:1;
unsigned RXSOP2:1;
// Interrupt
unsigned I_BC_LVL:1;
unsigned I_COLLISION:1;
unsigned I_WAKE:1;
unsigned I_ALERT:1;
unsigned I_CRC_CHK:1;
unsigned I_COMP_CHNG:1;
unsigned I_ACTIVITY:1;
unsigned I_VBUSOK:1;
};
} regStatus_t;


typedef struct {
regDeviceID_t DeviceID;
regSwitches_t Switches;
regMeasure_t Measure;
regSlice_t Slice;
regControl_t Control;
regMask_t Mask;
regPower_t Power;
regReset_t Reset;
regOCPreg_t OCPreg;
regMaskAdv_t MaskAdv;
regControl4_t Control4;
regStatus_t Status;
} DeviceReg_t;


2、初始化寄存器

从chip读取,或设置默认初始值

void InitializeRegisters(void)
{
    DeviceRead(regDeviceID, 1, &Registers.DeviceID.byte);
    DeviceRead(regSwitches0, 1, &Registers.Switches.byte[0]);
    DeviceRead(regSwitches1, 1, &Registers.Switches.byte[1]);
    DeviceRead(regMeasure, 1, &Registers.Measure.byte);
    DeviceRead(regSlice, 1, &Registers.Slice.byte);
    DeviceRead(regControl0, 1, &Registers.Control.byte[0]);
    DeviceRead(regControl1, 1, &Registers.Control.byte[1]);
    DeviceRead(regControl2, 1, &Registers.Control.byte[2]);
    DeviceRead(regControl3, 1, &Registers.Control.byte[3]);
    DeviceRead(regMask, 1, &Registers.Mask.byte);
    DeviceRead(regPower, 1, &Registers.Power.byte);
    DeviceRead(regReset, 1, &Registers.Reset.byte);
    DeviceRead(regOCPreg, 1, &Registers.OCPreg.byte);
    DeviceRead(regMaska, 1, &Registers.MaskAdv.byte[0]);
    DeviceRead(regMaskb, 1, &Registers.MaskAdv.byte[1]);
    DeviceRead(regStatus0a, 1, &Registers.Status.byte[0]);
    DeviceRead(regStatus1a, 1, &Registers.Status.byte[1]);
    DeviceRead(regInterrupta, 1, &Registers.Status.byte[2]);
    DeviceRead(regInterruptb, 1, &Registers.Status.byte[3]);
    DeviceRead(regStatus0, 1, &Registers.Status.byte[4]);
    DeviceRead(regStatus1, 1, &Registers.Status.byte[5]);
    DeviceRead(regInterrupt, 1, &Registers.Status.byte[6]);
}


3、操作寄存器

    修改整个寄存器或寄存器某bit/bits值 ,写入chip

    Registers.Mask.byte = 0xFF; // Mask all before global unmask
    DeviceWrite(regMask, 1, &Registers.Mask.byte);
    Registers.MaskAdv.byte[0] = 0xFF;
    DeviceWrite(regMaska, 1, &Registers.MaskAdv.byte[0]);
    Registers.MaskAdv.M_GCRCSENT = 1;
    DeviceWrite(regMaskb, 1, &Registers.MaskAdv.byte[1]);


    Registers.Control.INT_MASK = 0; // Enable interrupt Pin
    DeviceWrite(regControl0, 1, &Registers.Control.byte[0]);


    Registers.Control.TOG_RD_ONLY = 1; // Do not stop toggle for Ra
    DeviceWrite(regControl2, 1, &Registers.Control.byte[2]);

原创粉丝点击