总结如何在 stm32 中使用 printf 函数的方法
两种方法 在 Stm32 中使用 printf 函数有两种方法:
不管什么方法,都不需要使用半主机模式。
所谓的半主机模式就是指:通过仿真器实现开发板在电脑上的输入和输出。
微库法 这个方法就是在 Keil5 中 Target 中选择使用 MicroLib。
如果使用这种方法,则只需要重定向一个 fputc 函数即可。
1 2 3 4 5 6 7 int fputc (int ch, FILE *f) { while ((USART1->SR & 0X40 ) == 0 ); USART1->DR = (uint8_t )ch; return ch; }
这样就可以使用 printf 函数了。
代码法 就是通过 USART 这个外设,来实现原来的函数 printf 的功能。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 #if SYS_SUPPORT_OS #include "os.h" #endif #if 1 #if (__ARMCC_VERSION >= 6010050) __asm(".global __use_no_semihosting\n\t" ); __asm(".global __ARM_use_no_argv \n\t" ); #else #pragma import(__use_no_semihosting) struct __FILE { int handle; };#endif int _ttywrch(int ch) { ch = ch; return ch; }void _sys_exit(int x) { x = x; }char *_sys_command_string(char *cmd, int len) { return NULL ; } FILE __stdout;int fputc (int ch, FILE *f) { while ((USART1->SR & 0X40 ) == 0 ); USART1->DR = (uint8_t )ch; return ch; }#endif
下面是对于 USART 的配置。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 #if USART_EN_RX uint8_t g_usart_rx_buf[USART_REC_LEN];uint16_t g_usart_rx_sta = 0 ;uint8_t g_rx_buffer[RXBUFFERSIZE]; UART_HandleTypeDef g_uart1_handle; void usart_init (uint32_t baudrate) { g_uart1_handle.Instance = USART_UX; g_uart1_handle.Init.BaudRate = baudrate; g_uart1_handle.Init.WordLength = UART_WORDLENGTH_8B; g_uart1_handle.Init.StopBits = UART_STOPBITS_1; g_uart1_handle.Init.Parity = UART_PARITY_NONE; g_uart1_handle.Init.HwFlowCtl = UART_HWCONTROL_NONE; g_uart1_handle.Init.Mode = UART_MODE_TX_RX; HAL_UART_Init(&g_uart1_handle); HAL_UART_Receive_IT(&g_uart1_handle, (uint8_t *)g_rx_buffer, RXBUFFERSIZE); }void HAL_UART_MspInit (UART_HandleTypeDef *huart) { GPIO_InitTypeDef gpio_init_struct; if (huart->Instance == USART_UX) { USART_UX_CLK_ENABLE(); USART_TX_GPIO_CLK_ENABLE(); USART_RX_GPIO_CLK_ENABLE(); gpio_init_struct.Pin = USART_TX_GPIO_PIN; gpio_init_struct.Mode = GPIO_MODE_AF_PP; gpio_init_struct.Pull = GPIO_PULLUP; gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH; gpio_init_struct.Alternate = USART_TX_GPIO_AF; HAL_GPIO_Init(USART_TX_GPIO_PORT, &gpio_init_struct); gpio_init_struct.Pin = USART_RX_GPIO_PIN; gpio_init_struct.Alternate = USART_RX_GPIO_AF; HAL_GPIO_Init(USART_RX_GPIO_PORT, &gpio_init_struct); #if USART_EN_RX HAL_NVIC_EnableIRQ(USART_UX_IRQn); HAL_NVIC_SetPriority(USART_UX_IRQn, 3 , 3 ); #endif } }void HAL_UART_RxCpltCallback (UART_HandleTypeDef *huart) { if (huart->Instance == USART_UX) { if ((g_usart_rx_sta & 0x8000 ) == 0 ) { if (g_usart_rx_sta & 0x4000 ) { if (g_rx_buffer[0 ] != 0x0a ) { g_usart_rx_sta = 0 ; } else { g_usart_rx_sta |= 0x8000 ; } } else { if (g_rx_buffer[0 ] == 0x0d ) { g_usart_rx_sta |= 0x4000 ; } else { g_usart_rx_buf[g_usart_rx_sta & 0X3FFF ] = g_rx_buffer[0 ] ; g_usart_rx_sta++; if (g_usart_rx_sta > (USART_REC_LEN - 1 )) { g_usart_rx_sta = 0 ; } } } } HAL_UART_Receive_IT(&g_uart1_handle, (uint8_t *)g_rx_buffer, RXBUFFERSIZE); } }void USART_UX_IRQHandler (void ) { #if SYS_SUPPORT_OS OSIntEnter(); #endif HAL_UART_IRQHandler(&g_uart1_handle); #if SYS_SUPPORT_OS OSIntExit();#endif }#endif