Идея для синхронизации SPI - PullRequest
2 голосов
/ 29 апреля 2020

Интересно, есть ли другой способ синхронизации связи 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);
}

Есть ли какое-нибудь решение, где делать, пока l oop не используется?

1 Ответ

3 голосов
/ 29 апреля 2020

Если проблема с неопределенным ожиданием do-while для syn c заключается в том, что у вас не может быть «busy-wait», когда вы не можете выполнять другие работы, то решения включают:

  1. Использование планировщик RTOS и выполнение ожидания занятого ожидания в отдельном потоке обработчика SPI из «другой работы»
  2. Вместо того, чтобы опрашивать HAL_SPI_STATE_READY, используйте прерывание SPI и проверьте наличие символа синхронизации в обработчике прерываний.
  3. Выполните «другую работу» в 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. Адаптироваться к вашим потребностям.

...