STM32 uses GPIO to simulate UART to print log

Note: The analog UART part of this article refers to the STM32 IO port analog serial communication , thank you here!

 

Since the 3 UARTs that come with the chip are all used up, I have to use GPIO to simulate the UART to print the log.

Using TIM3 for delay use, the configuration on STM32CubeMX is as follows:

The count period configuration bit is 65535, which is also the maximum value that can be configured.

Then in tim.c add:

void Delay_us(uint32_t us)
{
    __HAL_TIM_SET_COUNTER(&htim3, 0);
    HAL_TIM_Base_Start(&htim3);
    while (__HAL_TIM_GET_COUNTER(&htim3) < (72 * us)) ;


    HAL_TIM_Base_Stop(&htim3);
}

Since the clock of the timer is 72MHz, 1us is 72 clock cycles. Therefore, the above delay time should be multiplied by 72. In addition, since the maximum count period is 65535, the maximum delay time of this function is 65535/72=910us. We can also reduce the timer's input clock by modifying the value of Prescaler, thereby increasing the maximum delay time of the delay function, but this will reduce some delay accuracy.

The next step is to simulate the UART output. The following is to use the GPIO to simulate the UART output of a byte. The baud rate is 9600, so the cycle is about 104us.

void sendByte(uint8_t val)
{
    HAL_GPIO_WritePin(IO_TX_GPIO_Port, IO_TX_Pin, GPIO_PIN_RESET);
    Delay_us(104);

    for (int i = 0; i < 8; i++)
    {
        if (val & 0x01)
        {
            HAL_GPIO_WritePin(IO_TX_GPIO_Port, IO_TX_Pin, GPIO_PIN_SET);
        } else {
            HAL_GPIO_WritePin(IO_TX_GPIO_Port, IO_TX_Pin, GPIO_PIN_RESET);
        }
        Delay_us(104);
        val >>= 1;
    }
    HAL_GPIO_WritePin(IO_TX_GPIO_Port, IO_TX_Pin, GPIO_PIN_SET);
    Delay_us(104);
}

According to the actual measurement, it can run stably when the baud rate is 9600 (tested 120,000 bytes without error), while the baud rate of 19200 has a bit error rate of less than one thousandth.

Next, modify the redirection of prinf. It used to be redirected to UART1, but now it is changed to an analog UART.

 PUTCHAR_PROTOTYPE
 {
   /* Place your implementation of fputc here */
   /* e.g. write a character to the USART2 and Loop until the end of transmission */
-  HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF);
+    sendByte(ch);
 
   return ch;
 }

It's over!

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324987778&siteId=291194637