如何让printf语句从指定的端口打印信息,本章节为你解锁……
一、直接上代码说明
我使用的AliOS Things Developer Kit,硬件上使用LPUART1(PB10/PB11)作为串口输出。
也可以根据具体情况配置其它UART。
UART_HandleTypeDef hlpuart1;
//初始化串口LPUART1
void MX_LPUART1_UART_Init(void)
{
hlpuart1.Instance = LPUART1;
hlpuart1.Init.BaudRate = 115200;
hlpuart1.Init.WordLength = UART_WORDLENGTH_8B;
hlpuart1.Init.StopBits = UART_STOPBITS_1;
hlpuart1.Init.Parity = UART_PARITY_NONE;
hlpuart1.Init.Mode = UART_MODE_TX_RX;
hlpuart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
//hlpuart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
//hlpuart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
if (HAL_UART_Init(&hlpuart1) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
}
//重写HAL_UART_MspInit
void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
{
GPIO_InitTypeDef GPIO_InitStruct;
if(uartHandle->Instance==LPUART1)
{
/* USER CODE BEGIN LPUART1_MspInit 0 */
__HAL_RCC_GPIOB_CLK_ENABLE(); //特别注意,我参考的alios thing中代码,没有这句,导致串口没有输出,这里添加这句后就OK了
/* USER CODE END LPUART1_MspInit 0 */
/* LPUART1 clock enable */
__HAL_RCC_LPUART1_CLK_ENABLE();
/**LPUART1 GPIO Configuration
PB10 ------> LPUART1_RX
PB11 ------> LPUART1_TX
*/
GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_11;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF8_LPUART1;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* LPUART1 interrupt Init */
HAL_NVIC_SetPriority(LPUART1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(LPUART1_IRQn);
/* USER CODE BEGIN LPUART1_MspInit 1 */
/* USER CODE END LPUART1_MspInit 1 */
}
}
// 重写write函数, printf时最终会调用这个函数。这里类似keil ARMCC中的fputc函数
int _write(int file, char *ptr, int len)
{
int i=0;
for (i = 0; i < len; i++)
{
while (!(LPUART1->ISR & USART_ISR_TXE))
{
}
LPUART1->TDR = ptr[i];
}
return len;
}
// main函数实现
int main(void)
{
HAL_Init();
/* Configure the System clock to have a frequency of 80 MHz */
SystemClock_Config();
/* Add your application code here
*/
MX_LPUART1_UART_Init();
/* Infinite loop */
while (1)
{
printf("Hello world!\n");
fflush(stdout); //如果printf函数最后不添加"\n",信息不会打印出来,所以这里需要添加这一句
/* Insert delay 500 ms */
HAL_Delay(500);
}
}
// 以下为系统初始化代码,保证系统能运行即可,与printf重定向无关,仅供参考
/**
* @brief System Clock Configuration
* The system Clock is configured as follow :
* System Clock source = PLL (MSI)
* SYSCLK(Hz) = 80000000
* HCLK(Hz) = 80000000
* AHB Prescaler = 1
* APB1 Prescaler = 1
* APB2 Prescaler = 1
* MSI Frequency(Hz) = 4000000
* PLL_M = 1
* PLL_N = 40
* PLL_R = 2
* PLL_P = 7
* PLL_Q = 4
* Flash Latency(WS) = 4
* @param None
* @retval None
*/
static void SystemClock_Config(void)
{
RCC_ClkInitTypeDef RCC_ClkInitStruct;
RCC_OscInitTypeDef RCC_OscInitStruct;
/* MSI is enabled after System reset, activate PLL with MSI as source */
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI;
RCC_OscInitStruct.MSIState = RCC_MSI_ON;
RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_6;
RCC_OscInitStruct.MSICalibrationValue = RCC_MSICALIBRATION_DEFAULT;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_MSI;
RCC_OscInitStruct.PLL.PLLM = 1;
RCC_OscInitStruct.PLL.PLLN = 40;
RCC_OscInitStruct.PLL.PLLR = 2;
RCC_OscInitStruct.PLL.PLLP = 7;
RCC_OscInitStruct.PLL.PLLQ = 4;
if(HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
/* Initialization Error */
while(1);
}
/* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2
clocks dividers */
RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if(HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK)
{
/* Initialization Error */
while(1);
}
}
二、Makefile注意事项
需要用到一些lib。libc.a\libgcc.a等
在使用 arm gcc 编译链接的过程可能会出现错误undefined reference to `_sbrk' `_close' `_fstat' `_read' `_write' 。
添加以下链接参数:
-std=gun99
--specs=nano.specs //使用静态库 libc_nano.a
--specs=nosys.specs //使用静态库 libnosys.a
我使用的编译参数参考如下:
# 使用了编译优化和硬件浮点数
CFLAGS += -mcpu=$(CPU) -mthumb -Wall
CFLAGS += -mfloat-abi=hard -mfpu=fpv4-sp-d16
CFLAGS += -Os
CFLAGS += -ffunction-sections -fdata-sections -std=c99
LFLAGS += -mcpu=$(CPU) -mthumb
LFLAGS += -mfloat-abi=hard -mfpu=fpv4-sp-d16
LFLAGS += -Wl,--gc-sections
# link libgcc.a libc.a libm.a
LFLAGS += -lgcc -lc -lm --specs=nosys.specs --specs=nano.specs -std=c99
# generate map file
LFLAGS += -Wl,-Map,$(TARGET).map
三、参考文档
stm32 基于ARM GCC Compliler(EmBitz IDE) print重定向到串口打印输出 com serial https://blog.csdn.net/daxiebao/article/details/52651891
STM32高级开发(12)-在GCC中使用printf打印串口数据 https://blog.csdn.net/zhengyangliu123/article/details/54966402