Если проблема с неопределенным ожиданием do-while для syn c заключается в том, что у вас не может быть «busy-wait», когда вы не можете выполнять другие работы, то решения включают:
- Использование планировщик RTOS и выполнение ожидания занятого ожидания в отдельном потоке обработчика SPI из «другой работы»
- Вместо того, чтобы опрашивать HAL_SPI_STATE_READY, используйте прерывание SPI и проверьте наличие символа синхронизации в обработчике прерываний.
- Выполните «другую работу» в do-while l oop (так называемая архитектура «big-l oop» или «executive l oop»).
В решении big-l oop у вас может быть:
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
}
Обратите внимание на то, что возвращение домой является общим принципом, а не точным кодом. Не зная природу подчиненного устройства или приложения, невозможно указать c. Адаптироваться к вашим потребностям.