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

太亏了,调试这玩意儿不写点啥记录下来简直亏成翔啊,原本DWM1000的官方例程就是基于STM32的,网上更是清一色的用32来控制DWM1000,本菜鸡要用的微控制器是KEA128,不是STM32,光是移植问题就足够原地爆炸了,何况之后还有双向收发测距…不说了,进入正题。
首先,经过一段时间的浸淫,总算对官方的例程有所了解,还被自愿地学了一波32(宝宝心里苦啊)硬件方面队友是根据datasheet的接线图画的原理图,这里把两张图都贴出来,连接上应该是没问题的:
datasheet中的简易接线
硬件队友画的DW1000接线
接下来就是代码了,这里先贴出main函数的前一部分:

以上是STM32例程的初始化部分。第一句,peripherals_init(); STM32系统初始化,不用移植;第二句,lcd_display_str(APP_NAME); LCD显示字符串,不用移植;第三句,reset_DW1000(); DW1000复位函数,进去一看,是STM32的GPIO引脚配置:
在这里插入图片描述

简单来说就是先把DW1000的复位引脚设置为推挽输出然后拉低,再把它设置成模拟输入,延时2ms,那么,对应的KEA128程序如下:
在这里插入图片描述

回到main函数的第四句,spi_set_rate_low(); SPI配置为低速模式,为啥呢?有注释:
在这里插入图片描述

为了让DW1000初始化,必须将它的时钟暂时设置为晶振频率,初始化之后就可以将SPI配置成高速模式以获得更好的性能。是了,spi_set_rate_low(); 到 spi_set_rate_high(); 干的就是这个。接下来的问题是,对32来说SPI速度是多少才算是低速?
在这里插入图片描述
在这里插入图片描述

大概就是二分频四分频之类的,网上有人提到过:
在这里插入图片描述

而例程中STM32使用SPI2来控制LCD,用来和DW1000通信的是SPI1:
在这里插入图片描述

以72MHz来算,那么SPI1接口时钟32分频就是 72M / 32 = 2.25M,本菜鸡直接配置成3MHz,然后DW1000初始化部分去掉LCD的部分,剩下的直接Copy:
在这里插入图片描述

还差最后一步,底层函数重写。STM32和KEA128的SPI底层函数是不同的,要想顺利完成移植,底层移植才是真正的核心。重要,而且极易猝死…接下来又是愉快的挖STM32底层环节,个人解读SPI写函数如下:
在这里插入图片描述
在这里插入图片描述
SPI读也是类似的,唯一不同的就是两个for循环体:
在这里插入图片描述

因为KEA128只有一个SPI0通道,这个UWB测距本身也因为要做成模块的原因而只有DW1000一个从设备,所以KEA128为默认主机,SPI的片选CS硬件拉低,再去掉保留中断状态这一环节,移植到KEA128这边的时候就变成了下面这样:
在这里插入图片描述
在这里插入图片描述
好,移植暂时告一段落,现在测试KEA128和PC能否正常通信:
首先将之前的spi_init()函数与后面的DW1000初始化注释,然后UART0初始化,接收中断使能:
在这里插入图片描述
编写接收中断函数,收到信号后回复字符‘K’表示应答:
在这里插入图片描述
测试情况如下:
在这里插入图片描述

KEA128正常工作,且与PC间通信正常。接下来测试KEA128与DW1000间能否正常通信:
在这里插入图片描述
哦嚯,果然还是猝死了orz…
正常正常,一次就成功那就不是菜鸡了,接下来开始找原因。直接将dwt_readdevid()放到while(1)中,利用逻辑分析仪读取SPI四个引脚的状态:
在这里插入图片描述
附上官方给出的dwt_readdevid()函数说明:
图片
再对比一下数据手册里的相关说明:
在这里插入图片描述
从收发格式上看MOSI线是没啥问题的,但是手册里还有一个简单的模型:
在这里插入图片描述
所以这个CSn是怎么回事啊喂!!??
之前使用的是KEA128自带的SPI模块,此次移植也是直接用KEA的库,底层函数这边没太注意,现在这节奏,不得不再去挖一波KEA的底层QAQ
先看看spi的初始化函数,然后在下面这一块发现了CSn之外的问题:

SPIN[spin]->C1 = (0
                  | (pcs << SPI_C1_SSOE_SHIFT)          //配合C2_MODFEN位选择片选引脚的功能
                  | SPI_C1_SPE_MASK                     //SPI 系统使能
                  | SPI_C1_MSTR_MASK                    //SPI 模块配置为SPI 主机
                //| SPI_C1_SPIE_MASK                  //SPRF 或MODF 为1 时请求硬件中断
                //| SPI_C1_SPTIE_MASK                 //SPTEF 为1 时,请求硬件中断。
                //| SPI_C1_CPOL_MASK                  //0:高电平有效SPI 时钟(空闲时为低电平) 1:低电平有效SPI 时钟(空闲时为高电平)
                  | SPI_C1_CPHA_MASK                    //0:SPSCK 上的第一个边沿出现在数据传输的第一个周期的中间 1:SPSCK 上的第一个边沿出现在数据传输的第一个周期的开始
                //| SPI_C1_LSBFE_MASK                 //1:SPI 串行数据传输从最低有效位开始
                   );    
SPIN[spin]->C2 = pcs << SPI_C2_MODFEN_SHIFT;            //配合C1_SSOE位选择片选引脚的功能
SPIN[spin]->BR = SPI_BR_SPR(spr) | SPI_BR_SPPR(sppr);   //设置波特率参数

CPHA位被置1了…底层啊orz…默默地把它注释掉,再看逻辑分析仪:
在这里插入图片描述
不是全部为FF了,DWM1000和KEA能进行通信了,但是后四次的数据传输读到的值全是7F,还是不对,得先让CSn的变化和官方给出的示意图相同才知道到底是啥情况。
目前的片选很烦,每传完一个字节就自己拉高,设备ID有32位四个字节啊,这样根本没办法正常传输嘛,行,不要这个片选了,直接用gpio控制,简单粗暴。修改SPI初始化函数如下:

  spi_init(spi0,NOT_PCS,MASTER,2.25*1000*1000);
  gpio_init(B0,GPO,1);

直接把片选脚单独拉出来控制,这样的话之前的两个底层函数的首尾就都需要分别加上gpio_set(B0,0);和gpio_set(B0,1);来表示片选信号。
修改完毕后,也不看波形了,直接利用uart把读到ID的发回来:
在这里插入图片描述
和库里的设备ID对上了,ojbk,至此DWM1000初始化成功,后续开始Double-sidedTwo-way Ranging的移植。

  • 23
    点赞
  • 98
    收藏
    觉得还不错? 一键收藏
  • 12
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值