你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

如何减小HAL_SPI_Receive 函数的等待时间?

[复制链接]
stefan2005 提问时间:2020-10-8 22:55 /
我想用stm32f303的两路SPI在4µs内各接收1个16bit 的数据,SPI SCK 18MHz 没毛病,但是两个HAL_SPI_RECEIVE 函数之间的等待时间却为惊人的8µs,竟然远大于<1µs 的信号传送时间,我的问题是,如何减小这个等待时间? 必须自己写底层函数吗?
SPI configuration:
  hspi1.Instance = SPI1;
  hspi1.Init.Mode = SPI_MODE_MASTER;
  hspi1.Init.Direction = SPI_DIRECTION_2LINES;
  hspi1.Init.DataSize = SPI_DATASIZE_16BIT;
  hspi1.Init.CLKPolarity = SPI_POLARITY_HIGH;
  hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
  hspi1.Init.NSS = SPI_NSS_HARD_OUTPUT;
  hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4;
  hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;[url=]Url[/url]
  hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
  hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
  hspi1.Init.CRCPolynomial = 7;
  hspi1.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;
  hspi1.Init.NSSPMode = SPI_NSS_PULSE_ENABLE;
  if (HAL_SPI_Init(&hspi1) != HAL_OK)
  {
    Error_Handler();
  }


测试放到main中的循环中
while(1)
{
uint16_t data_in;
HAL_SPI_Receive(&hspi1,(uint8_t *)&data_in,1,1);
}
下面是测试结果,时钟没问题 16 次, 18MHz. 但是两次接收之间的等待时间却是惊人的8µs.


201008_163505.jpg
201008_163440.jpg
收藏 评论13 发布时间:2020-10-8 22:55

举报

13个回答
lebment 回答时间:2020-10-9 09:48:42
用DMA啊,没有别的,循环模式收
七哥 回答时间:2020-10-9 00:51:03
不建议用同一片上的两路SPI互收发测试,最好用两块板一主一从测试,这样各干各的活。
不过单字节/单字收发的话,效率是很低,一个HAL_SPI_Receive函数,里面代码不少。
stefan2005 回答时间:2020-10-9 01:53:57
谢谢回复! 这里一次有16个时钟周期,所以是一次发16bit,我外接两个SPI接口的12bit ADC同时收数据,所以片子上开了两个SPI接口,想要在5µs的中断内接受数据,但是发现在限定的中断时间内没有完成下面的两道命令
HAL_SPI_Receive(&hspi1,(uint8_t *)&data_in_1,1,1);
HAL_SPI_Receive(&hspi4,(uint8_t *)&data_in_2,1,1);

结果就把其中的一个函数放到main循环中看要执行多长时间。发现两次接受得16µs.
所以想问一下有没有办法把这个间隔等待时间缩短。
stefan2005 回答时间:2020-10-9 02:10:37
SPI 接口的初始化是CUBEMX生成的,所以想问一下数据接收的函数如何写可以和HAL SPI Init 匹配。
MrJiu 回答时间:2020-10-9 03:44:06
很正常,HAL内部API会有一系列的判断,这就会增加延时。换句话说就是API里面是:各种判断+正真的数据+各种判断。。。我没测试过正真数据前和后到底会需要多长时间,但是看描述的,应该就是8us了。要想改变这个,估计可能很难。。。
MrJiu 回答时间:2020-10-9 03:50:47
接上条回复。只能自己实现,但是,如果想程序稳定的话,估计也会需要一定的时间,估计也不会短。理由如下:F3系列时钟频率是72M,ARM指令周期,一个简单的指令应该是需要4个时钟(更具51来的,我百度没查到具体值,应该是差不多的),那么1us只能执行18条语句。10us,也就执行180条语句。所以你看自己项目对于两个SPI读取间隔需要的精度是多高?如果是1us,我感觉有点凉凉!!!
MrJiu 回答时间:2020-10-9 03:52:22
注意,如果是调用函数,还要包括入栈和出栈!!!所以,对于高精度要求,最好是换实现思路。。。
stefan2005 回答时间:2020-10-9 15:06:04
@MrJiu: 谢谢您的回复。看来我得精简API函数了,看能不能加速代码。

@lebment: DMA适用于单通道多次采样。我的项目里是双通道里同时采样两个数据后马上处理。单通道多次采样后再采样第二通道的数据时差更大。
stefan2005 回答时间:2020-10-10 01:55:40
这里给出解决方法,我用了stm32f4, 144MHz SCLK, 同样的代码跑了一次,只要3µs, 符合项目要求。 看来HAL函数需要执行快的系统时钟。再次验证了Mr. Jiu 的判断,函数执行快慢和系统时钟有关。
不咸不要钱 回答时间:2020-10-10 09:23:51
这个之前也研究过,没找出来,楼主研究出来请告知一下谢谢,之前用NXP的MCU,这个时间间隔是可以调整的,当时用的时候还嫌弃就一个SPI,怎么还有这么多时间参数要调整 23333
陌路夕颜 回答时间:2020-10-10 11:07:16
自己直接用寄存器写发送接收以及判断吧
水晶之泪0517 回答时间:2020-11-27 09:55:58
代码执行效率太低了,直接使用寄存器操作试试
butterflyspring 回答时间:2020-12-2 11:53:41
库里面有LL层的方式,这样可以提高代码运行效率。不过需要用户熟悉硬件底层。如果楼主熟悉库函数的原理,或者可以考虑简单修改,只有把启动SPI的部分代码单独拿出来,这样就会大大缩短时间。当然注意不要改动出其他问题才行

所属标签

相似问题

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版