2021-08-13 09:04 AM
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?
Solved! Go to Solution.
2021-08-17 07:10 AM
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
2021-08-13 09:33 AM
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?
2021-08-13 01:33 PM
> followed by an interrupt on TX side
What interrupt?
Post a minimal but complete compilable example exhibiting the problem.
JW
2021-08-16 07:27 AM
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
2021-08-17 07:10 AM
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