[STM32H7] SPI CLK响应较慢

[复制链接]
5240|87
pmp 发表于 2023-10-22 12:06 | 显示全部楼层
可以通过调整SPI主从设备的通信速率来确保通信速率匹配,从而提高SPI CLK响应速度。
BullTalented 发表于 2023-10-23 10:38 | 显示全部楼层
检查一下你的SPI配置看看,SPI的配置存在问题,就会导致通信延迟
digit0 发表于 2023-10-23 11:54 | 显示全部楼层
可能存在硬件电路设计或SPI接口焊接问题,导致信号传输速度慢。
理想阳 发表于 2023-10-23 13:27 | 显示全部楼层
你为什么不检查一下软件配置呢
LLGTR 发表于 2023-10-23 13:50 | 显示全部楼层
若是spi接口利用间断方法举行数据传输,间断处理程序的服从也大概会影响相应时候
V853 发表于 2023-10-23 14:29 | 显示全部楼层
您可以尝试使用更快的SPI模式来提高数据传输速度。
 楼主| Hufei1994 发表于 2023-10-23 20:26 | 显示全部楼层
本帖最后由 Hufei1994 于 2023-10-23 20:34 编辑
呐咯密密 发表于 2023-10-18 17:21
这是我从STM32H743的HALL库里面找出来的的SPI发送接收函数,从你进入函数开始到真正将数据开始送出,前面 ...
  1. uint16_t SPI_ReadWriteByte(SPI_HandleTypeDef *hspi, const uint8_t *pTxData, uint8_t *pRxData)
  2. {               
  3.         uint16_t retry=0;

  4.         hspi->pRxBuffPtr  = (uint8_t *)pRxData;
  5.         hspi->pTxBuffPtr  = (const uint8_t *)pTxData;

  6.         hspi->Instance->CR1|=1<<0;//SPE=1,使能spi
  7.         hspi->Instance->CR1|=1<<9;//开启spi
  8.         
  9.         while((hspi->Instance->SR&1<<1)==0)//判断SR寄存器第二位TXP是否为1,等待发送区空        
  10.         {
  11.                 retry++;
  12.                 if(retry>0XFFFE)return 0;
  13.         }                          
  14.         *((__IO uint16_t *)&hspi->Instance->TXDR) = *((const uint16_t *)hspi->pTxBuffPtr);
  15.         
  16.         retry=0;
  17.         while((hspi->Instance->SR&1<<0)==0)//判断SR寄存器第一位RXP是否为1,等待接收完一个byte
  18.         {
  19.                 retry++;
  20.                 if(retry>0XFFFE)return 0;
  21.         }
  22.         *((uint16_t *)hspi->pRxBuffPtr) = *((__IO uint16_t *)&hspi->Instance->RXDR);

  23.         hspi->Instance->IFCR|=3<<3;//EOTC和TXTFC置1,清除EOT和TXTFC位
  24.         hspi->Instance->CR1&=~(1<<0);//SPE=0,关闭SPI2,会执行状态机复位/FIFO重置等操作
  25. }
  1. uint16_t SPI_ReadWrite_OneByte(uint16_t _txdata)
  2. {
  3.         uint16_t rxdata;
  4.         
  5.         HAL_GPIO_WritePin(SPI5_CS_GPIO_Port, SPI5_CS_Pin, GPIO_PIN_RESET);
  6.         SPI_ReadWriteByte(&hspi5, (uint8_t *)&_txdata, (uint8_t *)&rxdata);
  7.           HAL_GPIO_WritePin(SPI5_CS_GPIO_Port, SPI5_CS_Pin, GPIO_PIN_SET);
  8.         
  9.         return rxdata;
  10. }


  11. uint16_t AS5047_read(uint16_t add)
  12. {
  13.         uint16_t data;
  14.         add |= 0x4000;        //读指令 bit14 置1
  15.         if(Parity_bit_Calculate(add)==1) add=add|0x8000; //如果前15位 1的个数位偶数,则Bit15 置1
  16.         SPI_ReadWrite_OneByte(add);                //发送一条指令,不管读回的数据
  17.         data=SPI_ReadWrite_OneByte(NOP|0x4000); //发送一条空指令,读取上一次指令返回的数据。
  18.         data &=0x3fff;
  19.         return data;
  20. }

我按照HAL库实现的形式,用指针重写了SPI的传输代码,基本上全是寄存器操作,但是用时并没有预期的大大减小,总体角度读取用时由9.5us下降到了6.5us,仍然存在CS下拉后不立刻发CLK的现象(延迟了约1us),可能是cubemx配置的问题?理论的SPI纯传输时间约为3.6us(实际SPI纯CLK时间也是为3.6us左右),时间主要浪费在了CLK延迟响应上了


SPI测试.png
SPI配置.png
SPI理论传输时间.png
 楼主| Hufei1994 发表于 2023-10-23 22:34 | 显示全部楼层
玄德 发表于 2023-10-13 19:50
往 SPI ->DR 寄存器写入数据,SCK 才会出现。
你的 CS 是用 IO 方式产生的,它的边沿和 SCK 没有任何关系 ...

直接写DR寄存器看起来也是有点延时的
呐咯密密 发表于 2023-10-24 09:22 | 显示全部楼层
Hufei1994 发表于 2023-10-23 20:26
我按照HAL库实现的形式,用指针重写了SPI的传输代码,基本上全是寄存器操作,但是用时并没有预期的大大 ...

这是正常的,从CSN下拉到第一个脉冲发出一定会有延时的,MCU内部是需要执行指令的,这都会占用时间,总体时间和纯SPI时间一样这也是可以理解的,DMA只是搬运数据,真正落实到数据发出还是靠硬件SPI,而且DMA的搬运速度极快,与SPI的发送速度差距极大,所以看起来时间是一样的,一定要弄清楚概念,DMA不能加速硬件外设的传输速度,只能帮你把数据搬运到数据寄存器,你的SPI该用多少时间就是多少时间,DMA只是帮你节约了搬运数据的时间,这只有在大量数据的时候才能体现出优势,如果只是一个数据,反而会因为启动DAM而稍微造成时间的延长。DMA最大的优势是可以节省CPU资源让你去干其他的事。
 楼主| Hufei1994 发表于 2023-10-24 18:21 | 显示全部楼层
呐咯密密 发表于 2023-10-24 09:22
这是正常的,从CSN下拉到第一个脉冲发出一定会有延时的,MCU内部是需要执行指令的,这都会占用时间,总体 ...

我没用使用DMA收发SPI,就是阻塞方式的传输的。拉下CS后1us在响应CLK是正常的嘛?
呐咯密密 发表于 2023-10-25 09:33 | 显示全部楼层
Hufei1994 发表于 2023-10-24 18:21
我没用使用DMA收发SPI,就是阻塞方式的传输的。拉下CS后1us在响应CLK是正常的嘛? ...

正常也不正常,对于你的函数来说正常,对于MCU来说不正常,你再看看我上次发的寄存器方式的代码,你多了SPI的使能,这个使能完全可以放在初始化的时候,不取消使能,让SPI一直处于使能状态,当你给数据寄存器填充数据,SPI就会立马将数据送出。
 楼主| Hufei1994 发表于 2023-10-25 22:36 | 显示全部楼层
呐咯密密 发表于 2023-10-25 09:33
正常也不正常,对于你的函数来说正常,对于MCU来说不正常,你再看看我上次发的寄存器方式的代码,你多了S ...

这个不能放在初始化里,因为增加了使能,进而可以失能,失能的同时可以清除fifo,如果不清除fifo,读出来的数据有异常,在俩个固定的数之间跳变,这个我试过的
 楼主| Hufei1994 发表于 2023-10-25 22:40 | 显示全部楼层
呐咯密密 发表于 2023-10-25 09:33
正常也不正常,对于你的函数来说正常,对于MCU来说不正常,你再看看我上次发的寄存器方式的代码,你多了S ...

m7的SPI 是有fifo的,但是M4是没有的,你说的这种操作在M4上应该是可行的
呐咯密密 发表于 2023-10-26 09:07 | 显示全部楼层
Hufei1994 发表于 2023-10-25 22:40
m7的SPI 是有fifo的,但是M4是没有的,你说的这种操作在M4上应该是可行的

把强制D-Cache透写打开,在CSN下拉之前使能SPI,这样不就行了么
 楼主| Hufei1994 发表于 2023-10-26 13:53 | 显示全部楼层
呐咯密密 发表于 2023-10-26 09:07
把强制D-Cache透写打开,在CSN下拉之前使能SPI,这样不就行了么

好的好的,感谢提醒。我尝试一下开启透写模式,将SPI开启放在初始化中来进行。我之前被这个D-cach折腾过,所有用到了DMA的地方都加了清除函数SCB_CleanInvalidateDCache_by_Addr,FIFO相对于D-cach应该与DMA相对于D-cach一样吧?开了透写模式后,应该可以去掉所有的SCB_CleanInvalidateDCache_by_Addr函数了吧?
呐咯密密 发表于 2023-10-26 15:50 | 显示全部楼层
Hufei1994 发表于 2023-10-26 13:53
好的好的,感谢提醒。我尝试一下开启透写模式,将SPI开启放在初始化中来进行。我之前被这个D-cach折腾过 ...

是的
 楼主| Hufei1994 发表于 2023-10-26 20:08 | 显示全部楼层
呐咯密密 发表于 2023-10-26 09:07
把强制D-Cache透写打开,在CSN下拉之前使能SPI,这样不就行了么

D-Cache透写打开,SPI开启放入初始化后,总体SPI的传输时间变为5.875us,主要是SPI开延时与关延时降低了一些,这个延时感绝应该是没法在降低了,可能就是纯硬件延时了,最后感谢大佬的指点
Dcache透传模式.png
Clyde011 发表于 2023-12-1 07:15 | 显示全部楼层

作为功率开关管和整流器的散热部分
万图 发表于 2023-12-1 09:11 | 显示全部楼层

在主要开关电源拓扑中主要的电流环路
Uriah 发表于 2023-12-1 10:14 | 显示全部楼层

每条大电流的地线要短而宽
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 在线客服 返回列表 返回顶部