NUCLEO-F411RE 开发板自带仿真器,可以实现程序的下载,确实是个好的方案设计。同时,这个接口还能用作串口。对于后面的程序调试很有必要进行串口的移植。另外,在库文件的DOC文件里面有这样一句话“The STM32Cube HAL and LL drivers are the replacement of the standard peripheral library”,那么我们也是应该从标准库里面抬起头看看HAL和LL了。
1.JPG
  下载的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,这是官方提供的样例,重命名后,打开后如下图:
2.JPG
再找到样例,路径为:......\en.STM32Cube_FW_F4_V1.24.0\STM32Cube_FW_F4_V1.24.0\Projects\STM32F411RE-Nucleo\Templates,可以重命名后,打开如下图:
3.JPG
根据说明文档的程序执行流程可知,相关的外设初始化和时钟初始化后,会进行回调进入HAL_MspInit(),参考如图:
4.JPG
这是移植的重点,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);
}
这下在编译,串口打印结果:
5.JPG
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;
}
好了,现在打印,效果如下:
6.JPG
例程密码:STM32F411RE-Nucleo
附件.zip (1009.41 KB, 下载次数: 10)
全部回复 0
暂无评论,快来抢沙发吧