Хорошо, поэтому я нашел решение, но оно включало просто переосмысление моего подхода, извините за поиск ответа на эту проблему.
Я удалил посредника arduino, заменив его конвертером USB в RS232, и заставил прием UART работать по прерыванию. STM обнаруживает символ «r», который запускает передачу данных.
Вот часть прерывания:
void USART3_IRQHandler(void)
{
if (USART3->SR & UART_IT_RXNE) { // If a byte is received
rxBuff[0] = (uint8_t) (huart3.Instance->DR & (uint8_t) 0xFF); // Read it.
__HAL_UART_FLUSH_DRREGISTER(&huart3); // Clear the buffer to avoid errors.
rx_new_char_flag = TRUE; // Raise the new_char flag.
return; // Stops the IRQHandler from disabling interrupts.
}
}
и получение этого в основном
while (1) {
if (rx_new_char_flag == TRUE) {
rx_new_char_flag = FALSE;
if (rxBuff[0] == 'r') {
rxBuff[0] = 0;
HAL_UART_Transmit_IT(&huart3, matrice, 480); // Start transmission by interrupt.
}
}
На стороне ПК, чтобы оптимизировать производительность, вместо ожидания полных 480 байтов, я жду только одного символа, если он получен, я продолжаю читать последовательный порт, как показано в коде ниже
int i = 0;
do {
ReadFile(m_hSerial, &temp_rx[i], 1, &dwBytesRead, NULL);
i++;
} while (dwBytesRead > 0 && i < 480);
for (int j = i; j < 480; j++) // If the transmission is incomplete, fill the buffer with 0s to avoid garbage data.
temp_rx[j] = 0;
if(i>=480) // If all the bytes has been received, copy the data in the working buffer.
std::copy(std::begin(temp_rx), std::end(temp_rx), std::begin(m_touch_state));
Это хорошо работает при довольно приличной производительности, так что это может стать постоянным решением моей проблемы.