基于DWM1000的UWB测距调试(二)

下面开始测距程序的移植。因为官方提供的ds_twr测距程序是分A、B设备的,所以这就意味着接下来需要同时调试两份程序,双倍的快乐QAQ
首先测试双方能否顺利收发。
在此之前需要重新对SPI的波特率进行配置,KEA128的SPI通道最大波特率为总线时钟二分频,这里取12MHz。
对于设备A(发送方):

  /* Configure DW1000. See NOTE 7 below. */
  dwt_configure(&config);
  
//  /* Apply default antenna delay value. See NOTE 1 below. */
//  dwt_setrxantennadelay(RX_ANT_DLY);
//  dwt_settxantennadelay(TX_ANT_DLY);
//  /* Set expected response's delay and timeout. See NOTE 4, 5 and 6 below.
//  * As this example only handles one incoming frame with always the same delay and timeout, those values can be set here once for all. */
//  dwt_setrxaftertxdelay(POLL_TX_TO_RESP_RX_DLY_UUS);
//  dwt_setrxtimeout(RESP_RX_TIMEOUT_UUS);
//  dwt_setpreambledetecttimeout(PRE_TIMEOUT);

之后直到while循环为止的这一部分除了第一句dwt_configure(&config); 是必须的外,其余的都用于双向测距,而当前仅测试两个DWM1000模块间能否正常收发信息包,故直接注释。

    /* Write frame data to DW1000 and prepare transmission. See NOTE 4 below.*/
    dwt_writetxdata(sizeof(tx_msg), tx_msg, 0); /* Zero offset in TX buffer. */
    dwt_writetxfctrl(sizeof(tx_msg), 0, 0); /* Zero offset in TX buffer, no ranging. */
    
    /* Start transmission. */
    dwt_starttx(DWT_START_TX_IMMEDIATE);
    
    /* Poll DW1000 until TX frame sent event set. See NOTE 5 below.
    * STATUS register is 5 bytes long but, as the event we are looking at is in the first byte of the register, we can use this simplest API
    * function to access it.*/
    while (!(dwt_read32bitreg(SYS_STATUS_ID) & SYS_STATUS_TXFRS))
    { };
    
    /* Clear TX frame sent event. */
    dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_TXFRS);
    
    /* Execute a delay between transmissions. */
    systick_delay_ms(TX_DELAY_MS);
    
    /* Increment the blink frame sequence number (modulo 256). */
    tx_msg[BLINK_FRAME_SN_IDX]++;

while循环体内直接移植官方提供的Simple TX例程,同理对于设备B(接收方)也直接移植Simple RX例程,唯一多出来的就是接收完一帧数据后利用UART0将收到的数据中的一部分发到PC端以校验具体数据传输情况:

    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);
        uart_putchar(uart0,rx_buffer[2]);
        uart_putchar(uart0,rx_buffer[3]);
      }
      dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_RXFCG);
    }

在程序中要求发送的信息包如下:

而在PC端接收到的回馈信息如下:

从之前的uart发送函数可以知道,两个模块之间可以正常收发信息包。然而还是存在一点问题。使用官方的例程虽然可以收发信息包,但是在PC端看回馈信息的时候博主有注意到,官方的例程在KEA128上跑得似乎并不稳定,每一组DE都是不等时地回馈回来,而且在接收了54字节的时候更是彻底停下来了orz…
目前先不考虑代码优化的问题,暂且将SPI通信速率下调到8MHz,先把整体框架搭出来。那么,接下来的工作就是将官方提供的Double-sidedTwo-way Ranging例程移植到KEA里,然后逐步进行调试(直接移植过来直接就能用只需要校准一下这种情况是不存在的,毕竟用的是KEA128不是STM32QAQ)。
Double-sidedTwo-way Ranging的测距具体原理及实现算法网上不难找到,熊大已经很好地进行了说明:熊大UWB系列教程三,故在此不再赘述,只记录调试过程。
先将原来的收发测试部分移除,并将DS测距部分的程序全部移植到KEA这边。由于官方例程的DS测距程序也是在调用官方的库函数(带dwt前缀的函数),所以代码基本上是兼容的,不同的地方有两点:一是保留中断状态的函数 decamutexon() 与 decamutexoff(stat)的调用,这里暂时不考虑中断,所以直接移除;二是关于延时函数的问题,官方例程中默认调用STM32的延时函数,而博主在KEA这边直接替换成了滴答定时器延时。
接着根据DS的单次测距流程,逐步检查流程中各步骤的执行情况。规定1:A发送起始poll包 2:B接收到poll包 3:B发送resp包 4:A接收到resp包 5:A发送final包 6:B接收到final包。这里直接使用之前测试双机收发的方式,即在相应的步骤执行完毕后,使用UART将对应的标号回发到PC端。
在设备A端读取到的回馈情况如下:
在这里插入图片描述
在设备B端读取到的回馈情况如下:
在这里插入图片描述
设备B回馈的标号只有2而没有3,也就是说设备B在接收到设备A发出的poll包后,在校验poll包的时候发现错误或是在发送resp包的过程中出现了问题。设备B收到的数据表明接收方接收到的poll包是正确的,但是却没有成功发送resp包:

//设备A的poll包
static uint8 tx_poll_msg[] = {0x41, 0x88, 0, 0xCA, 0xDE, 'W', 'A', 'V', 'E', 0x21, 0, 0};
//设备B的校验包
static uint8 rx_poll_msg[] = {0x41, 0x88, 0, 0xCA, 0xDE, 'W', 'A', 'V', 'E', 0x21, 0, 0};

在这里插入图片描述
接下来的测试也验证了博主的推测:

        ret = dwt_starttx(DWT_START_TX_DELAYED | DWT_RESPONSE_EXPECTED);        
        
        /* If dwt_starttx() returns an error, abandon this ranging exchange and proceed to the next one. See NOTE 11 below. */
        if (ret == DWT_ERROR)
        {
          uart_putchar(uart0,'E');
          continue;
        }

在这里插入图片描述
跟进dwt_starttx() 函数一看,官方在报错的情况处给出了说明:

        else
        {
            // I am taking DSHP set to Indicate that the TXDLYS was set too late for the specified DX_TIME.
            // Remedial Action - (a) cancel delayed send
            temp = (uint8)SYS_CTRL_TRXOFF; // This assumes the bit is in the lowest byte
            dwt_write8bitoffsetreg(SYS_CTRL_ID, SYS_CTRL_OFFSET, temp);
            // Note event Delayed TX Time too Late
            // Could fall through to start a normal send (below) just sending late.....
            // ... instead return and assume return value of 1 will be used to detect and recover from the issue.
            pdw1000local->wait4resp = 0;
            retval = DWT_ERROR ; // Failed !
        }

嗯,简单来说就是设备B程序设定的 POLL_RX_TO_RESP_TX_DLY_UUS小了,程序从dwt_setdelayedtrxtime(resp_tx_time); 这一句执行到 ret = dwt_starttx(DWT_START_TX_DELAYED | DWT_RESPONSE_EXPECTED); 这一句的时间已经超过了原本设置的延迟发送时间 resp_tx_time 而使得程序报错。把POLL_RX_TO_RESP_TX_DLY_UUS 上调到2800,问题就解决了:
在这里插入图片描述
再回接到设备A这边,设备B已经回发了resp包,但设备A并没有成功接收:
在这里插入图片描述
A没有成功接收只有两种情况,一是B在A打开接收之前就回发了,二是A的接收超时时间太短。但是,官方例程在A端的例程中设定的A打开接收的延迟时间POLL_TX_TO_RESP_RX_DLY_UUS只有150,而在B端的例程中设定的B接收以后延迟发送的时间POLL_RX_TO_RESP_TX_DLY_UUS 就达到了2600,在这里更是上调到了2800,所以第一种情况是不可能发生的。A端的接收超时时间RESP_RX_TIMEOUT_UUS原值为2700,将其上调到3000,再看B端回馈的数据时,整个过程就通了:
在这里插入图片描述
236后面这一段奇怪的东西就是距离了,只不过还没有进行转化而已,另外天线延迟也还需要调整,但就目前来说主体工作算是完成了。在使用官方例程完成DWM1000的校准后就可以进行正常的测距了,后续若有时间将尝试对官方测距代码进行优化。

  • 13
    点赞
  • 66
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
辣鸡网站怎么把资源都涨价到35了,改回来 谷歌机翻+个人修正的user manul,感兴趣可以看看 目录 Initializing the driver 6 2 DW1000的概述 13 2.1简介 13 2.2连接到DW1000 13 2.2.1 SPI接口 13 .2.1.1 SPI工作模式 13 2.2.2中断 16 2.2.3通用I / O 17 2.2.4 SYNC引脚 17 2.3 DW1000操作状态 17 2.3.1状态图 17 2.3.2主要运行状态概述 17 2.4上电复位(POR) 19 2.5上电时的默认配置 21 2.5.3默认发射机配置T 22 2.5.4默认接收器配置 22 2.5.5应该修改的默认配置 23 3消息传输 26 3.1基本传输 26 3.2传输时间戳 27 3.3延迟传输 28 3.4扩展长度数据帧 29 3.5高速传输 30 3.5.1 TX缓冲区偏移索引 30 3.5.2发送或接收TX缓冲区时写入 31 4讯息接收 33 4.1基本接收 33 4.1.1前导码检测 33 4.1.2前导码累积 34 4.1.3 SFD检测 35 4.1.4 PHR解调 35 4.1.5数据解调 35 4.1.6 RX消息时间戳 36 4.2延迟接收 36 4.3双接收缓冲器 37 4.3.1启用双缓冲操作 37 4.3.2控制正在访问哪个缓冲区 37 4.3.3双缓冲的操作 38 4.3.4使用双缓冲时的TRXOFF 40 4.3.5超限 40 4.4低功耗侦听 41 4.4.1配置低功率监听 42 4.5低功耗SNIFF模式 42 4.5低功耗SNIFF模式 43 4.5.1 SNIFF模式 43 4.5.2低占空比SNIFF模式 44 4.7.1估算第一条路径的信号功率 45 4.7.2估算接收信号功率 46 5 Media Access Control (MAC) hardware features 47 5.1循环冗余校验 47 5.2帧过滤 47 5.2.1帧过滤规则 48 5.2.2帧过滤注意事项 49 5.3自动确认 49 5.3.2自动接收器重新启用 51 5.3.3自动ACK周转时间 51 5.3.4帧挂起位Frame Pending bit 51 5.3.5主机通知 51 5.4发送并自动等待响应 52 6 DW1000的其他功能 52 6.1外部同步 52 6.1.1一次性时基复位(OSTR)模式 52 6.1.2单发发送同步(OSTS)模式 53 6.1.3一次接收同步(OSRS)模式 53 6.2外部功率放大 55 6.3使用片上OTP存储器 55 6.3.1 OTP存储器映射 55 6.3.2将值编程到OTP存储器中 57 6.3.3从OTP内存中读取一个值 58 6.4测量IC温度和电压 58 10附录1:IEEE 802.15.4 UWB物理层 59 10.1框架结构概述 59 10.2数据调制方案 59 10.3同步头调制方案 60 10.4 PHY头 61 10.5 UWB信道和前导码 62 10.6标准的其他细节 62 11附录2:IEEE 802.15.4 MAC层 62 11.1一般MAC消息格式 63 11.2 MAC报头中的帧控制字段 63 11.2.1帧类型字段Frame type field 64 11.2.2启用安全性字段Security enabled Field 64 11.2.3帧未决字段Frame pending field 64 11.2.4确认请求字段Acknowledgement request field 65 11.2.5 PAN ID压缩字段PAN ID compression field 65 11.2.6目标寻址模式字段Destination addressing mode field 65 11.2.7帧版本字段Frame version field 66 11.2.8源寻址模式字段Source addressing mode field 66 11.3序号字段The Sequence Number field 66 11.4 DW1000中的MAC级处理 66
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值