HAL_UART_Transmit_IT отправка данных дважды - PullRequest
0 голосов
/ 09 июля 2019

Я пытаюсь установить связь UART между ПК и платой STM32f407-DISC1, используя arduino nano в качестве посредника. ПК отправляет «r» в arduino, чтобы указать запрос. Затем запрос передается в stm32 с прерыванием GPIO, которое затем должно передавать 480 байтов данных, используя HAL_UART_Transmit_IT. Однако он отправляет данные дважды, только с одним выполненным запросом.

Код на STM32 генерируется STM32CubeMX

Запрос данных сделан arduino

void loop() {
    digitalWrite(4, 0); // Clear EXTI11 line.

    if (mySerial.available() && received < 480) {   // STM32 sending data and is not done.
        buff[received] = mySerial.read();           // Append received data to the buffer.
        received++;
    }
    if (received >= 480) {                          // If the buffer is full
        received = 0;                               // transmit it to PC.
        Serial.println(buff);
    }


    if (Serial.available()) {
        if (Serial.read() == 'r') {     // PC requests data from the STM32
            digitalWrite(4, 1);         // Triggers STM32 EXTI11 line.
            while (Serial.available())  // Empty the buffer.
                Serial.read();
        }
    }
}

передача данных на STM32

void EXTI15_10_IRQHandler(void)
{
    // Make sure that the interrupt is the good one.
    if (HAL_GPIO_ReadPin(data_req_IRQ_GPIO_Port, data_req_IRQ_Pin)) {
        if (is_sending_data == FALSE)   // If no transmission is happening
            should_send_data = TRUE;    // raise transmission flag.
    }

    // IRQ handling stuff...
}

void HAL_UART_TxCpltCallback(UART_HandleTypeDef * huart) {
    is_sending_data = FALSE;    // Transmition is completed, unblock requests.
}

void main(void){
    // Init and other stuff...

    while (1) {
        if (should_send_data == TRUE) { // If data was requested
            HAL_GPIO_WritePin(LD5_GPIO_Port, LD5_Pin, GPIO_PIN_RESET);
            HAL_UART_Transmit_IT(&huart3, matrice, 480);    // Start transmission by interrupt.
            is_sending_data = TRUE;                         // Block requests.
            should_send_data = FALSE;                       // Clear flag.
        }
    // matrice acquisition stuff here
    }
}

1 Ответ

0 голосов
/ 12 июля 2019

Хорошо, поэтому я нашел решение, но оно включало просто переосмысление моего подхода, извините за поиск ответа на эту проблему.

Я удалил посредника 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));

Это хорошо работает при довольно приличной производительности, так что это может стать постоянным решением моей проблемы.

...