cancel
Showing results for 
Search instead for 
Did you mean: 

IR communication echo removal through turning interrupt on and off

Sagar  Lakhani
Associate
Posted on March 09, 2017 at 13:34

I am developing IR half duplex communication between two stm32f030 MCU, in the USART section, it is working as full duplex. i want that, whenever i receive anything from first usart, it is then sent to second usart. And to remove echo i want to turn off the usart receiving interrupt and turn it on as soon as it the data is sent to other usart. but the problem is when i do that, Echo is still received please give me any useful solution, i am attaching my code.

void USART2_IRQHandler(void)

{

USART_ITConfig(USART2, USART_IT_RXNE, DISABLE);

if( USART_GetITStatus(USART2, USART_IT_RXNE) ){

char t = USART2->RDR; // the character from the USART1 data register is saved in t

USART_SendData(USART1,t);

USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);

}

void USART1_IRQHandler(void)

{

USART_ITConfig(USART1, USART_IT_RXNE, DISABLE);

if( USART_GetITStatus(USART1, USART_IT_RXNE) ){

char t = USART1->RDR; // the character from the USART1 data register is saved in t

USART_SendData(USART2,t);

USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);

}

#usart #stm32f0
4 REPLIES 4
howard n2wx
Senior
Posted on March 09, 2017 at 15:46

USART_SendData() returns before the data leaves the transmitter's shift register, so here you're re-enabling the RXNE interrupt before the character ever leaves the uart:

USART_SendData(USART1,t);

USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);

USART_SendData(USART2,t);

USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);

Might want to use TXE and TC as a gate for ENABling RXNE.  Just don't spin wait for it in an ISR.

S.Ma
Principal
Posted on March 09, 2017 at 15:49

This example looks simple and dangerous.

What if the baud rate is different between these USART?

Are the interrupt priorities the same?

The pending interrupt, when occuring needs to be cleared by reading the DR. Trash it, save it or better, store it in a SW FIFO to feed the other peripheral.

Do the same on the reverse side with a RAM buffer and things might look better.

If there was no FIFO RAM buffer in the old days of DVD portable players, every bump on the road would stop the music...

Check in Cube Example if one of them is close to the required implementation to start from.

Sagar  Lakhani
Associate
Posted on March 10, 2017 at 05:32

As suggested by

i did a few modification.

void USART2_IRQHandler(void){USART_ITConfig(USART2, USART_IT_RXNE, DISABLE);if( USART_GetITStatus(USART2, USART_IT_RXNE) ){char t = USART2->RDR; // the character from the USART1 data register is saved in tUSART_SendData(USART1,t);while(!USART_GetFlagStatus(USART1, USART_FLAG_TC));USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);}void USART1_IRQHandler(void){USART_ITConfig(USART1, USART_IT_RXNE, DISABLE);if( USART_GetITStatus(USART1, USART_IT_RXNE) ){char t = USART1->RDR; // the character from the USART1 data register is saved in tUSART_SendData(USART2,t);while(!USART_GetFlagStatus(USART2, USART_FLAG_TC));USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);}�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

but still it is not working, I am reenabling the reciever interrupt when the transmission is complete. Please give suggestions.

Posted on March 13, 2017 at 17:28

Two suggestions-

1) Try disabling the receiver completely instead of disabling the RXNE interrupt. Disabling the int was a bad suggestion, it just delayed the inevitable.

2) Don't spin in the ISR waiting for TC to go true; wait outside of an ISR on TC and reenable the receiver when TC goes true. You'll probably have to do it in two simple but separate state machines.