下载的F4的软件包:en.STM32Cube_FW_F4_V1.24.0。打开 .......\STM32F411\en.STM32Cube_FW_F4_V1.24.0\STM32Cube_FW_F4_V1.24.0\Projects\STM32F411RE-Nucleo\Examples\MyUART\UART_Printf\MDK-ARM,这是官方提供的样例,重命名后,打开后如下图:
再找到样例,路径为:......\en.STM32Cube_FW_F4_V1.24.0\STM32Cube_FW_F4_V1.24.0\Projects\STM32F411RE-Nucleo\Templates,可以重命名后,打开如下图:
根据说明文档的程序执行流程可知,相关的外设初始化和时钟初始化后,会进行回调进入HAL_MspInit(),参考如图:
这是移植的重点,HAL库是为上层应用设计的,所以有回调的机制。若是以寄存器的操作方式进行调试,编译后没有错误,甚至初始化也没有报错,但是串口无打印信息。下面进行代码的移植:
1、main.c 串口的初始化(在需要移植串口的工程中):
/* UART handler declaration */
UART_HandleTypeDef UartHandle;
......
......
UartHandle.Instance = USARTx;
UartHandle.Init.BaudRate = 9600;
UartHandle.Init.WordLength = UART_WORDLENGTH_8B;
UartHandle.Init.StopBits = UART_STOPBITS_1;
UartHandle.Init.Parity = UART_PARITY_NONE;// UART_PARITY_ODD
UartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE;
UartHandle.Init.Mode = UART_MODE_TX_RX;
UartHandle.Init.OverSampling = UART_OVERSAMPLING_16;//UART_OVERSAMPLING_8
if(HAL_UART_Init(&UartHandle) != HAL_OK)
{
/* Initialization Error */
Error_Handler();
}
因为Template工程里面的main.h已经包含了相关的文件,所以没有报错。
再加入测试用的指令:
char a[]="\n\rmyello\n\r";
......
......
HAL_UART_Transmit(&UartHandle,(uint8_t *)a, 5, 0xFFFF);
/* Infinite loop */
编译一下,没有问题,但是没有打印输出。不急,咱们先平复一下心情。
2、修改stm32f4xx_hal_msp.c(在需要移植串口的工程中):
为什么会找到这个文件进行修改呢,还是因为回调函数HAL_MspInit()在这个函数。在HAL库里,样例程序Templates相关的文件定义很清晰,如下:void HAL_MspInit(void),void HAL_MspDeInit(void)。只有 两个函数,当然清晰。然后参考UART_Printf工程对这两个函数进行填充,如下:
/**
* @brief Initializes the Global MSP.
* @param None
* @retval None
*/
void HAL_MspInit(void)
{
/* NOTE : This function is generated automatically by STM32CubeMX and eventually
modified by the user
*/
//这个函数在时钟设置完成后会进行回调
GPIO_InitTypeDef GPIO_InitStruct;
/*##-1- Enable peripherals and GPIO Clocks #################################*/
/* Enable GPIO TX/RX clock */
USARTx_TX_GPIO_CLK_ENABLE();
USARTx_RX_GPIO_CLK_ENABLE();
/* Enable USARTx clock */
USARTx_CLK_ENABLE();
/*##-2- Configure peripheral GPIO ##########################################*/
/* UART TX GPIO pin configuration */
GPIO_InitStruct.Pin = USARTx_TX_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FAST;
GPIO_InitStruct.Alternate = USARTx_TX_AF;
HAL_GPIO_Init(USARTx_TX_GPIO_PORT, &GPIO_InitStruct);
/* UART RX GPIO pin configuration */
GPIO_InitStruct.Pin = USARTx_RX_PIN;
GPIO_InitStruct.Alternate = USARTx_RX_AF;
HAL_GPIO_Init(USARTx_RX_GPIO_PORT, &GPIO_InitStruct);
}
/**
* @brief DeInitializes the Global MSP.
* @param None
* @retval None
*/
void HAL_MspDeInit(void)
{
/* NOTE : This function is generated automatically by STM32CubeMX and eventually
modified by the user
*/
/*##-1- Reset peripherals ##################################################*/
USARTx_FORCE_RESET();
USARTx_RELEASE_RESET();
/*##-2- Disable peripherals and GPIO Clocks #################################*/
/* Configure UART Tx as alternate function */
HAL_GPIO_DeInit(USARTx_TX_GPIO_PORT, USARTx_TX_PIN);
/* Configure UART Rx as alternate function */
HAL_GPIO_DeInit(USARTx_RX_GPIO_PORT, USARTx_RX_PIN);
}
这下在编译,串口打印结果:
3、printf进行重定义(main.c):
printf重定义用到1个函数:
HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)
然后在putf中进行重写,加入如下代码:
/* Private function prototypes -----------------------------------------------*/
#ifdef __GNUC__
/* With GCC, 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 EVAL_COM1 and Loop until the end of transmission */
HAL_UART_Transmit(&UartHandle, (uint8_t *)&ch, 1, 0xFFFF);
return ch;
}
好了,现在打印,效果如下:
例程密码:STM32F411RE-Nucleo
全部回复 0
暂无评论,快来抢沙发吧