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

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

以上是STM32例程的初始化部分。第一句,peripherals_init(); STM32系统初始化,不用移植;第二句,lcd_display_str(APP_NAME); LCD显示字符串,不用移植;第三句,reset_DW1000(); DW1000复位函数,进去一看,是STM32的GPIO引脚配置:
基于DWM1000的UWB测距调试(一)

简单来说就是先把DW1000的复位引脚设置为推挽输出然后拉低,再把它设置成模拟输入,延时2ms,那么,对应的KEA128程序如下:
基于DWM1000的UWB测距调试(一)

回到main函数的第四句,spi_set_rate_low(); SPI配置为低速模式,为啥呢?有注释:
基于DWM1000的UWB测距调试(一)

为了让DW1000初始化,必须将它的时钟暂时设置为晶振频率,初始化之后就可以将SPI配置成高速模式以获得更好的性能。是了,spi_set_rate_low(); 到 spi_set_rate_high(); 干的就是这个。接下来的问题是,对32来说SPI速度是多少才算是低速?
基于DWM1000的UWB测距调试(一)
基于DWM1000的UWB测距调试(一)

大概就是二分频四分频之类的,网上有人提到过:
基于DWM1000的UWB测距调试(一)

而例程中STM32使用SPI2来控制LCD,用来和DW1000通信的是SPI1:
基于DWM1000的UWB测距调试(一)

以72MHz来算,那么SPI1接口时钟32分频就是 72M / 32 = 2.25M,本菜鸡直接配置成3MHz,然后DW1000初始化部分去掉LCD的部分,剩下的直接Copy:
基于DWM1000的UWB测距调试(一)

还差最后一步,底层函数重写。STM32和KEA128的SPI底层函数是不同的,要想顺利完成移植,底层移植才是真正的核心。重要,而且极易猝死…接下来又是愉快的挖STM32底层环节,个人解读SPI写函数如下:
基于DWM1000的UWB测距调试(一)
基于DWM1000的UWB测距调试(一)
SPI读也是类似的,唯一不同的就是两个for循环体:
基于DWM1000的UWB测距调试(一)

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

KEA128正常工作,且与PC间通信正常。接下来测试KEA128与DW1000间能否正常通信:
基于DWM1000的UWB测距调试(一)
哦嚯,果然还是猝死了orz