UWB-DW1000初始化、发送和接收详解(一)

这篇具有很好参考价值的文章主要介绍了UWB-DW1000初始化、发送和接收详解(一)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

DWM1000简介

DWM1000板子上的DW1000芯片,是基于CMOS的、低功耗的无线收发集成电路,遵循IEEE 802.15.4-2011协议中的UWB标准芯片。DWM1000不需要用户去设计电路,因为模块上包含天线,无线通讯模块及相关电路。
标准的IEEE 802.15.4-2011 UWB帧可承载127字节的有效载荷。不过DW1000支持非标准操作模式,帧长可达到1023个字节的数据。该操作模式通过寄存器文件 :0x04 - 系统配置的PHR_MODE选择位启用。

DW1000初始化

  peripherals_init();
    printf("hello dwm1000!\r\n");
   // dwt_dumpregisters();
    /* Reset and initialise DW1000.
     * For initialisation, DW1000 clocks must be temporarily set to crystal speed. After initialisation SPI rate can be increased for optimum
     * performance. */
    reset_DW1000(); /* Target specific drive of RSTn line into DW1000 low for a period. */

    spi_set_rate_low();
    if(dwt_initialise(DWT_LOADUCODE) == -1)
    {
        printf("dwm1000 init fail!\r\n");
        OLED_ShowString(0,0,"INIT FAIL");
        while (1)
        {
            STM_EVAL_LEDOn(LED1);
            deca_sleep(100);
            STM_EVAL_LEDOff(LED1);
            deca_sleep(100);
        }
    }
    spi_set_rate_high();

    /* Configure DW1000. See NOTE 6 below. */
    dwt_configure(&config);
    dwt_setleds(1);
    /* Apply default antenna delay value. See NOTE 1 below. */
    dwt_setrxantennadelay(RX_ANT_DLY);
    dwt_settxantennadelay(TX_ANT_DLY);
    OLED_ShowString(0,0,"INIT PASS");

    printf("init pass!\r\n");

初始化成功,显示屏显示 INIT PASS,串口助手打印 init pass。则DW1000可以正常使用。初始化失败 ,显示屏显示 INIT FAIL,串口助手打印 init fail .则说明DW1000初始化失败,不能正常使用,需要重新初始化。
UWB-DW1000初始化、发送和接收详解(一)
UWB-DW1000初始化、发送和接收详解(一)

DW1000上电复位时是RSTn脚的高低电平是有特殊变化的,如果不按照该变化来,很大可能导致DW1000不能正常使用。

UWB-DW1000初始化、发送和接收详解(一)
模块启动时,当设备开始供电的时候,RSTn 被内部的集成电路拉到低电平,RSTn 会一直保持低电平,直到模块上的晶振启动,并且当晶振的输出可以被所有模块上的设备使用时,RSTn 转为高电平。
UWB-DW1000初始化、发送和接收详解(一)

当系统启动时,RSTn 可以被用来作为输出去的外部电路。模块上的一个外部的电路可以最少用10ns去重置DW1000模块。RSTn是一个异步输入。当引脚被转为高电平时,DW1000开始初始化。注意RSTn不可以被外部电路驱动。

void reset_DW1000(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;

    // Enable GPIO used for DW1000 reset
    GPIO_InitStructure.GPIO_Pin = DW1000_RSTn;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(DW1000_RSTn_GPIO, &GPIO_InitStructure);
    //drive the RSTn pin low
    GPIO_WriteBit(GPIOB, DW1000_RSTn, 0);
    deca_sleep(100);
    GPIO_WriteBit(GPIOB, DW1000_RSTn, 1);

    deca_sleep(100);
    //put the pin back to tri-state ... as input
    GPIO_InitStructure.GPIO_Pin = DW1000_RSTn;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
    GPIO_Init(DW1000_RSTn_GPIO, &GPIO_InitStructure);
}

/*******函数名:int dwt_initialise(uint16 config) ****************/
/*******函数功能:DW1000初始化************************************/
/****参数:DWT_LOADUCODE(0x01):从ROM加载LDE码,启用准确的RX时间戳*/
/**********DWT_LOADNONE(0x0):不从OTP内存加载任何值****************/
/***返回值:成功返回 DWT_SUCCESS(0),失败返回 DWT_ERROR(-1)********/
int dwt_initialise(uint16 config)
{
	uint8 plllockdetect = EC_CTRL_PLLLCK;
	uint16 otp_addr = 0;
	uint32 ldo_tune = 0;

    dw1000local.dblbuffon = 0; // Double buffer mode off by default
    dw1000local.prfIndex = 0; // 16MHz
    dw1000local.cdata.aatset = 0; // Auto ACK bit not set
    dw1000local.wait4resp = 0;
    dw1000local.sleep_mode = 0;

    dw1000local.dwt_txcallback = NULL ;
    dw1000local.dwt_rxcallback = NULL ;

    // Read and validate device ID return -1 if not recognised
    dw1000local.deviceID =  dwt_readdevid() ;
    if (DWT_DEVICE_ID != dw1000local.deviceID) // MP IC ONLY (i.e. DW1000) FOR THIS CODE
    {
    	GPIO_ResetBits(GPIOA,GPIO_Pin_1);
		GPIO_ResetBits(GPIOA,GPIO_Pin_2);
        return DWT_ERROR ;
    }

    _dwt_enableclocks(FORCE_SYS_XTI); // NOTE: set system clock to XTI - this is necessary to make
                                       // -sure the values read by _dwt_otpread are reliable

	// Configure the CPLL lock detect
	dwt_writetodevice(EXT_SYNC_ID, EC_CTRL_OFFSET, 1, &plllockdetect);

	// Read OTP revision number
	otp_addr = _dwt_otpread(XTRIM_ADDRESS) & 0xffff;        // Read 32 bit value, XTAL trim val is in low octet-0 (5 bits)
	dw1000local.otprev = (otp_addr >> 8) & 0xff;			// OTP revision is next byte

    // Load LDO tune from OTP and kick it if there is a value actually programmed.
    ldo_tune = _dwt_otpread(LDOTUNE_ADDRESS);
	if((ldo_tune & 0xFF) != 0)
	{
		uint8 ldok = OTP_SF_LDO_KICK;
		// Kick LDO tune
		dwt_writetodevice(OTP_IF_ID, OTP_SF, 1, &ldok); // Set load LDE kick bit
		dw1000local.sleep_mode |= AON_WCFG_ONW_LLDO; // LDO tune must be kicked at wake-up
	}

    // Load Part and Lot ID from OTP
    dw1000local.partID = _dwt_otpread(PARTID_ADDRESS);
    dw1000local.lotID = _dwt_otpread(LOTID_ADDRESS);

    // XTAL trim value is set in OTP for DW1000 module and EVK/TREK boards but that might not be the case in a custom design
    dw1000local.xtrim = otp_addr & 0x1F;
    if (!dw1000local.xtrim) // A value of 0 means that the crystal has not been trimmed
    {
        dw1000local.xtrim = FS_XTALT_MIDRANGE ; // Set to mid-range if no calibration value inside
    }
    // Configure XTAL trim
    dwt_xtaltrim(dw1000local.xtrim);

    // Load leading edge detect code
    if(config & DWT_LOADUCODE)
	{
        _dwt_loaducodefromrom();
        dw1000local.sleep_mode |= AON_WCFG_ONW_LLDE; // microcode must be loaded at wake-up
	}
	else // Should disable the LDERUN enable bit in 0x36, 0x4
	{
		uint16 rega = dwt_read16bitoffsetreg(PMSC_ID, PMSC_CTRL1_OFFSET+1) ;
		rega &= 0xFDFF ; // Clear LDERUN bit
		dwt_write16bitoffsetreg(PMSC_ID, PMSC_CTRL1_OFFSET+1, rega) ;
	}

    _dwt_enableclocks(ENABLE_ALL_SEQ); // Enable clocks for sequencing

    // Read system register / store local copy
    dw1000local.sysCFGreg = dwt_read32bitreg(SYS_CFG_ID) ; // Read sysconfig register

    return DWT_SUCCESS ;

} // end dwt_initialise()
注意DW1000初始化这个函数需要在dwt_configuresleep之前运行,而且SPI频率必须小于 3MHz ,所以该使用该函数之前需要把SPI 时钟降下来先,它也可以从OTP内存中读取并应用LDO调优和晶体修剪值。
dwt_readdevid() 函数读取的是 0x00-设备标准符。对于生产的DW1000,设备ID 被设置为 0xDECA0130 。
int dwt_configure(dwt_config_t *config)
{
    uint8 nsSfd_result  = 0;
    uint8 useDWnsSFD = 0;
    uint8 chan = config->chan ;
    uint32 regval ;
    uint16 reg16 = lde_replicaCoeff[config->rxCode];
    uint8 prfIndex = dw1000local.prfIndex = config->prf - DWT_PRF_16M;
    uint8 bw = ((chan == 4) || (chan == 7)) ? 1 : 0 ; // Select wide or narrow band

    dw1000local.chan = config->chan ;

#ifdef DWT_API_ERROR_CHECK
    if (config->dataRate > DWT_BR_6M8)
    {
    	return DWT_ERROR ;
    }// validate datarate parameter
    if ((config->prf > DWT_PRF_64M) || (config->prf < DWT_PRF_16M))
    {
    	return DWT_ERROR ;      // validate Pulse Repetition Frequency
    }
    if (config->rxPAC > DWT_PAC64)
    {
    	return DWT_ERROR ;      // validate PAC size
    }
    if ((chan < 1) || (chan > 7) || (6 == chan))
    {
    	return DWT_ERROR ; // validate channel number parameter
    }

    // validate TX and TX pre-amble codes selections
    if (config->prf == DWT_PRF_64M)
    {
        // at 64M PRF, codes should be 9 to 27 only
        // config->txCode
        // config->rxCode
    }
    else
    {
        // at 16M PRF, codes should be 0 to 8 only
    }
    switch (config->txPreambLength)
    {
    case DWT_PLEN_4096 :
    case DWT_PLEN_2048 :
    case DWT_PLEN_1536 :
    case DWT_PLEN_1024 :
    case DWT_PLEN_512  :
    case DWT_PLEN_256  :
    case DWT_PLEN_128  :
    case DWT_PLEN_64   : break ; // all okay
    default            : return DWT_ERROR ; // not a good preamble length parameter
    }

    if(config->phrMode > DWT_PHRMODE_EXT)
    {
        return DWT_ERROR ;
    }
#endif

    // For 110 kbps we need a special setup
    if(DWT_BR_110K == config->dataRate)
    {
        dw1000local.sysCFGreg |= SYS_CFG_RXM110K ;
        reg16 >>= 3; // lde_replicaCoeff must be divided by 8
    }
    else
    {
        dw1000local.sysCFGreg &= (~SYS_CFG_RXM110K) ;
    }

    dw1000local.longFrames = config->phrMode ;

    dw1000local.sysCFGreg |= (SYS_CFG_PHR_MODE_11 & (config->phrMode << 16)) ;

    dwt_write32bitreg(SYS_CFG_ID,dw1000local.sysCFGreg) ;
    // Set the lde_replicaCoeff
    dwt_write16bitoffsetreg(LDE_IF_ID, LDE_REPC_OFFSET, reg16) ;

    _dwt_configlde(prfIndex);

    // Configure PLL2/RF PLL block CFG (for a given channel)
    dwt_writetodevice(FS_CTRL_ID, FS_PLLCFG_OFFSET, 5, &pll2_config[chan_idx[chan]][0]);

    // Configure RF RX blocks (for specified channel/bandwidth)
    dwt_writetodevice(RF_CONF_ID, RF_RXCTRLH_OFFSET, 1, &rx_config[bw]);

    // Configure RF TX blocks (for specified channel and PRF)
    // Configure RF TX control
    dwt_write32bitoffsetreg(RF_CONF_ID, RF_TXCTRL_OFFSET, tx_config[chan_idx[chan]]);

    // Configure the baseband parameters (for specified PRF, bit rate, PAC, and SFD settings)
    // DTUNE0
    dwt_write16bitoffsetreg(DRX_CONF_ID, DRX_TUNE0b_OFFSET, sftsh[config->dataRate][config->nsSFD]);

    // DTUNE1
    dwt_write16bitoffsetreg(DRX_CONF_ID, DRX_TUNE1a_OFFSET, dtune1[prfIndex]);

    if(config->dataRate == DWT_BR_110K)
    {
        dwt_write16bitoffsetreg(DRX_CONF_ID, DRX_TUNE1b_OFFSET, 0x64);
    }
    else
    {
        if(config->txPreambLength == DWT_PLEN_64)
        {
            uint8 temp = 0x10;
            dwt_write16bitoffsetreg(DRX_CONF_ID, DRX_TUNE1b_OFFSET, 0x10);
            dwt_writetodevice(DRX_CONF_ID, 0x26, 1, &temp);
        }
        else
        {
            uint8 temp = 0x28;
            dwt_write16bitoffsetreg(DRX_CONF_ID, DRX_TUNE1b_OFFSET, 0x20);
            dwt_writetodevice(DRX_CONF_ID, 0x26, 1, &temp);
        }
    }

    // DTUNE2
    dwt_write32bitoffsetreg(DRX_CONF_ID, DRX_TUNE2_OFFSET, digital_bb_config[prfIndex][config->rxPAC]);

    // DTUNE3 (SFD timeout)
    // Don't allow 0 - SFD timeout will always be enabled
    if(config->sfdTO == 0)
    {
        config->sfdTO = DWT_SFDTOC_DEF;
    }
    dwt_write16bitoffsetreg(DRX_CONF_ID, DRX_SFDTOC_OFFSET, config->sfdTO);

    // Configure AGC parameters
    dwt_write32bitoffsetreg( AGC_CFG_STS_ID, 0xC, agc_config.lo32);
    dwt_write16bitoffsetreg( AGC_CFG_STS_ID, 0x4, agc_config.target[prfIndex]);

    // Set (non-standard) user SFD for improved performance,
    if(config->nsSFD)
    {
         // Write non standard (DW) SFD length
         dwt_writetodevice(USR_SFD_ID,0x00,1,&dwnsSFDlen[config->dataRate]);
         nsSfd_result = 3 ;
         useDWnsSFD = 1 ;
    }
    regval =  (CHAN_CTRL_TX_CHAN_MASK & (chan << CHAN_CTRL_TX_CHAN_SHIFT)) | // Transmit Channel
              (CHAN_CTRL_RX_CHAN_MASK & (chan << CHAN_CTRL_RX_CHAN_SHIFT)) | // Receive Channel
              (CHAN_CTRL_RXFPRF_MASK & (config->prf << CHAN_CTRL_RXFPRF_SHIFT)) | // RX PRF
              ((CHAN_CTRL_TNSSFD|CHAN_CTRL_RNSSFD) & (nsSfd_result << CHAN_CTRL_TNSSFD_SHIFT)) | // nsSFD enable RX&TX
              (CHAN_CTRL_DWSFD & (useDWnsSFD << CHAN_CTRL_DWSFD_SHIFT)) | // Use DW nsSFD
              (CHAN_CTRL_TX_PCOD_MASK & (config->txCode << CHAN_CTRL_TX_PCOD_SHIFT)) | // TX Preamble Code
              (CHAN_CTRL_RX_PCOD_MASK & (config->rxCode << CHAN_CTRL_RX_PCOD_SHIFT)) ; // RX Preamble Code

    dwt_write32bitreg(CHAN_CTRL_ID,regval) ;

    // Set up TX Preamble Size and TX PRF
    // Set up TX Ranging Bit and Data Rate
    dw1000local.txFCTRL = (config->txPreambLength | config->prf) << 16;
    dw1000local.txFCTRL |= (config->dataRate << TX_FCTRL_TXBR_SHFT) | TX_FCTRL_TR; // Always set ranging bit !!!
    dwt_write32bitoffsetreg(TX_FCTRL_ID,0,dw1000local.txFCTRL) ;

    return DWT_SUCCESS ;

} // end dwt_configure()
int dwt_configure(dwt_config_t *config)是 DW1000 配置函数。配置通道,PRF等。参数为结构体。
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)
}__attribute__ ((packed))  dwt_config_t ;

初始化完成以及配置完成,还需要进行天线延迟校准,这个以后的文章会细说,这里先跳过。然后可以进行无线通信。以下是设备先发送然后在接收自己发过去的被对面接收以后转发回来的代码,本人亲测传输正常。

       static uint8_t TX_Buff[13] ={0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x20}; //发送buff
       static uint8_t RX_Buff[100] ={0};   //接收buff
        
        dwt_setrxaftertxdelay(0);   //设置发送后打开接收的延迟时间
		dwt_setrxtimeout(37000);    //设置接收超时时间
		dwt_setrxmode(0,0,0);       //设置接收模式
		
		 
		 while(1)
	{
		   dwt_writetxdata(sizeof(TX_Buff), TX_Buff, 0);  
           dwt_writetxfctrl(sizeof(TX_Buff), 0);
           dwt_starttx(DWT_START_TX_IMMEDIATE|DWT_RESPONSE_EXPECTED);  //立即发送并等待回应
			
//			           
//	        dwt_readsystime((uint8_t *)&now_systime);  //获取系统当前时间点
//		   Txtime = (now_systime + (2000 * UUS_TO_DWT_TIME)) >> 8;   //计算发送时间点
//		   dwt_setdelayedtrxtime(Txtime);  //设置延迟发送时间点
			                
//          dwt_starttx(DWT_START_TX_DELAYED); //延迟发送
	           		
			      
			  while (!(dwt_read32bitreg(SYS_STATUS_ID) & SYS_STATUS_TXFRS)) //等待发送完成
               { };
								
		     dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_RXFCG | SYS_STATUS_TXFRS); //清除发送和接收
								
             while (!((status_reg = dwt_read32bitreg(SYS_STATUS_ID)) & (SYS_STATUS_RXFCG | SYS_STATUS_ALL_RX_ERR)))
                  { };  //等待接收完成或者接收错误
										
			  if (status_reg & SYS_STATUS_RXFCG) //接收完成
			  {
					/* Clear good RX frame event and TX frame sent in the DW1000 status register. */
					dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_RXFCG | SYS_STATUS_TXFRS);
					/* A frame has been received, read it into the local buffer. */
					len = dwt_read32bitreg(RX_FINFO_ID) & RX_FINFO_RXFLEN_MASK;
					printf("len=%d\r\n",len);
				    if (len <= sizeof(RX_Buff))
					{
					  dwt_readrxdata(RX_Buff, len, 0);
					}
                    for(i=0;i<len;i++)
					{
				      printf("RX_buff[%d]=%x\r\n",i,RX_Buff[i]);
					}
			   }
		    else    //接收失败
				{
			    	/* Clear RX error events in the DW1000 status register. */
				   dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_ALL_RX_ERR);
				   printf("Receive_ERROR !\r\n");
			       for(i=0;i<20;i++)
				  {
				    printf("RX_buff[%d]=%x\r\n",i,RX_Buff[i]);
				    RX_Buff[i] =0;
				  }
				//GPIO_SetBits(GPIOA,GPIO_Pin_1);
		    	}
							 

}
void dwt_setrxaftertxdelay(uint32 rxDelayTime) 该函数是 设置发送后打开接收的延迟时间,时间单元是 UWB, 单位是微微秒(uus)。1 uus = 512 / 499.2MHz ≈ 1.0256 us。参数为0时,则发送完成后立即转为接收模式。
void dwt_setrxtimeout(uint16 time) 该参数是设置接收超时时间,时间单位也是 1uus ≈ 1.0256 us。dwt这些一系列的DW1000的API 函数,时间单位都是 1uus 后面不在强调。当接收时间超过设定时间,则不在进行接收,建议使用时,确定超时时间设置够用,否则会导致数据接收错误 ,参数为0时则禁用接收超时,一直处于接收状态。
void dwt_setrxmode(int mode, uint8 rxON, uint8 rxOFF) 该函数是设置接收模式,0-正常模式,1-SNIFF 模式,SNIFF 模式是指在低功耗模式下进行收,即收一会,关一会,如此循环,后两个参数是设置SNIFF模式下,收和关的时间。可以理解为占空比。默认为正常模式,所以不需要配置。
int dwt_writetxdata(uint16 txFrameLength, uint8 *txFrameBytes, uint16 txBufferOffset) 该函数是将数据写入 DW1000发送缓冲区,第一个参数为 发送的数据帧总长度,包括数据后面的两个字节的校验值。所以参数长度为你发送数据的长度+2。第二个参数为发送数据buff的指针(即首地址),第三个参数是传数据的偏移量,为0则从首字节开始发。

特别注意,如果数据长度这个参数你没有留数据校验这两个字节的空间,则这两个校验字节会把你所传的数据的最后两个字节覆盖了,导致数据传输错误。

int dwt_writetxfctrl(uint16 txFrameLength, uint16 txBufferOffset) 该函数在传输帧之前配置发送帧控制寄存器,参数是长度和偏移量
int dwt_starttx(uint8 mode) 该函数在上两个函数配置之后,启动传输,并且配置传输模式,0-立即发送,无需回复,1-延时发送。无需回应,2-立即发送,转接收等回应(转发送的时间由dwt_setrxaftertxdelay设置),3-延时发送,转接收等待回应。
如果设置为延时发送,则每次延时发送之前,需要配置发送的时间,否则无法正常发送。
void dwt_readsystime(uint8 * timestamp) 该函数用来读取系统当前时间,参数为一个指向五字节缓冲区的指针,如果传数组地址,则下面需要转换两次后才能使用,所以可以传一个 64bit 的变量的地址。即dwt_readsystime((uint8_t *)&now_systime);
Txtime = (now_systime + (2000 * UUS_TO_DWT_TIME)) >> 8; 该功能是把读取的当前时间加上延时传输时间,则就是计算发送时间点。
void dwt_setdelayedtrxtime(uint32 starttime) 该函数是配置延时传输时间和延时接收时间,dwt_setdelayedtrxtime(Txtime);即配置好延时发送时间点,最后使用dwt_starttx(1不转接收或3转接收)即可。

以下是开始为接收,接收完成后,把接收到的数据发送回去,本人亲测,传输正常

static uint8_t Check_Buff[13] ={0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x20,0xfa,0x8d};  //后两个为校验
static uint8_t RX_Buff[100] ={0}; //接收buff
while(1)
{
	 dwt_setrxtimeout(0);  //设置接收超时
	 dwt_setrxmode(0,0,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)  //接收完成
       {
            /* Clear good RX frame event in the DW1000 status register. */
            dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_RXFCG | SYS_STATUS_TXFRS);  //清除发送和接收

            /* A frame has been received, read it into the local buffer. */
            len = dwt_read32bitreg(RX_FINFO_ID) & RX_FINFO_RXFL_MASK_1023;   //读取接收长度包括校验
            if (len <= sizeof(RX_Buff))
              {
               dwt_readrxdata(RX_Buff, len, 0);   //将接收的数据放入RX_Buff中
               }
						
			if(memcmp(RX_Buff,Check_Buff,len)==0)  //判断接收的是否和发送过来的数据一模一样
			 {
			   for(i=0;i<len;i++)
				{
					printf("RX_buff[%d]=%x\r\n",i,RX_Buff[i]);
				}
				dwt_writetxdata(len, RX_Buff, 0); 
                dwt_writetxfctrl(len, 0);
      
                dwt_starttx(DWT_START_TX_IMMEDIATE); //传输接收数据给发送方
		     }				
	 }
	 else  //接收错误
     {
           /* Clear RX error events in the DW1000 status register. */
           dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_ALL_RX_ERR); //清除错误标准
	  	   printf("Receive_ERROR !\r\n");
		   for(i=0;i<20;i++)
		   {
			 printf("RX_buff[%d]=%x\r\n",i,RX_Buff[i]);
			 RX_Buff[i] =0;
			}
     }
}
		
int dwt_rxenable(int delayed) 该函数是延时一段时间打开接收,参数为延时时间,为0则立即打开接收。
uint32 dwt_read32bitoffsetreg(int regFileID,int regOffset) 该函数是用来读取32位的DW1000设备寄存器的值,第一个参数为要读取的寄存器的ID,第二个参数为开始读取的偏移量。返回值:成功返回读取的值,失败返回 DWT_ERROR(-1)。
int dwt_write32bitoffsetreg(int regFileID,int regOffset,uint32 regval) 该函数是用来写入32位的DW1000设备寄存器的值,第一个参数为要写入的寄存器的ID,第二个参数为开始写入的偏移量,第三个参数为写入寄存器的值。返回值:成功返回 DWT_SUCCESS(0),失败返回DWT_ERROR(-1)。

发送后转接收自己发送出去的数据,结果如下
UWB-DW1000初始化、发送和接收详解(一)文章来源地址https://www.toymoban.com/news/detail-430986.html

到了这里,关于UWB-DW1000初始化、发送和接收详解(一)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Pytorch权重初始化/参数初始化

    refer: 【Pytorch】各网络层的默认初始化方法 https://blog.csdn.net/guofei_fly/article/details/105109883 其实Pytorch初始化方法就在各自的层的 def reset_parameters(self) - None: 方法中。 有人可能会问 为什么这个方法和Pytorch直接出来的权重初始值不一样 ?单步调试会发现其实这个方法运行了至少两

    2024年02月11日
    浏览(50)
  • Linux内存初始化-启动阶段的内存初始化

    本文代码基于ARM64平台, Linux kernel 5.15 在加载kernel 之前, kernel对于系统是有一定要求的,明确规定了boot阶段必须要把MMU关闭: 那么在进入kernel之后, 就必须有一个使能MMU, 建立映射的过程, 本文描述kernel启动阶段进行内存初始化相关的操作。 在初始化阶段,我们mapping二段

    2024年02月08日
    浏览(67)
  • 深度学习参数初始化(二)Kaiming初始化 含代码

    目录 一、介绍 二、基础知识 三、Kaiming初始化的假设条件  四、Kaiming初始化的简单的公式推导 1.前向传播 2.反向传播 五、Pytorch实现 深度学习参数初始化系列: (一)Xavier初始化 含代码 (二)Kaiming初始化 含代码         Kaiming初始化论文地址:https://arxiv.org/abs/1502.01

    2024年02月04日
    浏览(62)
  • 【温故而知新】JavaScript初始化/初始化加载

    在JavaScript中,对象、数组、函数、类等都可以通过不同的方式进行初始化。以下是几种常见的初始化方式: 对象初始化: 使用字面量方式: 使用构造函数方式: 数组初始化: 使用字面量方式: 使用构造函数方式: 函数初始化: 类初始化: 使用Array的of和from方法进行数组

    2024年01月24日
    浏览(54)
  • 【随机种子初始化】一个神经网络模型初始化的大坑

    半年前写了一个模型,取得了不错的效果(简称项目文件1),于是整理了一番代码,保存为了一个新的项目(简称项目文件2)。半年后的今天,我重新训练这个整理过的模型,即项目文件2,没有修改任何的超参数,并且保持完全一致的随机种子,但是始终无法完全复现出半

    2024年02月09日
    浏览(50)
  • 初始化磁盘选哪个格式 初始化磁盘分区形式选什么好

    在 初始化磁盘 之前,我们应该先明确什么时候需要初始化磁盘,通常是在电脑安装了SSD固态硬盘,计算机无法正常读取该固态硬盘时。或者需要腾空移动磁盘,以做它用时。那么初始化磁盘时,有哪些格式呢?如今主流的是NTFS格式。也有FAT 32格式,但读写性能会比较差。

    2024年02月09日
    浏览(35)
  • c# 初始化列表,并给列表里面所有的元素进行初始化

    Enumerable.Repeat 方法是用于生成一个包含指定元素重复若干次的序列。它接受两个参数,第一个参数是要重复的元素,第二个参数是重复次数。 下面是 Enumerable.Repeat 方法的用法和示例:

    2024年02月13日
    浏览(33)
  • 官答|初始化GreatSQL报错无法找到数据目录或初始化数据字典失败

    GreatSQL推出新栏目——官答 官答栏目针对GreatSQL数据库中的问题,选取官方论坛和讨论群中的典型提问进行深入解答。内容涵盖数据库安装部署、配置优化、故障排查、性能测试等方面。 在文章中,我们不仅提供解决方案,还会结合实例深入剖析问题的成因,提升读者对GreatSQL数据

    2024年02月04日
    浏览(53)
  • media设备节点初始化与Video4Linux初始化

    media_devnode_init函数是一个内核初始化函数,用于在Linux内核启动期间进行设备节点初始化。 函数的主要作用是创建媒体设备节点(device node)并将其注册到系统的设备树中。媒体设备节点用于表示媒体设备(如摄像头、音频设备等),它们在/dev目录下以特定的名称存在,并允

    2024年02月05日
    浏览(32)
  • C语言字符串初始化详解:用常量字符串进行字符数组初始化

    简介 字符串初始化 用常量字符串 初始化过程 示范代码 结论 在C语言中,字符串被定义为字符数组。字符串的初始化是指将一个常量字符串复制到字符数组中。本文将详细介绍字符串的初始化方法,并提供相应的示范代码。 在C语言中,有几种常用的方法可以用常量字符串来

    2024年02月15日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包