1
\$\begingroup\$

could someone explain why i can only receive 13 chars with USART interrupt? I use '\n' to detect the end of string. enter image description here

#define BUFFER_SIZE 100

char receive_buffer[BUFFER_SIZE];
char receive_data;
int receive_index = NULL;
int data_ready_index = NULL;

void USART2_receive(void const * argument){
         for(;;){
                if(data_ready_index == 1){
                HAL_UART_Transmit_IT(&huart2, (uint8_t *)"Received data: ", strlen("Received data: "));
                HAL_Delay(50);
                HAL_UART_Transmit_IT(&huart2, (uint8_t *)receive_buffer, strlen(receive_buffer));
                memset(receive_buffer, NULL, sizeof(receive_buffer));
                HAL_Delay(50);
                HAL_UART_Transmit_IT(&huart2, (uint8_t *)"\r\n", strlen("\r\n"));
                data_ready_index = NULL;
                }
         }
     }

    void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {

        if (huart->Instance == USART2){
            if (receive_data != 13){
                receive_buffer[receive_index++]=receive_data;
            }else{
                    receive_index = NULL;
                    data_ready_index = 1;                                                               
                    // Received data ready to be processed
            }
      }
    }

    void USART2_IRQHandler(void){

      HAL_UART_IRQHandler(&huart2);
      HAL_UART_Receive_IT(&huart2, (uint8_t *) &receive_data, 1);
    }
\$\endgroup\$
18
  • \$\begingroup\$ What happens when you send it without the CR or in smaller chunks? \$\endgroup\$
    – Trevor_G
    Commented Jan 25, 2018 at 13:53
  • \$\begingroup\$ Funny that you say that you check for \n but your code is checking for \r which is 13 and you only process 13 bytes, but then why is strlen giving more than 13 and sends some 0x00 bytes with them (<0>) - the message you get back is the length of the transmitted message just the content of the last 3 bytes is wrong. \$\endgroup\$
    – Arsenal
    Commented Jan 25, 2018 at 13:54
  • \$\begingroup\$ @Trevor_G if i send in smaller chunks (less then 14) it is ok, everything works fine. And if i send without CR it doesn't appear at all. \$\endgroup\$ Commented Jan 25, 2018 at 14:02
  • \$\begingroup\$ Ya I meant if you send 12345678 then send 12345678 +CR what do you get back. \$\endgroup\$
    – Trevor_G
    Commented Jan 25, 2018 at 14:05
  • 2
    \$\begingroup\$ Good catch...thats exactly why things got worse at slower baudrate, overflow happened at the rxbuffer on PC side. \$\endgroup\$
    – Mitu Raj
    Commented Jan 25, 2018 at 15:16

2 Answers 2

2
\$\begingroup\$

I found the problem. In the void USART2_receive(void const * argument) function i increased delay from 50 to 100 and then everything works fine. As @MITURAJ mentioned this may be caused by buffer overflow.

void USART2_receive(void const * argument){
    for(;;){
        if(data_ready_index == 1){
            HAL_UART_Transmit_IT(&huart2, (uint8_t *)"Received data: ", 
            strlen("Received data: "));
            HAL_Delay(100);
            HAL_UART_Transmit_IT(&huart2, (uint8_t *)receive_buffer, 
            strlen(receive_buffer));
            HAL_Delay(100);
            HAL_UART_Transmit_IT(&huart2, (uint8_t *)"\r\n", strlen("\r\n"));
            data_ready_index = NULL;
            memset(receive_buffer, NULL, sizeof(receive_buffer));
        }
    }
}
\$\endgroup\$
2
  • 2
    \$\begingroup\$ What is the purpose of the delay, and why did increasing it fix the problem? \$\endgroup\$ Commented Jan 25, 2018 at 15:45
  • \$\begingroup\$ I just don't know how to mark someone comment as helpful answer \$\endgroup\$ Commented Jan 25, 2018 at 16:39
2
\$\begingroup\$

Finding that you need a longer delay should tip you off that you are not waiting for the Tx to actually finish. HAL_UART_Transmit_IT uses an interrupt to send bytes out (it is non-blocking). You are basically telling it to transmit, waiting a little bit, and cramming data into the buffer again before the transmit is done!

Instead I suggest that you monitor the callback to HAL_UART_TxCpltCallback and once that happens set some flag. In your USART2_receive function, wait for the flag to be set before asking it to send things again. Remember to clear the flag before waiting for it to be set again :)

\$\endgroup\$
3
  • \$\begingroup\$ Thank you for detail explanation, it quite tought to implement these changes as i am junior developer. Maybe there is any examples which i could follow for this feature? \$\endgroup\$ Commented Jan 31, 2018 at 17:50
  • \$\begingroup\$ @Into_Embedded, it is pretty straight forward, it is like the HAL_UART_RxCpltCallback function. The CubeMx probably generates the TxCpltCallback function for you and you just have to fill it out. Take a look at the STM32 examples too, there should be something there for non-blocking UART. \$\endgroup\$
    – Catsunami
    Commented Feb 1, 2018 at 23:27
  • \$\begingroup\$ i will definetly look into now it doesn't look so taught as it looked first. \$\endgroup\$ Commented Feb 1, 2018 at 23:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.