STM429HAL库函数,如果使用两个USART或两个SPI,其对应的底层MSP初始化函数怎么定义?怎么解决两个MSP初始化函数重复定义?
在 STM32 HAL 库中,对于不同的外设,每个外设都有对应的初始化函数。对于 USART 和 SPI 这样的外设,如果使用多个相同类型的外设,需要分别调用它们各自的初始化函数。
在初始化函数中,通常会初始化外设的时钟、引脚、模式等参数。如果使用多个相同类型的外设,每个外设的初始化参数可能会不同。因此,需要为每个外设分别定义一个初始化函数,并在初始化时传入相应的参数。
当使用多个相同类型的外设时,可能会出现重复定义的问题。为了解决这个问题,可以使用 static 关键字来限制初始化函数的作用域,使得它只在当前文件中可见。这样,不同的文件可以分别定义各自的初始化函数,不会互相干扰。
例如,假设我们有两个 USART 外设,分别是 USART1 和 USART2。在初始化时,需要分别调用 HAL_UART_Init 函数,并传入相应的参数。为了避免重复定义问题,我们可以在不同的文件中分别定义这两个初始化函数,并使用 static 关键字来限制它们的作用域。例如:
// usart1.c 文件
#include "usart.h"
static void USART1_MspInit(UART_HandleTypeDef* huart)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* USART1 clock enable */
__HAL_RCC_USART1_CLK_ENABLE();
/* GPIO clock enable */
__HAL_RCC_GPIOA_CLK_ENABLE();
/* USART1 GPIO configuration */
GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_10;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* USART1 interrupt Init */
HAL_NVIC_SetPriority(USART1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(USART1_IRQn);
}
void USART1_Init(void)
{
UART_HandleTypeDef huart;
/* USART1 configuration */
huart.Instance = USART1;
huart.Init.BaudRate = 115200;
huart.Init.WordLength = UART_WORDLENGTH_8B;
huart.Init.StopBits = UART_STOPBITS_1;
huart.Init.Parity = UART_PARITY_NONE;
huart.Init.Mode = UART_MODE_TX_RX;
huart.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart.Init.OverSampling = UART_OVERSAMPLING_16;
/* USART1 MSP initialization */
USART1_MspInit(&huart);
/* USART1 initialization */
HAL_UART_Init(&huart);
}
// usart2.c 文件
#include "usart.h"
static void USART2_MspInit(UART_HandleTypeDef* huart)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* USART2 clock enable */
__HAL_RCC_USART2_CLK_ENABLE();
/* GPIO clock enable */
__HAL_RCC_GPIOA_CLK_ENABLE();
/* USART2 GPIO configuration */
GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_3;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO
该回答引用GPTᴼᴾᴱᴺᴬᴵ
在使用STM32 HAL库函数初始化多个USART或SPI时,每个外设都有对应的底层MSP(MCU Support Package)初始化函数。这些函数负责配置外设的时钟、GPIO、中断等,并在HAL库函数中被调用。
针对您的问题,可以采用以下两种方法解决:
1.定义不同的MSP初始化函数
在HAL库中,每个外设的MSP初始化函数名称都以该外设的名称为前缀,例如USART的MSP初始化函数名称为HAL_UART_MspInit(),而SPI的MSP初始化函数名称为HAL_SPI_MspInit()。因此,可以在代码中为每个外设定义不同的MSP初始化函数,避免重复定义。例如,如果您需要初始化两个USART和两个SPI,可以按照如下方式定义不同的MSP初始化函数:
void HAL_UART_MspInit(UART_HandleTypeDef* huart)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(huart->Instance==USART1)
{
/* USART1 clock enable */
__HAL_RCC_USART1_CLK_ENABLE();
/* USART1 GPIO Configuration
PA9 ------> USART1_TX
PA10 ------> USART1_RX
*/
GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_10;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
else if(huart->Instance==USART2)
{
/* USART2 clock enable */
__HAL_RCC_USART2_CLK_ENABLE();
/* USART2 GPIO Configuration
PA2 ------> USART2_TX
PA3 ------> USART2_RX
*/
GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_3;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF7_USART2;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
}
void HAL_UART_MspDeInit(UART_HandleTypeDef* huart)
{
if(huart->Instance==USART1)
{
/* Peripheral clock disable */
__HAL_RCC_USART1_CLK_DISABLE();
/* USART1 GPIO Configuration
PA9 ------> USART1_TX
PA10 ------> USART1_RX
*/
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_9|GPIO_PIN_10);
}
else if(huart->Instance==USART2)
{
/* Peripheral clock disable */
__HAL_RCC_USART2_CLK_DISABLE();
/* USART2 GPIO Configuration
PA2 ------> USART2_TX
PA3 ------> USART2_RX
*/
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_2|GPIO_PIN_3);
}
}
void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(hspi->Instance==SPI1)
{
/* SPI1 clock enable */
__HAL_RCC_SPI1_CLK_ENABLE();
/* SPI1 GPIO Configuration
PA5 ------> SPI1_SCK
PA6 ------> SPI1_MISO
PA7 ------> SPI1_MOSI
*/
GPIO_InitStruct.Pin = GPIO_PIN
第二种方法是使用外部变量。在每个文件中定义一个变量,例如:
在usart.c文件中定义:
USART_HandleTypeDef huart1;
void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
{
if(uartHandle->Instance==USART1)
{
/* 初始化USART1的底层硬件资源 */
}
}
在usart2.c文件中定义:
USART_HandleTypeDef huart2;
void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
{
if(uartHandle->Instance==USART2)
{
/* 初始化USART2的底层硬件资源 */
}
}
在main.c文件中声明这些变量:
extern USART_HandleTypeDef huart1;
extern USART_HandleTypeDef huart2;
这样就可以在主函数中使用USART1和USART2了。
请注意,使用外部变量可能会导致代码结构混乱,因此建议仅在必要时使用。
希望这些方法能够帮助到您。
不知道你这个问题是否已经解决, 如果还没有解决的话: