STM32 serial port debugging notes

Phenomenon : After the stm32 is reset, the first byte printed by the serial port is wrong or disappears.

Reason : Bit errors are mostly due to problems with port initialization. When using the standard library of ST official v3.5, the serial port output port has been repeatedly initialized.

The following code:

    /* PA[15:0] set as push-pull output*/
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    /* Serial port TX port PA9 is set to multiplex push-pull output*/
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

 It can be seen that the PA9 pin where the serial TX port is located has been initialized twice, which will result in an error in the first byte.

Error code solution : The above program is obviously to use GPIO_Pin_All to be lazy, if it is written one by one, it will be fine. Or it is also possible to manipulate the registers directly.

What happened to the situation where the first byte disappeared? First look at the data sheet.

 

 Generally, the sending code of our serial port query method is as follows, including the implementation of the printf serial port printing in the ST official routine.

{
    USART_SendData(USART1, dat);
    /* Loop until the end of transmission */
    while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET)
    {}
}

 Combining the above diagram and program is easy to spot the problem.

The reset value of the 'TXE' and 'TC' flags are both '1'.
 Then when we write the first byte to the USART_DR register through the USART_SendData function after the reset, and then query the TC flag through the while, because the initial value of the TC is '1', we jump out of the while directly, even if the serial port does not have any Start sending! This is how the first byte is skipped. .

The solution for the disappearance of the first byte : before calling the USART _SendData function, clear the 'TC' flag to '0' and it is OK. The code is as follows

 

{
    USART_ClearFlag(USART1, USART_FLAG_TC);
    USART_SendData(USART1, dat);
    /* Loop until the end of transmission */
    while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET)
    {}
}

 

 ----------------------------------------------------------------printf-----------------------------------------------------------------

 

Use the printf function in keil, ST official has routines, you need to add the following code to main.c:

 

#include <stdio.h>

#ifdef __GNUC__
/* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf
   set to 'Yes') calls __io_putchar() */
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /* __GNUC__ */

/**
  * @brief  Retargets the C library printf function to the USART.
  * @param  None
  * @retval None
  */
PUTCHAR_PROTOTYPE
{
    /* Place your implementation of fputc here */
    /* e.g. write a character to the USART */
    USART_ClearFlag(USART1, USART_FLAG_TC);
    USART_SendData(USART1, (uint8_t) ch);

    /* Loop until the end of transmission */
    while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET)
    {}

    return ch;
}

 Note: You also need to add MicroLib to the settings to be able to use the printf function normally! ! ! As shown below

 

 

 

 

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=327092687&siteId=291194637