SPI同步的想法
Idea for SPI synchronization
请问有没有其他方法可以同步SPI通信。在 STM 示例中,我发现这部分代码有效:
void Slave_Synchro(void)
{
uint8_t txackbyte = SPI_SLAVE_SYNBYTE;
uint8_t rxackbyte = 0x00;
do
{
if (HAL_SPI_TransmitReceive_IT(&SpiHandle, (uint8_t *)&txackbyte, (uint8_t *)&rxackbyte, 1) != HAL_OK)
{
Error_Handler();
}
while (HAL_SPI_GetState(&SpiHandle) != HAL_SPI_STATE_READY){}
}
while (rxackbyte != SPI_MASTER_SYNBYTE);
}
有没有不使用do while循环的解决方案?
如果 do-while 无限期等待同步的问题是您无法使用 "busy-wait" 无法执行其他炒锅,则解决方案包括:
- 使用 RTOS 调度程序并在 "other work"
的单独 SPI 处理程序线程中执行忙等待
- 不轮询 HAL_SPI_STATE_READY,而是使用 SPI 中断并检查中断处理程序中的同步字符。
- 在 do-while 循环中执行 "other work"(所谓的 "big-loop" 或 "executive loop" 架构)。
在大循环解决方案中你可能有:
bool synchronised = false ;
while(;;)
{
if( !synchronised )
{
if( HAL_SPI_GetState(&SpiHandle) == HAL_SPI_STATE_READY )
{
if (HAL_SPI_TransmitReceive_IT(&SpiHandle, (uint8_t *)&txackbyte, (uint8_t *)&rxackbyte, 1) != HAL_OK)
{
Error_Handler();
}
}
synchronised == HAL_SPI_GetState(&SpiHandle) == HAL_SPI_STATE_READY &&
rxackbyte == SPI_MASTER_SYNBYTE);
}
if( synchronised )
{
// do SPI work
}
// do other work
}
您可以通过创建一个函数来整理它,例如:
bool isSlaveSynchronised()
{
static bool synchronised = false ;
if( !synchronised )
{
if( HAL_SPI_GetState(&SpiHandle) == HAL_SPI_STATE_READY )
{
if (HAL_SPI_TransmitReceive_IT(&SpiHandle, (uint8_t *)&txackbyte, (uint8_t *)&rxackbyte, 1) != HAL_OK)
{
Error_Handler();
}
}
synchronised == HAL_SPI_GetState(&SpiHandle) == HAL_SPI_STATE_READY &&
rxackbyte == SPI_MASTER_SYNBYTE);
}
return synchronised ;
}
然后:
while(;;)
{
if( !isSlaveSynchronised() )
{
// do SPI work
}
// do other work
}
注意这里的带回家是一般原则,而不是精确的代码。在不知道从属设备或应用程序的性质的情况下是不可能具体的。适应您的需求。
请问有没有其他方法可以同步SPI通信。在 STM 示例中,我发现这部分代码有效:
void Slave_Synchro(void)
{
uint8_t txackbyte = SPI_SLAVE_SYNBYTE;
uint8_t rxackbyte = 0x00;
do
{
if (HAL_SPI_TransmitReceive_IT(&SpiHandle, (uint8_t *)&txackbyte, (uint8_t *)&rxackbyte, 1) != HAL_OK)
{
Error_Handler();
}
while (HAL_SPI_GetState(&SpiHandle) != HAL_SPI_STATE_READY){}
}
while (rxackbyte != SPI_MASTER_SYNBYTE);
}
有没有不使用do while循环的解决方案?
如果 do-while 无限期等待同步的问题是您无法使用 "busy-wait" 无法执行其他炒锅,则解决方案包括:
- 使用 RTOS 调度程序并在 "other work" 的单独 SPI 处理程序线程中执行忙等待
- 不轮询 HAL_SPI_STATE_READY,而是使用 SPI 中断并检查中断处理程序中的同步字符。
- 在 do-while 循环中执行 "other work"(所谓的 "big-loop" 或 "executive loop" 架构)。
在大循环解决方案中你可能有:
bool synchronised = false ;
while(;;)
{
if( !synchronised )
{
if( HAL_SPI_GetState(&SpiHandle) == HAL_SPI_STATE_READY )
{
if (HAL_SPI_TransmitReceive_IT(&SpiHandle, (uint8_t *)&txackbyte, (uint8_t *)&rxackbyte, 1) != HAL_OK)
{
Error_Handler();
}
}
synchronised == HAL_SPI_GetState(&SpiHandle) == HAL_SPI_STATE_READY &&
rxackbyte == SPI_MASTER_SYNBYTE);
}
if( synchronised )
{
// do SPI work
}
// do other work
}
您可以通过创建一个函数来整理它,例如:
bool isSlaveSynchronised()
{
static bool synchronised = false ;
if( !synchronised )
{
if( HAL_SPI_GetState(&SpiHandle) == HAL_SPI_STATE_READY )
{
if (HAL_SPI_TransmitReceive_IT(&SpiHandle, (uint8_t *)&txackbyte, (uint8_t *)&rxackbyte, 1) != HAL_OK)
{
Error_Handler();
}
}
synchronised == HAL_SPI_GetState(&SpiHandle) == HAL_SPI_STATE_READY &&
rxackbyte == SPI_MASTER_SYNBYTE);
}
return synchronised ;
}
然后:
while(;;)
{
if( !isSlaveSynchronised() )
{
// do SPI work
}
// do other work
}
注意这里的带回家是一般原则,而不是精确的代码。在不知道从属设备或应用程序的性质的情况下是不可能具体的。适应您的需求。