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\$
  • \$\begingroup\$ What happens when you send it without the CR or in smaller chunks? \$\endgroup\$ – Trevor_G Jan 25 '18 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 Jan 25 '18 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\$ – Into_Embedded Jan 25 '18 at 14:02
  • \$\begingroup\$ Ya I meant if you send 12345678 then send 12345678 +CR what do you get back. \$\endgroup\$ – Trevor_G Jan 25 '18 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 Jan 25 '18 at 15:16
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
    \$\begingroup\$ What is the purpose of the delay, and why did increasing it fix the problem? \$\endgroup\$ – Bruce Abbott Jan 25 '18 at 15:45
  • \$\begingroup\$ I just don't know how to mark someone comment as helpful answer \$\endgroup\$ – Into_Embedded Jan 25 '18 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\$
  • \$\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\$ – Into_Embedded Jan 31 '18 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 Feb 1 '18 at 23:27
  • \$\begingroup\$ i will definetly look into now it doesn't look so taught as it looked first. \$\endgroup\$ – Into_Embedded Feb 1 '18 at 23:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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