简体   繁体   English

如何在 STM32F3 上修复 SPI 的片选时序?

[英]How to fix Chip Select Timing for SPI on STM32F3?

I'm working on a project with the STM32F303RE that requires full-duplex SPI and I am using the HAL library provided by STM.我正在使用 STM32F303RE 进行一个需要全双工 SPI 的项目,并且我正在使用 STM 提供的 HAL 库。 While all lines are working in terms of SCK, MOSI and MISO, I've noticed that the chip select line goes low much longer than necessary and seems to be triggering off around 20kHz as opposed to the 2MHz SPI.虽然所有线路都在 SCK、MOSI 和 MISO 方面工作,但我注意到片选线路的低电平比必要的要长得多,并且似乎在 20kHz 左右触发,而不是 2MHz SPI。 This is a problem as the slave I am using triggers off the CS line and during multiple SPI calls the data becomes corrupted.这是一个问题,因为我使用的从设备触发了 CS 线,并且在多次 SPI 调用期间数据被损坏。 How can I fix the timing?我怎样才能确定时间?

I'm currently using a manual GPIO that simply sets low/high before and after the SPI call.我目前正在使用手动 GPIO,它只是在 SPI 调用之前和之后设置低/高。 From reading online, it seems the CS pin is a problem source for quite a few people as there is also the option to use a hardware NSS signal although people recommend against this as it doesn't work properly.从在线阅读来看,似乎 CS 引脚是很多人的问题源,因为也可以选择使用硬件 NSS 信号,尽管人们建议不要这样做,因为它不能正常工作。

// Set SS pin low to activate
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_RESET);

// Read Temp
if(HAL_SPI_TransmitReceive(&hspi2, (uint8_t*)&master_buffer_tx[4], (uint8_t*)&master_buffer_rx[4], 1, 1000)!=HAL_OK){
      Error_Handler();
}

// Check finished
while(HAL_SPI_GetState(&hspi2) != HAL_SPI_STATE_READY){
}

// Set SS pin high to deactivate
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_SET);

HAL_Delay(10);

I would expect CS to go low roughly half a cycle before SCK and similarly afterwards.我预计 CS 会在 SCK 之前的大约半个周期和之后的类似情况下走低。 These are the possible ideas I've had: Is the "Check finished" line causing the problem?这些是我可能的想法:“检查完成”行是否导致了问题? Could it be my clock settings?会不会是我的时钟设置? Should the GPIO pin I use be the same as where NSS would be?我使用的 GPIO 引脚应该与 NSS 所在的位置相同吗? Should I be using hardware NSS?我应该使用硬件 NSS 吗? Do I need to use interrupts and DMA?我需要使用中断和 DMA 吗?

Sorry if any of this seems naive as I'm still working on my understanding of the micro controller.对不起,如果这看起来很幼稚,因为我仍在努力理解微控制器。 Thanks!谢谢!

CS and SCK timing CS 和 SCK 时序

I think I can explain the delay between activation of CS and the SPI transfer: If you take a look inside HAL_SPI_TransmitReceive() you can see that it actually requires a lot of operations to set up and start the actual SPI transfer.我想我可以解释激活 CS 和 SPI 传输之间的延迟:如果您查看HAL_SPI_TransmitReceive()内部,您会发现它实际上需要很多操作来设置和启动实际的 SPI 传输。 Depending on your clock configuration this can easily take several microseconds (see also this question ).根据您的时钟配置,这很容易花费几微秒(另请参阅此问题)。

I am a bit puzzled about the delay after the SPI transfer until CS is de-asserted.我对 SPI 传输后直到 CS 被取消断言的延迟感到有点困惑。 The HAL code should need much less operations to finish the transfer compared to the transfer preparation.与传输准备相比,HAL 代码需要更少的操作来完成传输。 The "Check finished" code should neither need many cycles, since it actually only checks a software flag (not even a hardware register). “检查完成”代码不需要很多周期,因为它实际上只检查软件标志(甚至不是硬件寄存器)。 The call is not necessary though, because HAL_SPI_TransmitReceive() is a blocking function which only returns after the SPI transfer has finished.不过该调用不是必需的,因为HAL_SPI_TransmitReceive()是一个阻塞函数,它仅在 SPI 传输完成后返回。

Regarding your problem I wanted to recommend using the hardware NSS feature.关于您的问题,我想推荐使用硬件 NSS 功能。 But at second thought this asserts CS as soon as the SPI unit is enabled.但是再想一想,一旦启用了 SPI 单元,就会断言 CS。 The ST HAL does not seem to disable the SPI unit after each transfer - so this will not work as intended. ST HAL 似乎没有在每次传输后禁用 SPI 单元 - 所以这不会按预期工作。

I think you need to analyze further what happens inside the HAL between the actual SPI transfer and the de-assertion of CS.我认为您需要进一步分析在实际 SPI 传输和 CS 取消断言之间 HAL 内部发生了什么。 This does not look like a normal behavior.这看起来不像是正常行为。 It is not necessary to use interrupts or DMA to improve the CS behavior.没有必要使用中断或 DMA 来改善 CS 行为。 These features take load from the CPU but require more complex code, which might not improve the CS delay.这些功能从 CPU 加载负载,但需要更复杂的代码,这可能不会改善 CS 延迟。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM