IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> STM32 SPI读DW1000的Device_ID的问题与解决 -> 正文阅读

[嵌入式]STM32 SPI读DW1000的Device_ID的问题与解决


官方Demo API读出的值为0,HAL读出的值为{0x 一串数字}
问题的解决方法,简单说就是增加唤醒的时长

硬件

  • STM32F103ZET
  • DWM1000
  • CH340

引脚和配置

STM32DW1000
PA0RSTN
PA4(SPI1_NSS)CSN
PA5(SPI1_SCK)CLK
PA6(SPI_MISO)MISO
PA7(SPI1_MOSI)MOSI
PB5IRQN
PB0WUP
GNDGND

问题的经过

  1. 将官方的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];
  // wakeup and init 
  dwt_spicswakeup(buf, 20);
  reset_DW1000(); /* Target specific drive of RSTn line into DW1000 low for a period. */
  port_set_dw1000_slowrate();
  uint32 dwt_ID = 0;
  // dwt_readdevid()是官方的函数,读写寄存器0x00,理论上应该读出来的是0xDECA0130
  dwt_ID = dwt_readdevid();
  // 可惜读出来的值为0
  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.

在这里插入图片描述

  1. 我又按照上述文档的如下方式,再尝试读写0x21寄存器,写入0x03,但读出还是0
	// Nss
	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET);
	uint8 dataA[20] = { 0x03 };
	uint8 dataB[20];
    // 这是官方读取设备函数(寄存器ID,index,长度,buffer)
	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 */
  1. 但疑惑的是,我用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.creadfromspiint readfromspi(uint16 headerLength,const uint8 *headerBuffer, uint32 readlength, uint8 *readBuffer){与deca_device_api.h文件保持一致
deca_spi.creadfromspiHAL_SPI_Transmit(&hspi1, (uint8 *)&headerBuffer[i], 1, HAL_MAX_DELAY);
deca_spi.cwritetospiint writetospi(uint16 headerLength,const uint8 *headerBuffer,uint32 bodyLength,const uint8 *bodyBuffer){
port.hport_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.cportGetTickCnt__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) // Device was in deep sleep (the first read fails)
    {
        // Need to keep chip select line low for at least 500us
        dwt_readfromdevice(0x0, 0x0, length, buff); // Do a long read to wake up the chip (hold the chip select low)

        // Need 5ms for XTAL to start and stabilise (could wait for PLL lock IRQ status bit !!!)
        // NOTE: Polling of the STATUS register is not possible unless frequency is < 3MHz
        deca_sleep(5);
    }
    else
    {
			//printf("0x%lx", dwt_readdevid());
        return DWT_SUCCESS;
    }
    // DEBUG - check if still in sleep mode
    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);

串口输出结果
在这里插入图片描述其它相应配置
在这里插入图片描述

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2022-04-22 18:52:42  更:2022-04-22 18:56:07 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 4:24:13-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码