UWB项目(分布式测距网络)之UWM1000基础应用

1、DW1000简介

        DWM1000 芯片是 Decawave 公司设计的超宽带收发模组,其自成收发系统,通过SPI接口与外界系统通信。用于TDOA定位系统中,测距精度可达10cm,最高6.8Mbps的数据传输率。其具有如下参数:

        1、具有 3.5GHz 6.5GHz的   4 个射频波段,可参数选择;
        2、发生端信号功率可编程控制;
        3、数据传输率有三种,为 110kbps,850kbps,6.8Mbps;

 2、DW1000测距帧

测距过程:模块A发起poll帧,模块B回复resp帧,最后模块A发送final帧。最后距离计算在模块B中。

static uint8 rx_poll_msg[] = {0x41, 0x88, 0, 0xCA, 0xDE, 'W', 'A', 'V', 'E', 0x21, 0, 0};
static uint8 tx_resp_msg[] = {0x41, 0x88, 0, 0xCA, 0xDE, 'V', 'E', 'W', 'A', 0x10, 0x02, 0, 0, 0, 0};
static uint8 rx_final_msg[] = {0x41, 0x88, 0, 0xCA, 0xDE, 'W', 'A', 'V', 'E', 0x23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};

1、DW1000传输数据

        DW1000芯片定义了规范的通信数据帧格式,不是用户想怎么定义就怎么定义的。如果没有按照规范进行数据发送,就会出现传输数据不是自己期望的情况。数据帧格式如下:

 因此,如果想要正确传输数据,需要按照上表定义通信报文数组。

首先是2个字节的Frame Control帧——用于帧过滤、通信组网、地址设置;

接下来1个字节的Sequence Number帧——帧序列号,每帧数据DW1000会自动增加1;

接下来2个字节的PAN ID帧——用于通信组网

接下来2个字节的Destination Address帧——用于帧过滤,目的地址

接下来2个字节的Source Address帧——用于帧过滤,源地址

接下来多个字节的Ranging Message帧——这里才是我们用户可以自行添加和定义的数据位置

最后的2个字节的FCS帧——用于数据校验,DW1000芯片会自动添加校验值,所以我们留空即可,设为0,0

1.1 发送帧过滤的数据

假如节点A(0x0)需要发送数据:0x01,0x02,0x03,0x04,0x05,0x06给节点B(0x1)。

可以这样定义数据:0x88,0x41,0x0,0x59,0x68,0x01,0x0,0x01,0x02,0x03,0x04,0x05,0x06,0x0,0x0

1、DW1000需要配置的参数

typedef struct
{
    uint8 chan ;           //!< channel number {1, 2, 3, 4, 5, 7 }
    uint8 prf ;            //!< Pulse Repetition Frequency {DWT_PRF_16M or DWT_PRF_64M}
    uint8 txPreambLength ; //!< DWT_PLEN_64..DWT_PLEN_4096
    uint8 rxPAC ;          //!< Acquisition Chunk Size (Relates to RX preamble length)
    uint8 txCode ;         //!< TX preamble code
    uint8 rxCode ;         //!< RX preamble code
    uint8 nsSFD ;          //!< Boolean should we use non-standard SFD for better performance
    uint8 dataRate ;       //!< Data Rate {DWT_BR_110K, DWT_BR_850K or DWT_BR_6M8}
    uint8 phrMode ;        //!< PHR mode {0x0 - standard DWT_PHRMODE_STD, 0x3 - extended frames DWT_PHRMODE_EXT}
    uint16 sfdTO ;         //!< SFD timeout value (in symbols)
} dwt_config_t ;

2、帧过滤模式

1.发送消息

//发送消息数组
static uint8 tx_msg[] = {0xC5, 0, 'D', 'E', 'C', 'A', 'W', 'A', 'V', 'E', 0, 0};
#define BLINK_FRAME_SN_IDX 1//帧数索引
#define TX_DELAY_MS 1000//休眠时间,单位ms

//main函数内
//第一步:传入数据,开始发送
dwt_writetxdata(sizeof(tx_msg), tx_msg, 0);//将需要发送的数据写入dwm1000芯片的内存,从偏移位置0开始
dwt_writetxfctrl(sizeof(tx_msg), 0);//确认发送数据参数
dwt_starttx(DWT_START_TX_IMMEDIATE);//开启发送(立即发送)

//第二步:等待发送完成
while (!(dwt_read32bitreg(SYS_STATUS_ID) & SYS_STATUS_TXFRS))
{ };

//第三步:清空发送标志
dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_TXFRS);

//第四步:下次发送前休眠
deca_sleep(TX_DELAY_MS);

//第五步:帧数自增
tx_msg[BLINK_FRAME_SN_IDX]++;

//函数功能:向外发送数据
void SendData(uint8_t data[])
{
    //print_Message("in SendData!!!\r\n");
    tx_status = TX_WAIT;
    //第一步:传入数据,开始发送
    dwt_writetxdata(sizeof(data), data, 0);        //将需要发送的数据写入dwm1000芯片的内存,从偏移位置0开始
    dwt_writetxfctrl(sizeof(data), 0, 1);          //确认发送数据参数
    int ret = dwt_starttx(DWT_START_TX_IMMEDIATE); //开启发送(立即发送)
    HAL_IWDG_Refresh(&hiwdg);                      //喂狗。不要自动重启,告警后让人工重启
    if (ret == DWT_ERROR)
    {
        //发送失败,打印失败信息
        print_Message("send data error!\r\n");
        //第三步:清空发送标志
        dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_RXFCG | SYS_STATUS_TXFRS);
        //灯光示警
        while (1)
        {
            HAL_IWDG_Refresh(&hiwdg); //喂狗。不要自动重启,告警后让人工重启
            print_Message("please reboot device!!!\r\n");
            led_on(LED_ALL);
            HAL_Delay(200); //ms延时
            led_off(LED_ALL);
        }
    }

    //第二步:等待发送完成
    while (!tx_status)
    {
        HAL_IWDG_Refresh(&hiwdg); //喂狗
    };
    print_Message("send data success!\r\n");

    HAL_IWDG_Refresh(&hiwdg); //喂狗
    //第三步:清空发送标志
    dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_RXFCG | SYS_STATUS_TXFRS);
}

2.芯片手动休眠

#define DUMMY_BUFFER_LEN 600
static uint8 dummy_buffer[DUMMY_BUFFER_LEN];

main函数:
//先唤醒DWM1000芯片,防止芯片在休眠
dwt_spicswakeup(dummy_buffer, DUMMY_BUFFER_LEN);

//配置休眠和唤醒参数
dwt_configuresleep(DWT_PRESRV_SLEEP | DWT_CONFIG, DWT_WAKE_CS | DWT_SLP_EN);

//芯片进入休眠
dwt_entersleep();

//唤醒DWM1000芯片
dwt_spicswakeup(dummy_buffer, DUMMY_BUFFER_LEN);

3.芯片自动休眠

#define DUMMY_BUFFER_LEN 600
static uint8 dummy_buffer[DUMMY_BUFFER_LEN];

main函数:
//先唤醒DWM1000芯片,防止芯片在休眠
dwt_spicswakeup(dummy_buffer, DUMMY_BUFFER_LEN);

//配置休眠和唤醒参数
dwt_configuresleep(DWT_PRESRV_SLEEP | DWT_CONFIG, DWT_WAKE_CS | DWT_SLP_EN);

//发送一帧数据后自动进入休眠
dwt_entersleepaftertx(1);

//单片机延时等待下一次发送
deca_sleep(TX_DELAY_MS);

//唤醒DWM1000芯片
dwt_spicswakeup(dummy_buffer, DUMMY_BUFFER_LEN);

4.接收消息

#define FRAME_LEN_MAX 127
static uint8 rx_buffer[FRAME_LEN_MAX];

main函数:

//步骤1:初始化接收数组
int i;
for (i = 0 ; i < FRAME_LEN_MAX; i++ )
{
    rx_buffer[i] = 0;
}

//开启芯片接收
dwt_rxenable(0);

//等待接收到数据或者错误、超时发生
while (!((status_reg = dwt_read32bitreg(SYS_STATUS_ID)) & (SYS_STATUS_RXFCG | SYS_STATUS_ALL_RX_ERR)))
{ };

//如果接收到数据成功
if (status_reg & SYS_STATUS_RXFCG)
{
    //将接收到的数据拷贝到单片机中
    frame_len = dwt_read32bitreg(RX_FINFO_ID) & RX_FINFO_RXFL_MASK_1023;
    if (frame_len <= FRAME_LEN_MAX)
    {
        dwt_readrxdata(rx_buffer, frame_len, 0);//从芯片读取接收数据,从偏移地址0开始
    }

    //清空芯片寄存器的接收数据标志
    dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_RXFCG);
}
else
{
    //清空芯片寄存器的接收错误标志
    dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_ALL_RX_ERR);
}

//函数功能:转为监听状态
void ListenData(void)
{
    //步骤1:初始化接收数组
    int i, status_reg, frame_len;
    for (i = 0; i < FRAME_LEN_MAX; i++)
    {
        rx_buffer[i] = 0;
    }

    HAL_IWDG_Refresh(&hiwdg);                       //喂狗
    dwt_setrxtimeout(inst_resp_rx_timeout);         //设置接收超时时间,不设置一直在接收状态,都发送不了数据
    int ret = dwt_rxenable(DWT_START_RX_IMMEDIATE); //开启接收机接收
    if (ret == DWT_ERROR)
    {
        print_Message("recv 001\r\n"); //打印系统参数信息
        //接收机开启失败,打印失败信息
        print_Message("Recv Open error!\r\n");
        //清空芯片寄存器的接收数据标志
        dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_RXFCG | SYS_STATUS_TXFRS);
        //清空芯片寄存器的接收错误标志
        dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_ALL_RX_ERR);
    }
    HAL_IWDG_Refresh(&hiwdg); //喂狗
}

5.发送后延迟一段时间开启接收

//延迟开启时间,单位:1 uus is 512/499.2 ms
#define TX_TO_RX_DELAY_UUS 60

//超时时间,单位:1 uus is 512/499.2 ms
#define RX_RESP_TO_UUS 5000


main函数:
//在帧输出完成后延迟一段时间开启接收
dwt_setrxaftertxdelay(TX_TO_RX_DELAY_UUS);

//设置回复帧超时
dwt_setrxtimeout(RX_RESP_TO_UUS);

6.接收数据后回复

#define FRAME_LEN_MAX 127
static uint8 rx_buffer[FRAME_LEN_MAX];
static uint8 tx_msg[] = {0x41, 0x8C, 0, 0x9A, 0x60, 0, 0, 0, 0, 0, 0, 0, 0, 'D', 'W', 0x10, 0x00, 0, 0, 0, 0};
#define DATA_FRAME_SN_IDX 2
#define DATA_FRAME_DEST_IDX 5
#define BLINK_FRAME_SRC_IDX 2

//延迟开启时间,单位:1 uus is 512/499.2 ms
#define TX_TO_RX_DELAY_UUS 60
//超时时间,单位:1 uus is 512/499.2 ms
#define RX_RESP_TO_UUS 5000


main函数:
//条件符合情况,回复数据
if ((frame_len == 14) && (rx_buffer[0] == 0xC5) && (rx_buffer[10] == 0x43) && (rx_buffer[11] == 0x2))
{
    int i;

    //发送数据初始化,把收到的数据链接到发送数据中
    for (i = 0; i < 8; i++)
    {
        tx_msg[DATA_FRAME_DEST_IDX + i] = rx_buffer[BLINK_FRAME_SRC_IDX + i];
    }

    //发送数据
    dwt_writetxdata(sizeof(tx_msg), tx_msg, 0);
    dwt_writetxfctrl(sizeof(tx_msg), 0);
    dwt_starttx(DWT_START_TX_IMMEDIATE);

    //等待发送完成
    while (!(dwt_read32bitreg(SYS_STATUS_ID) & SYS_STATUS_TXFRS))
    { };

    //清空发送标志
    dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_TXFRS);
    tx_msg[DATA_FRAME_SN_IDX]++;
}

7.发送连续波

static dwt_txconfig_t txconfig = {
    0xC0,            /* PG delay. */
    0x25456585,      /* TX power. */
};

main函数:
dwt_configuretxrf(&txconfig);
//启动连续波模式
dwt_configcwmode(config.chan);
//延时一段时间
deca_sleep(CONT_WAVE_DURATION_MS);
//软件重启
dwt_softreset();

8.连续帧发送

//帧与帧之间的时延,单位8ns
#define CONT_FRAME_PERIOD 124800
static dwt_txconfig_t txconfig = {
    0xC0,            /* PG delay. */
    0x25456585,      /* TX power. */
};

main函数:
//设置发射模式
dwt_configuretxrf(&txconfig);
//启动连续帧模式
dwt_configcontinuousframemode(CONT_FRAME_PERIOD);

//发送数据,然后延迟一段时间
//软件重启
dwt_softreset();

9.twr标签:测距

#define POLL_TX_TO_RESP_RX_DLY_UUS 150
#define RESP_RX_TIMEOUT_UUS 2700

static uint8 tx_poll_msg[] = {0x41, 0x88, 0, 0xCA, 0xDE, 'W', 'A', 'V', 'E', 0x21, 0, 0};
static uint8 rx_resp_msg[] = {0x41, 0x88, 0, 0xCA, 0xDE, 'V', 'E', 'W', 'A', 0x10, 0x02, 0, 0, 0, 0};
static uint8 tx_final_msg[] = {0x41, 0x88, 0, 0xCA, 0xDE, 'W', 'A', 'V', 'E', 0x23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};

#define ALL_MSG_SN_IDX 2
static uint8 frame_seq_nb = 0;

typedef unsigned long long uint64;
static uint64 poll_tx_ts;
static uint64 resp_rx_ts;
static uint64 final_tx_ts;

#define FINAL_MSG_POLL_TX_TS_IDX 10
#define FINAL_MSG_RESP_RX_TS_IDX 14
#define FINAL_MSG_FINAL_TX_TS_IDX 18

main函数:
//设置发送和接收后的天线到事件的延迟
dwt_setrxantennadelay(RX_ANT_DLY);
dwt_settxantennadelay(TX_ANT_DLY);

//设置发送后延迟一段时间开启接收
dwt_setrxaftertxdelay(POLL_TX_TO_RESP_RX_DLY_UUS);
//设置接收超时时间
dwt_setrxtimeout(RESP_RX_TIMEOUT_UUS);

tx_poll_msg[ALL_MSG_SN_IDX] = frame_seq_nb;
//发送数据tx_poll_msg
//发送后期待回复
dwt_starttx(DWT_START_TX_IMMEDIATE | DWT_RESPONSE_EXPECTED);

//等待接收数据
while (!((status_reg = dwt_read32bitreg(SYS_STATUS_ID)) & (SYS_STATUS_RXFCG | SYS_STATUS_ALL_RX_ERR)))
{ };

//帧自增
frame_seq_nb++;

//如果数据正常接收
if (status_reg & SYS_STATUS_RXFCG)
{
    uint32 frame_len;

    //清空接收标志
    dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_RXFCG | SYS_STATUS_TXFRS);

    //获取接收帧长度,读取接收数据
    frame_len = dwt_read32bitreg(RX_FINFO_ID) & RX_FINFO_RXFLEN_MASK;
    if (frame_len <= RX_BUF_LEN)
    {
        dwt_readrxdata(rx_buffer, frame_len, 0);
    }

    //对接收数据进行解析
    rx_buffer[ALL_MSG_SN_IDX] = 0;
    //如果接收数据是回复消息
    if (memcmp(rx_buffer, rx_resp_msg, ALL_MSG_COMMON_LEN) == 0)
    {
        uint32 final_tx_time;

        //提取时间戳
        poll_tx_ts = get_tx_timestamp_u64();
        resp_rx_ts = get_rx_timestamp_u64();

        //计算最终消息的传输时间
        final_tx_time = (resp_rx_ts + (RESP_RX_TO_FINAL_TX_DLY_UUS * UUS_TO_DWT_TIME)) >> 8;
        dwt_setdelayedtrxtime(final_tx_time);

        //最终发送帧时间戳是传输时间+天线延迟
        final_tx_ts = (((uint64)(final_tx_time & 0xFFFFFFFE)) << 8) + TX_ANT_DLY;

        //在最终发送帧中写入所有时间戳
        final_msg_set_ts(&tx_final_msg[FINAL_MSG_POLL_TX_TS_IDX], poll_tx_ts);
        final_msg_set_ts(&tx_final_msg[FINAL_MSG_RESP_RX_TS_IDX], resp_rx_ts);
        final_msg_set_ts(&tx_final_msg[FINAL_MSG_FINAL_TX_TS_IDX], final_tx_ts);

        //发送数据
        tx_final_msg[ALL_MSG_SN_IDX] = frame_seq_nb;
        dwt_writetxdata(sizeof(tx_final_msg), tx_final_msg, 0);
        dwt_writetxfctrl(sizeof(tx_final_msg), 0);
        dwt_starttx(DWT_START_TX_DELAYED);

        //等待发送完成
        while (!(dwt_read32bitreg(SYS_STATUS_ID) & SYS_STATUS_TXFRS))
        { };

        //清空发送标志
        dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_TXFRS);

        //帧自增
        frame_seq_nb++;
    }
}
else
{
    //清除接收错误数据标志
    dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_ALL_RX_ERR);
}

10.twr基站:测距

#define TX_ANT_DLY 16436
#define RX_ANT_DLY 16436

static uint8 rx_poll_msg[] = {0x41, 0x88, 0, 0xCA, 0xDE, 'W', 'A', 'V', 'E', 0x21, 0, 0};
static uint8 tx_resp_msg[] = {0x41, 0x88, 0, 0xCA, 0xDE, 'V', 'E', 'W', 'A', 0x10, 0x02, 0, 0, 0, 0};
static uint8 rx_final_msg[] = {0x41, 0x88, 0, 0xCA, 0xDE, 'W', 'A', 'V', 'E', 0x23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};

#define ALL_MSG_COMMON_LEN 10
/* Index to access some of the fields in the frames involved in the process. */
#define ALL_MSG_SN_IDX 2
#define FINAL_MSG_POLL_TX_TS_IDX 10
#define FINAL_MSG_RESP_RX_TS_IDX 14
#define FINAL_MSG_FINAL_TX_TS_IDX 18
#define FINAL_MSG_TS_LEN 4

#define RX_BUF_LEN 24
static uint8 rx_buffer[RX_BUF_LEN];

#define UUS_TO_DWT_TIME 65536
#define POLL_RX_TO_RESP_TX_DLY_UUS 2600
#define RESP_TX_TO_FINAL_RX_DLY_UUS 500
#define FINAL_RX_TIMEOUT_UUS 3300

main函数:
//设置发送和接收后的天线到事件的延迟
dwt_setrxantennadelay(RX_ANT_DLY);
dwt_settxantennadelay(TX_ANT_DLY);

//设置接收超时时间
dwt_setrxtimeout(0);

//开启接收
dwt_rxenable(0);

//等待接收完成
while (!((status_reg = dwt_read32bitreg(SYS_STATUS_ID)) & (SYS_STATUS_RXFCG | SYS_STATUS_ALL_RX_ERR)))
{ };

//如果接收数据正常,进入
if (status_reg & SYS_STATUS_RXFCG)
{
    uint32 frame_len;

    //清除接收标志
    dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_RXFCG);

    //读取数据到单片机
    frame_len = dwt_read32bitreg(RX_FINFO_ID) & RX_FINFO_RXFL_MASK_1023;
    if (frame_len <= RX_BUFFER_LEN)
    {
        dwt_readrxdata(rx_buffer, frame_len, 0);
    }

    //如果是poll消息,发送回复消息
    rx_buffer[ALL_MSG_SN_IDX] = 0;
    if (memcmp(rx_buffer, rx_poll_msg, ALL_MSG_COMMON_LEN) == 0)
    {
        uint32 resp_tx_time;

        //提取poll的时间戳
        poll_rx_ts = get_rx_timestamp_u64();

        //发送回复消息
        resp_tx_time = (poll_rx_ts + (POLL_RX_TO_RESP_TX_DLY_UUS * UUS_TO_DWT_TIME)) >> 8;
        //设置发送延迟时间
        dwt_setdelayedtrxtime(resp_tx_time);

        //设置发送后延时开启接收
        dwt_setrxaftertxdelay(RESP_TX_TO_FINAL_RX_DLY_UUS);
        //设置接收超时时间
        dwt_setrxtimeout(FINAL_RX_TIMEOUT_UUS);

        //发送消息
        tx_resp_msg[ALL_MSG_SN_IDX] = frame_seq_nb;
        dwt_writetxdata(sizeof(tx_resp_msg), tx_resp_msg, 0);
        dwt_writetxfctrl(sizeof(tx_resp_msg), 0);
        dwt_starttx(DWT_START_TX_DELAYED | DWT_RESPONSE_EXPECTED);

        //等待接收完成,接收的是最终消息
        while (!((status_reg = dwt_read32bitreg(SYS_STATUS_ID)) & (SYS_STATUS_RXFCG | SYS_STATUS_ALL_RX_ERR)))
        { };

        //帧数自增
        frame_seq_nb++;

        //如果接收的数据正常
        if (status_reg & SYS_STATUS_RXFCG)
        {
            //清除接收数据标志
            dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_RXFCG | SYS_STATUS_TXFRS);

            //将数据读取到单片机
            frame_len = dwt_read32bitreg(RX_FINFO_ID) & RX_FINFO_RXFLEN_MASK;
            if (frame_len <= RX_BUF_LEN)
            {
                dwt_readrxdata(rx_buffer, frame_len, 0);
            }

            //确认接收的是不是最终消息
            rx_buffer[ALL_MSG_SN_IDX] = 0;
            if (memcmp(rx_buffer, rx_final_msg, ALL_MSG_COMMON_LEN) == 0)
            {
                uint32 poll_tx_ts, resp_rx_ts, final_tx_ts;
                uint32 poll_rx_ts_32, resp_tx_ts_32, final_rx_ts_32;
                double Ra, Rb, Da, Db;
                int64 tof_dtu;

                //提取回复时间戳和最终消息时间戳
                resp_tx_ts = get_tx_timestamp_u64();
                final_rx_ts = get_rx_timestamp_u64();
                
                final_msg_get_ts(&rx_buffer[FINAL_MSG_POLL_TX_TS_IDX], &poll_tx_ts);
                final_msg_get_ts(&rx_buffer[FINAL_MSG_RESP_RX_TS_IDX], &resp_rx_ts);
                final_msg_get_ts(&rx_buffer[FINAL_MSG_FINAL_TX_TS_IDX], &final_tx_ts);

                //计算飞行时间
                poll_rx_ts_32 = (uint32)poll_rx_ts;
                resp_tx_ts_32 = (uint32)resp_tx_ts;
                final_rx_ts_32 = (uint32)final_rx_ts;
                Ra = (double)(resp_rx_ts - poll_tx_ts);
                Rb = (double)(final_rx_ts_32 - resp_tx_ts_32);
                Da = (double)(final_tx_ts - resp_rx_ts);
                Db = (double)(resp_tx_ts_32 - poll_rx_ts_32);
                tof_dtu = (int64)((Ra * Rb - Da * Db) / (Ra + Rb + Da + Db));

                tof = tof_dtu * DWT_TIME_UNITS;
                distance = tof * SPEED_OF_LIGHT;

                //显示
                sprintf(dist_str, "DIST: %3.2f m", distance);
                lcd_display_str(dist_str);
            }
        }
        else
        {
            //清除接收错误标志
            dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_ALL_RX_ERR);
        }
    }
}
else
{
    //清除接收错误标志
    dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_ALL_RX_ERR);
}

  • 3
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kissgoodbye2012

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值