官方Demo API读出的值为0,HAL读出的值为{0x 一串数字} 问题的解决方法,简单说就是增加唤醒的时长
硬件
引脚和配置
STM32 | DW1000 |
---|
PA0 | RSTN | PA4(SPI1_NSS) | CSN | PA5(SPI1_SCK) | CLK | PA6(SPI_MISO) | MISO | PA7(SPI1_MOSI) | MOSI | PB5 | IRQN | PB0 | WUP | GND | GND |
问题的经过
- 将官方的Demo(https://www.decawave.com/wp-content/uploads/2019/01/dw1000_api_rev2p14.zip)移植到了CubeMX创建的Keil5 MDK项目后(已移除了LCD、LED和USB部分),但当我想调用官方的dwt_readdevid()函数读取Device时,读出来的值为0。
MX_GPIO_Init();
MX_SPI1_Init();
MX_USART1_UART_Init();
uint8 buf[20];
dwt_spicswakeup(buf, 20);
reset_DW1000();
port_set_dw1000_slowrate();
uint32 dwt_ID = 0;
dwt_ID = dwt_readdevid();
printf("ID:%lx\r\n",dwt_ID);
3. 然后,我再看了网络中大部分类似该篇https://mculover666.blog.csdn.net/article/details/114890352 的文章(这是直接使用HAL库),读出来的值为0x 800210a,可这也是不正确的。在看了https://decaforum.decawave.com/search?q=device%20id 论坛中相关话题,也没有找到合适的答案。而根据这份文档的https://www.decawave.com/sites/default/files/aps022_debugging_dw1000_based_products_systems.pdf的第7页,读出类似的值说明SPI的配置有问题:
If the device returns some other value e.g. 0xBD940260: -
- the SPI mode is probably not set correctly (the controller’s SPI mode does not match the DW1000 SPI mode); or
- the data read back is shifted. Check the controller’s SPI configuration.
- 我又按照上述文档的如下方式,再尝试读写0x21寄存器,写入0x03,但读出还是0
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET);
uint8 dataA[20] = { 0x03 };
uint8 dataB[20];
dwt_writetodevice(0x21, 0, 20, &dataA[0]);
dwt_readfromdevice(0x21, 0 , 20, &dataB[0]);
printf("(api reg 0x21)the data a is 0x%d, datab is 0x%d\r\n", dataA[0], dataB[0]);
deca_reg.h对0x21的描述为用户指定的SFD序列
/****************************************************************************//**
* @brief Bit definitions for register USR_SFD
* Please read User Manual : User defined SFD sequence
**/
#define USR_SFD_ID 0x21 /* User-specified short/long TX/RX SFD sequences */
- 但疑惑的是,我用HAL库的这个HAL_SPI_TransmitReceive函数读写时,写入0x04,读出0x04,时而为0x0。
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET);
uint8 dataA[20] = { 0x03, 0x04 };
uint8 dataB[20];
printf("***********\r\n");
HAL_SPI_TransmitReceive(&hspi1, &dataA[1], &dataB[1], 4, HAL_MAX_DELAY);
问题的矛头
文件 | 函数 | 修改后 | 说明 |
---|
deca_spi.c | readfromspi | int readfromspi(uint16 headerLength,const uint8 *headerBuffer, uint32 readlength, uint8 *readBuffer){ | 与deca_device_api.h文件保持一致 | deca_spi.c | readfromspi | HAL_SPI_Transmit(&hspi1, (uint8 *)&headerBuffer[i], 1, HAL_MAX_DELAY); | | deca_spi.c | writetospi | int writetospi(uint16 headerLength,const uint8 *headerBuffer,uint32 bodyLength,const uint8 *bodyBuffer){ | | port.h | port_deca_isr_t port_deca_isr; | extern port_deca_isr_t port_deca_isr; | | port.h | 末尾 | | 为port.c的延时函数int usleep(useconds_t usec)定义类型useconds_t ,原是STM32Workspace软件插件中type.h封装的 | port.c | portGetTickCnt | __INLINE uint32_t portGetTickCnt(void) | |
在port.h、port.c文件中需要对USB、LCD等相关代码清除,引入main.h声明引脚
- SPI配置的问题,对比官方Demo中的CubeMX项目具体配置(时钟输入不必为12,串口打印会乱码)。
这是串口打印出来的结果
问题的解决
根据https://decaforum.decawave.com/uploads/short-url/jQPkxawHn3LzbJln0QqjPShspZP.pdf文档第48页,dwt_spicswakeup函数唤醒DW1000至少需要500us,并取决于SPI读写速率 那么在deca_device.c文件下的dwt_spicswakeup函数中如下修改
int dwt_spicswakeup(uint8 *buff, uint16 length)
{
if(dwt_readdevid() != DWT_DEVICE_ID)
{
dwt_readfromdevice(0x0, 0x0, length, buff);
deca_sleep(5);
}
else
{
return DWT_SUCCESS;
}
if(dwt_readdevid() != DWT_DEVICE_ID)
{
deca_sleep(200);
return DWT_ERROR;
}
printf("0x%lx", dwt_readdevid());
return DWT_SUCCESS;
}
在main.c文件main函数测试
printf("DW1000:\r\n");
while (dwt_spicswakeup(dummy_buffer, DUMMY_BUFFER_LEN) != DWT_SUCCESS);
串口输出结果 其它相应配置
|