Skip to main content
Graduate II
June 26, 2024
Solved

Problem with UART interrupt

  • June 26, 2024
  • 7 replies
  • 2955 views

Hi,

I have two MCU communicating with each other via RS485. It's a very simple code one MCU send a data to other and the other is trying to receive this.

 

With MCU2 code everything is fine. It sends data like it should be.

Problem is with MCU1 code. When I delete #65 line in code (that one with HAL_UART_Transmit...) it works great. It receive data from MCU2 and starts engine and horn. But when I add this line it stop working. I dont understand why this is happening.

When the MCU2 works as a receiver everything is ok, but when I try to send something from it suddenly the whole uart stops working

 

MCU1 code:

/* USER CODE BEGIN 0 */


uint8_t buffer[2];
uint8_t ZERO[2]={0x00,0x00};
uint8_t AA[2]={0xAA,0xAA};
uint8_t BB[2]={0xBB,0xBB};

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{

if(buffer[0]==0xCC && buffer[1]==0xCC)
{
	Engine(ON);
}

if(buffer[0]==0xDD && buffer[1]==0xDD)
{
	Horn(ON);
}


HAL_UART_Receive_IT(&huart2, buffer, 2);
}



/* USER CODE END 0 */

/**
 * @brief The application entry point.
 * @retval int
 */
int main(void)
{
 /* USER CODE BEGIN 1 */


 /* USER CODE END 1 */

 /* MCU Configuration--------------------------------------------------------*/

 /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
 HAL_Init();

 /* USER CODE BEGIN Init */

 /* USER CODE END Init */

 /* Configure the system clock */
 SystemClock_Config();

 /* USER CODE BEGIN SysInit */

 /* USER CODE END SysInit */

 /* Initialize all configured peripherals */
 MX_GPIO_Init();
 //MX_I2C1_Init();
 MX_USART2_UART_Init();
 /* USER CODE BEGIN 2 */


 transceiver(WRITE);
 HAL_UART_Transmit(&huart2, ZERO, 2, 10); 
 transceiver(READ);
 HAL_UART_Receive_IT(&huart2, buffer, 2);




 /* USER CODE END 2 */

 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {



 /* USER CODE END WHILE */

 /* USER CODE BEGIN 3 */
 }
 /* USER CODE END 3 */
}

 

MCU2 code:

/* USER CODE BEGIN 0 */


uint8_t CC[2]={0xCC,0xCC};
uint8_t DD[2]={0xDD,0xDD};


/* USER CODE END 0 */

/**
 * @brief The application entry point.
 * @retval int
 */
int main(void)
{
 /* USER CODE BEGIN 1 */


 /* USER CODE END 1 */

 /* MCU Configuration--------------------------------------------------------*/

 /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
 HAL_Init();

 /* USER CODE BEGIN Init */

 /* USER CODE END Init */

 /* Configure the system clock */
 SystemClock_Config();

 /* USER CODE BEGIN SysInit */

 /* USER CODE END SysInit */

 /* Initialize all configured peripherals */
 MX_GPIO_Init();
 MX_USART1_UART_Init();
 MX_USART2_UART_Init();
 /* USER CODE BEGIN 2 */


 HAL_Delay(1000);
 transceiver(WRITE);
 HAL_UART_Transmit(&huart2, CC, 2, 10);
 HAL_Delay(1000);
 HAL_UART_Transmit(&huart2, DD, 2, 10);
 transceiver(READ);


 /* USER CODE END 2 */

 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {

 /* USER CODE END WHILE */

 /* USER CODE BEGIN 3 */
 }
 /* USER CODE END 3 */
}

 

    This topic has been closed for replies.
    Best answer by Raf_al

    Ok, so i tried with HAL_UART_Transmit_IT but it didnt work.

    By accident I disconnected my oscilloscope from MCU1 UART lines and now it works.:grinning_face_with_sweat:

     

    7 replies

    Graduate II
    June 26, 2024

    Instrument the code so you have some idea as to what's going on

    Does HAL_UART_Receive_IT() return an error in any of these case?

    Is there an error or status flagged by the UART that needs to be cleared for reception to work? Are you clearing it?

    Graduate II
    June 26, 2024

    You don't check for HAL status on any of the HAL calls so how do you know what is happening?

     

     if(HAL_UART_Transmit(&huart2, ZERO, 2, 10) != HAL_OK)
     {
     // Do some error handling
     } 
    
     if(HAL_UART_Receive_IT(&huart2, buffer, 2) != HAL_OK)
     {
     // Do some error handling
     }
    

     

     

    And what do these do?

     

    transceiver(WRITE);
    transceiver(READ);

     

     

     

     

     

    Raf_alAuthor
    Graduate II
    June 27, 2024

    I modified MCU1 code a little bit.

    /* USER CODE BEGIN 0 */
    
    
    uint8_t buffer[2];
    uint8_t ZERO[2]={0x00,0x00};
    uint8_t AA[2]={0xAA,0xAA};
    uint8_t BB[2]={0xBB,0xBB};
    
    
    void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
    {
    
    if(buffer[0]==0xCC && buffer[1]==0xCC)
    {
    	LED1(ON);
    }
    
    if(buffer[0]==0xDD && buffer[1]==0xDD)
    {
    	LED2(ON);
    }
    if(buffer[0]==0xEE && buffer[1]==0xEE)
    {
    	LED1(OFF);
    	LED2(OFF);
    }
    
    
    if((HAL_UART_Receive_IT(&huart2, buffer, 2))==!HAL_OK)
    		{
    	LED3(ON);
    		}
    
    }
    
    
    
    /* USER CODE END 0 */
    
    /**
     * @brief The application entry point.
     * @retval int
     */
    int main(void)
    {
     /* USER CODE BEGIN 1 */
    
    
     /* USER CODE END 1 */
    
     /* MCU Configuration--------------------------------------------------------*/
    
     /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
     HAL_Init();
    
     /* USER CODE BEGIN Init */
    
     /* USER CODE END Init */
    
     /* Configure the system clock */
     SystemClock_Config();
    
     /* USER CODE BEGIN SysInit */
    
     /* USER CODE END SysInit */
    
     /* Initialize all configured peripherals */
     MX_GPIO_Init();
     //MX_I2C1_Init();
     MX_USART2_UART_Init();
     /* USER CODE BEGIN 2 */
    
    
     transceiver(WRITE);
     if((HAL_UART_Transmit(&huart2, ZERO, 2, 10))==!HAL_OK)
    		LED3(ON);
     transceiver(READ);
     HAL_UART_Receive_IT(&huart2, buffer, 2);
    
    
    
    
     /* USER CODE END 2 */
    
     /* Infinite loop */
     /* USER CODE BEGIN WHILE */
     while (1)
     {
    
    
    
     /* USER CODE END WHILE */
    
     /* USER CODE BEGIN 3 */
     }
     /* USER CODE END 3 */
    }

    On MCU2 I have 3 switches. When I push down first switch it sends {0xCC,0xCC}, second switch {0xDD,0xDD} and third switch {0xEE,0xEE}.

    LED3 is off, so everytime status of HAL_UART_Transmist and HAL_UART_Receive_IT is HAL_OK.

     

    Something I saw is that if I press the button once, LED 1 or 2 doesn't light up, but if I press it twice, it does. In the same way to off the LEDs I need two presses.

    It's as if HAL_UART_Receive_IT is configured to a 4 byte buffer and not a 2 byte buffer.

    Graduate II
    June 27, 2024

    You still didn't answer my last question

    Raf_alAuthor
    Graduate II
    June 27, 2024

    Right,

    transceiver(WRITE);
    transceiver(READ);

    That just sets the state of the rs485 transceiver.

    Transceiver (WRITE) sets 1 on the pin to send data

    Transceiver (READ) sets 0 on the pin to receive data

    Generally this function works well I looked it up on an oscilloscope.

    Super User
    June 27, 2024

    @Raf_al wrote:

    With MCU2 code everything is fine. It sends data like it should be.


    How have you proved that?

    Raf_alAuthor
    Graduate II
    June 27, 2024

    I can see on the oscilloscope that it sends, for example, these {0xDD,0xDD} when I press the button. I just decode the whole frame. It's simple UART 8n1

    Graduate II
    June 27, 2024

    Is the Transceiver (READ) switching fast enough before the other MCU replies? Check with oscilloscope.

     

    Maybe try this approach

     /* Initialize all configured peripherals */
     MX_GPIO_Init();
     MX_USART2_UART_Init();
     /* USER CODE BEGIN 2 */
    
     
     HAL_UART_Receive_IT(&huart2, buffer, 2); // enable first
    
    	transceiver(WRITE);
    	if((HAL_UART_Transmit_IT(&huart2, ZERO, 2)) != HAL_OK) // use transsmit interrupt
    		LED3(ON);
     
    
     /* USER CODE END 2 */
    
     /* Infinite loop */
     /* USER CODE BEGIN WHILE */
     while (1)
     {
     /* USER CODE END WHILE */
    
     /* USER CODE BEGIN 3 */
     }
     /* USER CODE END 3 */
    }
    
    void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
    {
    	transceiver(READ);
    }

     

     

     

    Raf_alAuthor
    Graduate II
    June 27, 2024

    I think that problem is somewhere else. I can press that button (button that sends 0xDD for example) 10 seconds after MCU1 goes to tranceiver read mode.

    Super User
    June 27, 2024

    @Raf_al wrote:

    I think ...


    It's good to have a theory. :thumbs_up:

    Now you need to devise a test to prove whether your theory is correct or not ...

    See The Scientific Approach to Debugginghttp://www.8052mcu.com/faqs/120313 

    Raf_alAuthorAnswer
    Graduate II
    June 28, 2024

    Ok, so i tried with HAL_UART_Transmit_IT but it didnt work.

    By accident I disconnected my oscilloscope from MCU1 UART lines and now it works.:grinning_face_with_sweat: