1
\$\begingroup\$

I'm trying to develop a UART receiver/transmitter for an academic project. For now i developed the UART continuous data receiving part and it works quite well. Here is the code: Interrupt file:

extern volatile char RxData[10][8];
extern volatile uint8_t RxComplete;
extern volatile uint8_t RxCompleteOneRow;

extern volatile uint8_t ColumnRxBuffer;
extern volatile uint8_t RowRxBuffer;
void USART2_IRQHandler(void)
{
    //HAL_UART_IRQHandler(&huart2);

        if(RowRxBuffer < 9)
        {
            if(ColumnRxBuffer < 7)
            {
                RxData[RowRxBuffer][ColumnRxBuffer] = (uint8_t)(huart2.Instance->DR & (uint8_t)0xff);
                ColumnRxBuffer++;
            }
            else
            {
                RxData[RowRxBuffer][ColumnRxBuffer] = (uint8_t)(huart2.Instance->DR & (uint8_t)0xff);
                ColumnRxBuffer = 0;
                if(RowRxBuffer == 0)
                {
                    RxCompleteOneRow = 1;
                }
                RxComplete = 1;
                __HAL_UART_FLUSH_DRREGISTER(&huart2);
                RowRxBuffer++;
            }
        }
        else
        {
            if(ColumnRxBuffer < 7)
            {
                RxData[RowRxBuffer][ColumnRxBuffer] = (uint8_t)(huart2.Instance->DR & (uint8_t)0xff);
                ColumnRxBuffer++;
            }
            else
            {
                RxData[RowRxBuffer][ColumnRxBuffer] = (uint8_t)(huart2.Instance->DR & (uint8_t)0xff);
                ColumnRxBuffer = 0;
                RxComplete = 1;
                __HAL_UART_FLUSH_DRREGISTER(&huart2);
                RowRxBuffer = 0;
            //  tick = 0;

            }
        }

    return;
}

UART Config:

static void MX_USART2_UART_Init(void)
{

  huart2.Instance = USART2;
  huart2.Init.BaudRate = 9600;
  huart2.Init.WordLength = UART_WORDLENGTH_8B;
  huart2.Init.StopBits = UART_STOPBITS_1;
  huart2.Init.Parity = UART_PARITY_NONE;
  huart2.Init.Mode = UART_MODE_TX_RX;
  huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart2.Init.OverSampling = UART_OVERSAMPLING_16;
  if (HAL_UART_Init(&huart2) != HAL_OK)
  {
    Error_Handler();
  }

  __HAL_UART_ENABLE_IT(&huart2, UART_IT_RXNE);

}

The device needs to send some data over UART in non blocking mode, so i tryed to modify the code, using some if statement to check if the interrupt is generated from the incoming data or the completed transmission.

To do so i used if(__HAL_UART_GET_IT_SOURCE(&huart2, UART_IT_RXNE)) and if(__HAL_UART_GET_IT_SOURCE(&huart2, UART_IT_TC)) in the interrupt handler and adding __HAL_UART_ENABLE_IT(&huart2, UART_IT_TC); in the config function. Doing these modification the micro doesn't even start: it goes in an unknown state and remain stuck to it. Debugging the code step-by-step i noticed that the micro goes to this unknown state when it tries to turn on a LED, which is the first thing that does this code. If necessary i could upload the entire code.

What am i doing wrong?

For sake of readability, here it is the modified code that i mentioned before https://pastebin.com/qhS2JjLm

\$\endgroup\$
0
\$\begingroup\$

If you have nothing (more) to send, then you need to disable your UART_IT_TC interrupt. This interrupt flag is set whenever the UART Transmit buffer is empty, so since you don't even load anything into the Transmit buffer this flag will always be set, resulting in the micro continuously jumping to your interrupt handler and never executing any other code.

Do not __HAL_UART_ENABLE_IT(&huart2, UART_IT_TC); until you are ready to send data and __HAL_UART_DISABLE_IT(&huart2, UART_IT_TC); in your interrupt when you have finished sending.

You could also simplify your receive code a little by moving the line RxData[RowRxBuffer][ColumnRxBuffer] = (uint8_t)(huart2.Instance->DR & (uint8_t)0xff); which is duplicated 4 times for each of the conditions so that it's executed immediately after if(__HAL_UART_GET_IT_SOURCE(&huart2, UART_IT_RXNE)) before any of the if/else conditions.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Thank you for your answer and your suggestion. Now the micro starts, but it get stuck once jumps to these lines : if(strncmp(RxData[0], "HELLO___", 8) == 0) { __HAL_UART_ENABLE_IT(&huart2, UART_IT_TC); HAL_UART_Transmit_IT(&huart2, "HI______", 8); In paricular it remain stuck in the receiving part of the interrupt code, even if the micro sends data and doesn't receive, considering also that the receiver portion of the code is "if" protected. I know this because in debugging mode, the RxBuffer is constantly filled with underscores. What do you suggests? \$\endgroup\$ – RawCode Mar 20 at 11:09
  • \$\begingroup\$ Ok - hold on now - if you're using the ST library's HAL_UART_Transmit_IT() to send, why are you trying to write your own interrupt handler and not using the HAL_UART_IRQHandler() in the library code ... ? You need to choose one path or the other and not try to mix & match. Using HAL_UART_Init() to configure the port is fine either way. If you use the HAL library to transmit then you don't need to enable to TX interrupt because it does that for you. \$\endgroup\$ – brhans Mar 20 at 15:50
  • \$\begingroup\$ I suppose you could use the HAL library to transmit while using your code to receive - in which case I'd uncomment and move your commented out call to HAL_UART_IRQHandler(&huart2); down to the end of USART2_IRQHandler (and don't wrap it in any ifs). \$\endgroup\$ – brhans Mar 20 at 15:54
  • \$\begingroup\$ I used HAL_UART_Transmit_IT() because i don't know how to send messages without using that line. Reading is quite easy, since i need only to check a register, but what about transmitting? Thanks for the suggestion though. I noticed that, using the HAL_UART_IRQHandler(&huart2); and HAL_UART_Transmit_IT(), the HAL_GPIO_WritePin() call writes in my receiver buffer the underscores "_" that i mentioned before. These underscores mess up with my code, making the micro's behaviour impredictable. Why the HAL_GPIO_WritePin() call does this? \$\endgroup\$ – RawCode Mar 20 at 17:02
  • \$\begingroup\$ I noticed that even the HAL_Delay() writes to the receiver buffer also some underscores. \$\endgroup\$ – RawCode Mar 20 at 17:08

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.