Переполнение в прерывании подчиненного устройства ST32 HAL SPI
У меня проблемы с ST32F030 и Slave SPI
Я пытаюсь заставить его ответить на команду spi:-
Ведущий отправляет 0x05, подчиненный отвечает массивом из 7 байтов. Это вроде работает в первый раз, но затем теряет синхронизацию и получает бит OVR. Я не могу понять, почему.
Вот код:-
int main(void)
{
HAL_Init();
/* Configure the system clock */
SystemClock_Config();
/* Initialize all configured peripherals */
MX_SPI1_Init();
spi_init();
while (1)
{
HAL_SPI_Receive_IT(&hspi1, &spiData[0], 1);
}
}
/* SPI1 init function */
static void MX_SPI1_Init(void)
{
hspi1.Instance = SPI1;
hspi1.Init.Mode = SPI_MODE_SLAVE;
hspi1.Init.Direction = SPI_DIRECTION_2LINES;
hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi1.Init.NSS = SPI_NSS_SOFT;
hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
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_DISABLE;
/* SPi priority interrupt configuration */
HAL_NVIC_SetPriority(SPI1_IRQn, 1, 1);
if (HAL_SPI_Init(&hspi1) != HAL_OK)
{
Error_Handler();
}
}
void spi_init()
{
HAL_SPI_Receive_IT(&hspi1, spiData, 1);
}
void SPI1_IRQHandler(void)
{
HAL_SPI_IRQHandler(&hspi1);
}
uint8_t spiData[8];
uint8_t edgesmsg[7];
void spi_interrupt()
{
uint8_t c;
c = spiData[0];
if ( c == 0x05)
HAL_SPI_Transmit(&hspi1, edgesmsg, 7, 1000);
}
Любые предложения с благодарностью получены
1 ответ
Ваша проблема в том, что вы пытаетесь все время читать из SPI, не завершая предыдущую операцию, поэтому вы получаете переполнение (бит OVR). Попробуйте лучше упорядочить вещи.
Например, удалить HAL_SPI_Receive_IT(&hspi1, &spiData[0], 1);
из вашего основного цикла и вызовите его в вашем обработчике прерываний. Код должен быть:
int main(void)
{
HAL_Init();
/* Configure the system clock */
SystemClock_Config();
/* Initialize all configured peripherals */
MX_SPI1_Init();
spi_init();
while (1)
{
//Do not call HAL_SPI_Receive_IT here
//HAL_SPI_Receive_IT(&hspi1, &spiData[0], 1);
}
}
void spi_interrupt()
{
uint8_t c;
c = spiData[0];
if ( c == 0x05)
{
HAL_SPI_Transmit(&hspi1, edgesmsg, 7, 1000);
}
//Re-enable interrupt to read next sequence
HAL_SPI_Receive_IT(&hspi1, &spiData[0], 1);
}
Это принцип. Вы включаете прерывание после обработки вашего пакета. Однако я не уверен, каковы ваши намерения, и вам может понадобиться адаптировать приведенный выше код.
Также обратите внимание, что любой обработчик прерываний должен быть максимально быстрым. Так что не совсем приемлемо звонить HAL_SPI_Transmit
(функция опроса) в вашем обработчике прерываний spi_interrupt
, Вы должны либо позвонить HAL_SPI_Transmit_IT
или не использовать прерывание вообще. В первом случае остерегайтесь последовательности снова.