cancel
Showing results for 
Search instead for 
Did you mean: 

IRDA Communication Problem - Unreasonable Recieved Data

selçuk Yolcu
Associate II
Posted on March 23, 2018 at 15:16

Hi,

    I'm trying to use simple IRDA IT communication.

I am using Interrupt to receive data. I set for 7 bytes to receive data and when 6th array  character is taken, I transmit data. But with second cycle, the received data is crashed by somethings. If receive data is used alone without transmit, then there is no problem, However, while either receive and transmit functions are used,  the received data became unreasonable. I use HAL functions How can I fix it?

The MCU is STM32L031G6Ux

the crashed Data is 'L;S&~�?'   instead of '1234567'

  main.c   -----  setting Recieve Data 

UART_HandleTypeDef hlpuart1;

IRDA_HandleTypeDef hirda2;

TIM_HandleTypeDef htim22;

void SystemClock_Config(void);

static void MX_GPIO_Init(void);

static void MX_USART2_IRDA_Init(void);

static void MX_LPUART1_UART_Init(void);

static void MX_TIM22_Init(void);

uint32_t count=0;

uint8_t RecievedData[7];

uint8_t FinalData[7];

uint8_t TransmitedData[] = 'Hello world!';

HAL_IRDA_StateTypeDef stat;

HAL_StatusTypeDef status;

int main(void)

{

HAL_Init();

SystemClock_Config();

MX_GPIO_Init();

MX_USART2_IRDA_Init();

MX_LPUART1_UART_Init();

MX_TIM22_Init();

HAL_TIM_Base_Init(&htim22);

HAL_TIM_Base_Start(&htim22);

HAL_IRDA_Receive_IT(&hirda2, RecievedData, sizeof(RecievedData));

while (1)

{

if (button == true)

   {   

        

HAL_IRDA_Transmit(&hirda2, TransmitedData, strlen(TransmitedData)-1, 100);

   }

}

}

... Other initialization

stm3210xx_it.c ------- Interrupt wait for data ------

 Recieve function is set for 7 bytes 

void USART2_IRQHandler(void)

{

/* USER CODE BEGIN USART2_IRQn 0 */

count = __HAL_TIM_GET_COUNTER(&htim22);   

// If time between two recieved data is bigger than 100 ms 

if (count > 100 )                                                 

// then reset RecievedData Array

{                                                                         

// Because, Sometimes data is '

1234

' instead of '

1234567

'

                                                                          /

/ And assume that second data is '

1234567

'

memset(RecievedData, 0, 7);                         

 // In this case with second data, function give me '

1234

123

'

IRDA_EndRxTransfer(&hirda2);                       

// And it continue in this synchronous (next data '

4567

123

')

IRDA_EndTxTransfer(&hirda2);                       

// This Block prevents this situation 

}

/* USER CODE END USART2_IRQn 0 */

HAL_IRDA_IRQHandler(&hirda2);

/* USER CODE BEGIN USART2_IRQn 1 */

stat = HAL_IRDA_GetState(&hirda2);

if (stat== HAL_IRDA_STATE_READY && RecievedData[6] != 0) 

   {

      for (int i=0; i<7; i++)                               

// if 7 bytes come, The recieve array to final array

         {

            FinalData[i]= RecievedData[i];

         }

     memset(RecievedData, 0, 7);                                                        

// Reset array

   }

if (stat== HAL_IRDA_STATE_RESET)

   {

      memset(RecievedData, 0, 7);

   }

__HAL_TIM_SET_COUNTER(&htim22, 0);                                   

// Reset Counter

HAL_IRDA_Receive_IT(&hirda2, RecievedData, 7);                     

// set Interruprt for next interrupt

/* USER CODE END USART2_IRQn 1 */

}

#hal-usart #hal #rx #irda #tx #hal-uart
1 ACCEPTED SOLUTION

Accepted Solutions
Mathieu Garivet
Associate III
Posted on March 26, 2018 at 08:12

How do you init the IRDA peripheral ? I had similar issues with a bad init. Use a 115200 baudrate, 8 bit, prescaler to 1, no parity on both sides of course.

Here is my init :

/* USART1 init function */

static void MX_USART1_IRDA_Init(void)

{

hirda1.Instance = USART1;

hirda1.Init.BaudRate = 115200;

hirda1.Init.WordLength = IRDA_WORDLENGTH_8B;

hirda1.Init.Parity = IRDA_PARITY_NONE;

hirda1.Init.Prescaler = 1;

hirda1.Init.PowerMode = IRDA_POWERMODE_NORMAL;

hirda1.Init.Mode = IRDA_MODE_TX_RX;

if (HAL_IRDA_Init(&hirda1) != HAL_OK)

{

        Error_Handler();

}

}

View solution in original post

5 REPLIES 5
Posted on March 23, 2018 at 16:06

Don't really see many IRDA questions these days.

You might need to more actively manage the state of your driver as the medium is half-duplex.

You could perhaps dig through some of the EVAL board support code, with from HAL, or earlier SPL, for IRDA examples.

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
selçuk Yolcu
Associate II
Posted on March 26, 2018 at 07:24

Actually, I set the prameters and functions via CubeMX and I tried simple example but it had same problem. Then, I have tried to fix problem but there is no way for solution which i could find. I really need to help. I added my source code to attachment.

________________

Attachments :

IRDA.rar : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006Hxs2&d=%2Fa%2F0X0000000b1Z%2FdHK7zG0KC8xG10.e_YfgUGt5A3PBy1.Oxuf14F7tqAA&asPdf=false
Mathieu Garivet
Associate III
Posted on March 26, 2018 at 08:12

How do you init the IRDA peripheral ? I had similar issues with a bad init. Use a 115200 baudrate, 8 bit, prescaler to 1, no parity on both sides of course.

Here is my init :

/* USART1 init function */

static void MX_USART1_IRDA_Init(void)

{

hirda1.Instance = USART1;

hirda1.Init.BaudRate = 115200;

hirda1.Init.WordLength = IRDA_WORDLENGTH_8B;

hirda1.Init.Parity = IRDA_PARITY_NONE;

hirda1.Init.Prescaler = 1;

hirda1.Init.PowerMode = IRDA_POWERMODE_NORMAL;

hirda1.Init.Mode = IRDA_MODE_TX_RX;

if (HAL_IRDA_Init(&hirda1) != HAL_OK)

{

        Error_Handler();

}

}

Posted on March 26, 2018 at 10:38

it can not work 115200 baudrate, it is 9600 in two side. After the prescaler value it correctly work (still 9600). Thank you

Posted on June 26, 2018 at 19:47

Thanks for the tip. The prescaler was set to 10 by the CubeMX configuration, baud rate 9600.The IrDA received lots of misread values. Once the prescaler was changed to 1, there were no misread values, all were correctly read.

I am not clear on what is the purpose of the prescaler. Is it a clock divider to achieve the desired baud rate? Or is it a parameter for filtering out glitches?