目录
1. 下载HAL 库
2. 配置工程
3. 测试
STM32F407_Discovery这个板子可快速搭建音频开发相关,无论是官方的参数示例,或者是HAL库代码中给出的示例,都不带串口调试这部分的,音频开发涉及IIC/IIS以及PDM麦克风等模块,GPIO口有限,很多具有串口复用功能的GPIO都给了其他模块,如果强制配成串口进行调试,音频链路运行的过程中输出就会不正常,开发过程中使用其他调试手段也可以,但是个人感觉串口有时候更容易排查,更直观。
经过尝试和代码的详细排查,发现运行实例Audio_playback_and_record的时候,串口2的tx可用,对应的GPIO是PA2。
本文基于STM32 HAL 库版本:STM32Cube_FW_F4_V1.27.0
下载链接:https://www.st.com/en/embedded-software/stm32cubef4.html
下载需要注册一个ST账户,两个资源包都要下载,然后解压到同一个目录即可:
Audio_playback_and_record是官方自带的一个音频开发示例,接下来要添加串口打印功能。
在配置文件stm32f4xx_hal_conf.h中将uart模块功能打开:
STM32F4-Discovery\Applications\Audio\Audio_playback_and_record\Inc\stm32f4xx_hal_conf.h
工程中加入uart的hal库驱动文件:stm32f4xx_hal_uart.c
在用户src目录下新增一个文件uart2.c,代码如下:
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* UART handler declaration */
UART_HandleTypeDef UartHandle;
//重写printf底层函数接口
int fputc(int c, FILE *stream)
{
USART2->DR=c; //发送一个字符
while(!(USART2->SR&1<<7)){}
return c;
}
//重写scanf底层函数接口 /* 不要配rx功能,因为rx引脚和其他模块有冲突 */
//int fgetc(FILE *stream)
//{
// while(!(USART2->SR&1<<5)){}
// return USART2->DR;
//}
int uart2_init(uint32_t BaudRate)
{
/*##-1- Configure the UART peripheral ######################################*/
/* Put the USART peripheral in the Asynchronous mode (UART Mode) */
/* UART1 configured as follow:
- Word Length = 8 Bits
- Stop Bit = One Stop bit
- Parity = None
- BaudRate = 9600 baud
- Hardware flow control disabled (RTS and CTS signals) */
UartHandle.Instance = USARTx;
UartHandle.Init.BaudRate = BaudRate;
UartHandle.Init.WordLength = UART_WORDLENGTH_8B;
UartHandle.Init.StopBits = UART_STOPBITS_1;
UartHandle.Init.Parity = UART_PARITY_NONE;
UartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE;
// UartHandle.Init.Mode = UART_MODE_TX_RX;
UartHandle.Init.Mode = UART_MODE_TX;
UartHandle.Init.OverSampling = UART_OVERSAMPLING_16;
if(HAL_UART_Init(&UartHandle) != HAL_OK)
{
return HAL_ERROR;
}
return HAL_OK;
}
对应地在用户目录inc下新增一个文件uart2.h:
#ifndef __UART2_H__
#define __UART2_H__
#include "stm32f4xx_hal.h"
int uart2_init(uint32_t BaudRate);
#endif /* __UART2_H__ */
在用户目录inc下的main.h新增代码,主要是定义了复用功能串口的GPIO,新增部分代码如下:
#include "uart2.h"
....................
....................
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* User can use this section to tailor USARTx/UARTx instance used and associated
resources */
/* Definition for USARTx clock resources */
#define USARTx USART2
#define USARTx_CLK_ENABLE() __HAL_RCC_USART2_CLK_ENABLE();
#define USARTx_RX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
#define USARTx_TX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
#define USARTx_FORCE_RESET() __HAL_RCC_USART2_FORCE_RESET()
#define USARTx_RELEASE_RESET() __HAL_RCC_USART2_RELEASE_RESET()
/* Definition for USARTx Pins */
#define USARTx_TX_PIN GPIO_PIN_2
#define USARTx_TX_GPIO_PORT GPIOA
#define USARTx_TX_AF GPIO_AF7_USART2
#define USARTx_RX_PIN GPIO_PIN_3
#define USARTx_RX_GPIO_PORT GPIOA
#define USARTx_RX_AF GPIO_AF7_USART2
/* Exported macro ------------------------------------------------------------*/
#define COUNTOF(__BUFFER__) (sizeof(__BUFFER__) / sizeof(*(__BUFFER__)))
/* Exported functions ------------------------------------------------------- */
main.h完整代码如下:
/**
******************************************************************************
* @file Audio/Audio_playback_and_record/Inc/main.h
* @author MCD Application Team
* @brief Header for main.c module.
******************************************************************************
* @attention
*
* Copyright (c) 2017 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __MAIN_H
#define __MAIN_H
/* Includes ------------------------------------------------------------------*/
#include "stm32f4xx_hal.h"
#include "stm32f4_discovery.h"
#include "stm32f4_discovery_audio.h"
#include "stm32f4_discovery_accelerometer.h"
#include
#include "stm32f4xx_it.h"
#include "waveplayer.h"
#include "waverecorder.h"
#include "ff.h"
#include "ff_gen_drv.h"
#include "usbh_diskio_dma.h"
#include "uart2.h"
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* Uncomment this define to disable repeat feature */
/* #define PLAY_REPEAT_DISABLED */
typedef enum
{
APPLICATION_IDLE = 0,
APPLICATION_START,
APPLICATION_RUNNING,
}
MSC_ApplicationTypeDef;
/* You can change the Wave file name as you need, but do not exceed 11 characters */
#define WAVE_NAME "0:audio_sample.wav"
#define REC_WAVE_NAME "0:rec.wav"
/* State Machine for the USBH_USR_ApplicationState */
#define USBH_USR_FS_INIT ((uint8_t)0x00)
#define USBH_USR_AUDIO ((uint8_t)0x01)
/* Defines for the Audio used commands */
#define CMD_PLAY ((uint32_t)0x00)
#define CMD_RECORD ((uint32_t)0x01)
#define CMD_STOP ((uint32_t)0x02)
/* Defines for LEDs lighting */
#define LED3_TOGGLE 0x03 /* Toggle LED3 */
#define LED4_TOGGLE 0x04 /* Toggle LED4 */
#define LED6_TOGGLE 0x06 /* Toggle LED6 */
#define LEDS_OFF 0x07 /* Turn OFF all LEDs */
#define STOP_TOGGLE 0x00 /* Stop LED Toggling */
/* Defines for the Audio playing process */
#define PAUSE_STATUS ((uint32_t)0x00) /* Audio Player in Pause Status */
#define RESUME_STATUS ((uint32_t)0x01) /* Audio Player in Resume Status */
#define IDLE_STATUS ((uint32_t)0x02) /* Audio Player in Idle Status */
#define REPEAT_ON ((uint32_t)0x00) /* Replay Status in ON */
#define REPEAT_OFF ((uint32_t)0x01) /* Replay Status in OFF */
/* Defines for MEMS Acclerometer ID Types */
#define MEMS_LIS3DSH 0x3F /* LIS3DSH MEMS Acclerometer ID */
#define MEMS_LIS302DL 0x3B /* LIS302DL MEMS Acclerometer ID */
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
void Error_Handler(void);
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* User can use this section to tailor USARTx/UARTx instance used and associated
resources */
/* Definition for USARTx clock resources */
#define USARTx USART2
#define USARTx_CLK_ENABLE() __HAL_RCC_USART2_CLK_ENABLE();
#define USARTx_RX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
#define USARTx_TX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
#define USARTx_FORCE_RESET() __HAL_RCC_USART2_FORCE_RESET()
#define USARTx_RELEASE_RESET() __HAL_RCC_USART2_RELEASE_RESET()
/* Definition for USARTx Pins */
#define USARTx_TX_PIN GPIO_PIN_2
#define USARTx_TX_GPIO_PORT GPIOA
#define USARTx_TX_AF GPIO_AF7_USART2
#define USARTx_RX_PIN GPIO_PIN_3
#define USARTx_RX_GPIO_PORT GPIOA
#define USARTx_RX_AF GPIO_AF7_USART2
/* Exported macro ------------------------------------------------------------*/
#define COUNTOF(__BUFFER__) (sizeof(__BUFFER__) / sizeof(*(__BUFFER__)))
/* Exported functions ------------------------------------------------------- */
#endif /* __MAIN_H */
最后在用户src目录下,新增文件:stm32f4xx_hal_msp.c,重写一些初始化API,主要是对GPIO的初始化操作,该文件内容如下:
/**
******************************************************************************
* @file UART/UART_TwoBoards_ComPolling/Src/stm32f4xx_hal_msp.c
* @author MCD Application Team
* @version V1.2.5
* @date 29-January-2016
* @brief HAL MSP module.
******************************************************************************
* @attention
*
* © COPYRIGHT(c) 2016 STMicroelectronics
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of STMicroelectronics nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/** @addtogroup STM32F4xx_HAL_Examples
* @{
*/
/** @defgroup UART_TwoBoards_ComPolling
* @{
*/
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/** @defgroup HAL_MSP_Private_Functions
* @{
*/
/**
* @brief UART MSP Initialization
* This function configures the hardware resources used in this example:
* - Peripheral's clock enable
* - Peripheral's GPIO Configuration
* @param huart: UART handle pointer
* @retval None
*/
void HAL_UART_MspInit(UART_HandleTypeDef *huart)
{
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 USART2 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_NOPULL;
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 UART MSP De-Initialization
* This function frees the hardware resources used in this example:
* - Disable the Peripheral's clock
* - Revert GPIO configuration to their default state
* @param huart: UART handle pointer
* @retval None
*/
void HAL_UART_MspDeInit(UART_HandleTypeDef *huart)
{
/*##-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);
}
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
注:不配rx功能,到此为止,已经实现了串口2的初始化以及GPIO的初始化。用户src目录下新增两个文件:
main.c测试代码如下:
/* Includes ------------------------------------------------------------------*/
#include "main.h"
static void SystemClock_Config(void);
int main(void)
{
/* STM32F4xx HAL library initialization:
- Configure the Flash prefetch, instruction and Data caches
- Configure the Systick to generate an interrupt each 1 msec
- Set NVIC Group Priority to 4
- Global MSP (MCU Support Package) initialization
*/
HAL_Init();
/* Configure LED3, LED4, LED5 and LED6 */
BSP_LED_Init(LED3);
BSP_LED_Init(LED4);
BSP_LED_Init(LED5);
BSP_LED_Init(LED6);
/* Configure the system clock to 168 MHz */
SystemClock_Config();
/* 串口2初始化: 只用tx功能 */
if(uart2_init(9600))
{
Error_Handler();
}
printf("main\n");
while(1) {
BSP_LED_On(LED6);
HAL_Delay(1000);
BSP_LED_Off(LED6);
HAL_Delay(1000);
printf("main: %d\n", 666);
}
return 0;
}
/**
* @brief System Clock Configuration
* The system Clock is configured as follow :
* System Clock source = PLL (HSE)
* SYSCLK(Hz) = 168000000
* HCLK(Hz) = 168000000
* AHB Prescaler = 1
* APB1 Prescaler = 4
* APB2 Prescaler = 2
* HSE Frequency(Hz) = 8000000
* PLL_M = 8
* PLL_N = 336
* PLL_P = 2
* PLL_Q = 7
* VDD(V) = 3.3
* Main regulator output voltage = Scale1 mode
* Flash Latency(WS) = 5
* @param None
* @retval None
*/
static void SystemClock_Config(void)
{
RCC_ClkInitTypeDef RCC_ClkInitStruct;
RCC_OscInitTypeDef RCC_OscInitStruct;
/* Enable Power Control clock */
__HAL_RCC_PWR_CLK_ENABLE();
/* The voltage scaling allows optimizing the power consumption when the device is
clocked below the maximum system frequency, to update the voltage scaling value
regarding system frequency refer to product datasheet. */
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
/* Enable HSE Oscillator and activate PLL with HSE as source */
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = 8;
RCC_OscInitStruct.PLL.PLLN = 336;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 7;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/* 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_DIV4;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
{
Error_Handler();
}
/* STM32F405x/407x/415x/417x Revision Z devices: prefetch is supported */
if (HAL_GetREVID() == 0x1001)
{
/* Enable the Flash prefetch */
__HAL_FLASH_PREFETCH_BUFFER_ENABLE();
}
}
编译下载,可看到板子LED灯闪烁,且串口有输出:
注:PA2是板子的TX引脚。