Skip to main content
FEber.1
Associate II
August 13, 2021
Solved

STM32L052 USART: Problem Switchover from Output- to UART - TX - functionality produces a disturbing H/L - edge on TX

  • August 13, 2021
  • 4 replies
  • 1136 views

Two Usart - TX - lines shall be used either in PP- output- or in Usart - TX - mode.

The switchover from a normal output pin to a Uart - TX - pin produces

an High/ Low edge on TX followed by an interrupt on TX side.

On RX- side this H/L edge causes an unwanted Interrupt too. And that is the actual problem.

The cause is the following sequence

u32ModeBack = GPIOA->MODER;

u32ModeBack &= ~(GPIO_MODER_MODE2_Msk | GPIO_MODER_MODE15_Msk);      

u32ModeBack |= (0x02ul<<GPIO_MODER_MODE2_Pos);                  //Alternate output function

GPIOA->MODER = u32ModeBack;

Is there a possibility to avoid this additional output of pulses?

This topic has been closed for replies.
Best answer by FEber.1

Update:

Now I have achieved a clean switch from output to Uart-Tx by changing the order of IO initialization:

//RX + TX Pull Up

u32ModeBack = GPIOA->PUPDR;

u32ModeBack &= ~(GPIO_PUPDR_PUPD2_Msk | GPIO_PUPDR_PUPD15_Msk);

u32ModeBack |= (GPIO_PUPDR_PUPD2_0 | GPIO_PUPDR_PUPD15_0);            

GPIOA->PUPDR = u32ModeBack;

//Alternate function = Usart 2

GPIOA->AFR[0] &= ~(GPIO_AFRL_AFSEL2_Msk);                        

GPIOA->AFR[0] |= (GPIO_AF4_USART2<<GPIO_AFRL_AFSEL2_Pos);            

GPIOA->AFR[1] &= ~(GPIO_AFRH_AFSEL15_Msk);                        

GPIOA->AFR[1] |= (GPIO_AF4_USART2<<GPIO_AFRH_AFSEL15_Pos);        

   

//Switch to alternate function

u32ModeBack = GPIOA->MODER;

u32ModeBack &= ~(GPIO_MODER_MODE2_Msk | GPIO_MODER_MODE15_Msk);        

u32ModeBack |= (GPIO_MODER_MODE2_1 | GPIO_MODER_MODE15_1);          

GPIOA->MODER = u32ModeBack;

Many thanks for your help

4 replies

TDK
August 13, 2021

So it goes from a high GPIO pin, then low immediately when initialized as AF, then high again without changing anything?

Is the USART peripheral initialized prior to switching it to AF? External pullup present?

"If you feel a post has answered your question, please click ""Accept as Solution""."
waclawek.jan
Super User
August 13, 2021

> followed by an interrupt on TX side

What interrupt?

Post a minimal but complete compilable example exhibiting the problem.

JW

FEber.1
FEber.1Author
Associate II
August 16, 2021

Hi TDK and Jan,

Meantime I know, that from my point of view I made the error to use the flag

USART_ISR_TXE instead of USART_ISR_TC for controlling of usart - tx - interrupt - routine.

The flag USART_ISR_TXE created my initial problem: 

An interrupt without writing anything.

OK, now I useUSART_ISR_TC. That wastes time but is fast enough for max.19200 Baud.

The correct solution would be a combined using of USART_ISR_TC and USART_ISR_TXE I guess.

For the elimination of problem two I have taken into account the question of TDK regarding of pull-ups.

Before switching to alternate function the internal TX - pull up is switched on and some instruction

later switched off again. Perhaps this cast can be removed when I am more familiar with STM32- USARTs.

Many thank for your help 

FEber.1
FEber.1AuthorBest answer
Associate II
August 17, 2021

Update:

Now I have achieved a clean switch from output to Uart-Tx by changing the order of IO initialization:

//RX + TX Pull Up

u32ModeBack = GPIOA->PUPDR;

u32ModeBack &= ~(GPIO_PUPDR_PUPD2_Msk | GPIO_PUPDR_PUPD15_Msk);

u32ModeBack |= (GPIO_PUPDR_PUPD2_0 | GPIO_PUPDR_PUPD15_0);            

GPIOA->PUPDR = u32ModeBack;

//Alternate function = Usart 2

GPIOA->AFR[0] &= ~(GPIO_AFRL_AFSEL2_Msk);                        

GPIOA->AFR[0] |= (GPIO_AF4_USART2<<GPIO_AFRL_AFSEL2_Pos);            

GPIOA->AFR[1] &= ~(GPIO_AFRH_AFSEL15_Msk);                        

GPIOA->AFR[1] |= (GPIO_AF4_USART2<<GPIO_AFRH_AFSEL15_Pos);        

   

//Switch to alternate function

u32ModeBack = GPIOA->MODER;

u32ModeBack &= ~(GPIO_MODER_MODE2_Msk | GPIO_MODER_MODE15_Msk);        

u32ModeBack |= (GPIO_MODER_MODE2_1 | GPIO_MODER_MODE15_1);          

GPIOA->MODER = u32ModeBack;

Many thanks for your help