优化实现串口驱动,SPI驱动 W25QXX还需要初始化验证修复

This commit is contained in:
冯佳
2026-01-23 09:59:43 +08:00
parent 51e8d79f78
commit b166bee1a9
69 changed files with 6253 additions and 1178 deletions

View File

@ -6,6 +6,9 @@ add_library(bsp STATIC)
# Add BSP sources
target_sources(bsp PRIVATE
Src/bsp_init.c
Src/stm32f407vet6_board.c
Src/bsp_board_manager.c
Src/bsp_w25qxx.c
)
# Add BSP include directories
@ -17,4 +20,6 @@ target_include_directories(bsp PUBLIC
target_link_libraries(bsp PRIVATE
stm32cubemx
hal
w25qxx
delay
)

107
BSP/Inc/bsp_board.h Normal file
View File

@ -0,0 +1,107 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : bsp_board.h
* @brief : Board support package board abstraction header file
******************************************************************************
*/
/* USER CODE END Header */
#ifndef BSP_BOARD_H
#define BSP_BOARD_H
#include <stdint.h>
#include "hal_gpio.h"
#include "hal_uart.h"
/**
* @brief Board LED configuration structure
*/
typedef struct {
hal_gpio_port_t port;
hal_gpio_pin_t pin;
hal_gpio_mode_t mode;
hal_gpio_speed_t speed;
hal_gpio_pull_t pull;
} bsp_led_config_t;
/**
* @brief Board button configuration structure
*/
typedef struct {
hal_gpio_port_t port;
hal_gpio_pin_t pin;
hal_gpio_mode_t mode;
hal_gpio_speed_t speed;
hal_gpio_pull_t pull;
} bsp_button_config_t;
/**
* @brief UART instance identifier definitions
*/
typedef enum {
BSP_UART_INSTANCE_1 = 0,
BSP_UART_INSTANCE_2,
BSP_UART_INSTANCE_3,
BSP_UART_INSTANCE_4,
BSP_UART_INSTANCE_5,
BSP_UART_INSTANCE_6,
BSP_UART_INSTANCE_MAX
} bsp_uart_instance_t;
/**
* @brief Board UART configuration structure
*/
typedef struct {
bsp_uart_instance_t instance;
uint32_t baudrate;
hal_uart_parity_t parity;
hal_uart_stopbits_t stopbits;
hal_uart_databits_t databits;
hal_gpio_port_t tx_port;
hal_gpio_pin_t tx_pin;
hal_gpio_port_t rx_port;
hal_gpio_pin_t rx_pin;
} bsp_uart_config_t;
/**
* @brief Board peripheral initialization function type
*/
typedef void (*bsp_periph_init_func_t)(const void* config);
/**
* @brief Board configuration structure
*/
typedef struct {
const char* name;
bsp_led_config_t led;
bsp_button_config_t button;
bsp_uart_config_t uart;
/* Initialization function pointers */
bsp_periph_init_func_t led_init;
bsp_periph_init_func_t button_init;
bsp_periph_init_func_t uart_init;
/* Additional board-specific configuration */
uint32_t clock_speed;
uint8_t uart_count;
} bsp_board_config_t;
/**
* @brief STM32F407VET6 board configuration extern declaration
*/
extern const bsp_board_config_t stm32f407vet6_board_config;
/**
* @brief Board hardware initialization
*/
void bsp_board_init(void);
/**
* @brief Get board name
* @retval Board name string
*/
const char* bsp_board_get_name(void);
#endif /* BSP_BOARD_H */

View File

@ -0,0 +1,63 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : bsp_board_manager.h
* @brief : Board support package manager header file
******************************************************************************
*/
/* USER CODE END Header */
#ifndef BSP_BOARD_MANAGER_H
#define BSP_BOARD_MANAGER_H
#include <stdint.h>
#include <string.h>
#include "bsp_board.h"
/**
* @brief Get number of supported boards
* @retval Number of supported boards
*/
uint8_t bsp_board_get_count(void);
/**
* @brief Get board configuration by index
* @param index: Board configuration index
* @retval Pointer to board configuration structure, NULL if invalid index
*/
const bsp_board_config_t* bsp_board_get_by_index(uint8_t index);
/**
* @brief Get board configuration by name
* @param name: Board name string
* @retval Pointer to board configuration structure, NULL if not found
*/
const bsp_board_config_t* bsp_board_get_by_name(const char* name);
/**
* @brief Set current board configuration by index
* @param index: Board configuration index
* @retval 0 if successful, -1 if invalid index
*/
int8_t bsp_board_set_by_index(uint8_t index);
/**
* @brief Set current board configuration by name
* @param name: Board name string
* @retval 0 if successful, -1 if not found
*/
int8_t bsp_board_set_by_name(const char* name);
/**
* @brief Get current board configuration
* @retval Pointer to current board configuration structure
*/
const bsp_board_config_t* bsp_board_get_config(void);
/**
* @brief Get current board index
* @retval Current board index
*/
uint8_t bsp_board_get_current_index(void);
#endif /* BSP_BOARD_MANAGER_H */

View File

@ -11,6 +11,7 @@
#define BSP_CONFIG_H
#include "hal_gpio.h"
#include "hal_uart.h"
/**
* @brief Board name definition
@ -32,7 +33,7 @@
/**
* @brief UART hardware configuration
*/
#define BSP_UART_INSTANCE USART1
#define BSP_UART_INSTANCE BSP_UART_INSTANCE_1
#define BSP_UART_BAUDRATE 115200
#define BSP_UART_PARITY HAL_UART_PARITY_NONE
#define BSP_UART_STOPBITS HAL_UART_STOPBITS_1

View File

@ -10,6 +10,8 @@
#ifndef BSP_INIT_H
#define BSP_INIT_H
#include "bsp_board.h"
/**
* @brief Initialize board support package
*/
@ -26,4 +28,10 @@ void bsp_gpio_init(void);
*/
const char* bsp_get_board_name(void);
/**
* @brief Get current board configuration
* @retval Pointer to board configuration structure
*/
const bsp_board_config_t* bsp_get_board_config(void);
#endif /* BSP_INIT_H */

86
BSP/Inc/bsp_w25qxx.h Normal file
View File

@ -0,0 +1,86 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : bsp_w25qxx.h
* @brief : BSP layer for W25QXX flash memory
******************************************************************************
*/
/* USER CODE END Header */
#ifndef BSP_W25QXX_H
#define BSP_W25QXX_H
#include "w25qxx.h"
#include "hal_spi.h"
#include "hal_gpio.h"
/**
* @brief W25QXX chip select pin configuration
*/
#define W25QXX_CS_PORT HAL_GPIO_PORT_B
#define W25QXX_CS_PIN HAL_GPIO_PIN_0
/**
* @brief W25QXX SPI instance
*/
#define W25QXX_SPI_INSTANCE HAL_SPI_INSTANCE_1
/**
* @brief Initialize W25QXX flash memory
* @retval true if initialization is successful, false otherwise
*/
bool bsp_w25qxx_init(void);
/**
* @brief Get W25QXX device information
* @param info Pointer to device information structure to fill
* @retval true if successful, false otherwise
*/
bool bsp_w25qxx_get_device_info(w25qxx_device_info_t *info);
/**
* @brief Read data from W25QXX flash memory
* @param address Starting address to read from
* @param data Pointer to data buffer to store read data
* @param size Size of data to read
* @retval true if read is successful, false otherwise
*/
bool bsp_w25qxx_read(uint32_t address, uint8_t *data, uint32_t size);
/**
* @brief Write data to W25QXX flash memory
* @param address Starting address to write to
* @param data Pointer to data buffer to write
* @param size Size of data to write
* @retval true if write is successful, false otherwise
*/
bool bsp_w25qxx_write(uint32_t address, const uint8_t *data, uint32_t size);
/**
* @brief Erase 4KB block
* @param address Address within the block to erase
* @retval true if erase is successful, false otherwise
*/
bool bsp_w25qxx_erase_block_4kb(uint32_t address);
/**
* @brief Erase 32KB block
* @param address Address within the block to erase
* @retval true if erase is successful, false otherwise
*/
bool bsp_w25qxx_erase_block_32kb(uint32_t address);
/**
* @brief Erase 64KB block
* @param address Address within the block to erase
* @retval true if erase is successful, false otherwise
*/
bool bsp_w25qxx_erase_block_64kb(uint32_t address);
/**
* @brief Erase entire chip
* @retval true if erase is successful, false otherwise
*/
bool bsp_w25qxx_erase_chip(void);
#endif /* BSP_W25QXX_H */

107
BSP/Src/bsp_board_manager.c Normal file
View File

@ -0,0 +1,107 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : bsp_board_manager.c
* @brief : Board support package manager source file
******************************************************************************
*/
/* USER CODE END Header */
#include "bsp_board_manager.h"
#include "bsp_board.h"
/* Forward declarations for board configurations */
extern const bsp_board_config_t stm32f407vet6_board_config;
/**
* @brief List of supported board configurations
*/
static const bsp_board_config_t* supported_boards[] = {
&stm32f407vet6_board_config,
/* Add more board configurations here */
};
/**
* @brief Current board configuration index
*/
static uint8_t current_board_index = 0;
/**
* @brief Get number of supported boards
* @retval Number of supported boards
*/
uint8_t bsp_board_get_count(void) {
return sizeof(supported_boards) / sizeof(supported_boards[0]);
}
/**
* @brief Get board configuration by index
* @param index: Board configuration index
* @retval Pointer to board configuration structure, NULL if invalid index
*/
const bsp_board_config_t* bsp_board_get_by_index(uint8_t index) {
if (index < bsp_board_get_count()) {
return supported_boards[index];
}
return NULL;
}
/**
* @brief Get board configuration by name
* @param name: Board name string
* @retval Pointer to board configuration structure, NULL if not found
*/
const bsp_board_config_t* bsp_board_get_by_name(const char* name) {
for (uint8_t i = 0; i < bsp_board_get_count(); i++) {
if (supported_boards[i]->name != NULL &&
strcmp(supported_boards[i]->name, name) == 0) {
return supported_boards[i];
}
}
return NULL;
}
/**
* @brief Set current board configuration by index
* @param index: Board configuration index
* @retval 0 if successful, -1 if invalid index
*/
int8_t bsp_board_set_by_index(uint8_t index) {
if (index < bsp_board_get_count()) {
current_board_index = index;
return 0;
}
return -1;
}
/**
* @brief Set current board configuration by name
* @param name: Board name string
* @retval 0 if successful, -1 if not found
*/
int8_t bsp_board_set_by_name(const char* name) {
for (uint8_t i = 0; i < bsp_board_get_count(); i++) {
if (supported_boards[i]->name != NULL &&
strcmp(supported_boards[i]->name, name) == 0) {
current_board_index = i;
return 0;
}
}
return -1;
}
/**
* @brief Get current board configuration
* @retval Pointer to current board configuration structure
*/
const bsp_board_config_t* bsp_board_get_config(void) {
return supported_boards[current_board_index];
}
/**
* @brief Get current board index
* @retval Current board index
*/
uint8_t bsp_board_get_current_index(void) {
return current_board_index;
}

View File

@ -8,79 +8,75 @@
/* USER CODE END Header */
#include "bsp_init.h"
#include "bsp_config.h"
#include "stm32f4xx_hal.h"
#include "bsp_board.h"
#include "bsp_board_manager.h"
#include "hal.h"
#include "hal_gpio.h"
#include "hal_uart.h"
/**
* @brief Initialize board support package
*/
void bsp_init(void) {
/* Initialize board GPIO */
bsp_gpio_init();
/* Get board configuration */
const bsp_board_config_t* board_config = bsp_board_get_config();
/* Initialize HAL layer */
hal_init();
/* Initialize peripherals based on configuration */
/* Initialize LED */
if (board_config->led_init != NULL) {
board_config->led_init(&board_config->led);
} else {
/* Use default initialization if no function provided */
hal_gpio_config_t gpio_config = {
.port = board_config->led.port,
.pin = board_config->led.pin,
.mode = board_config->led.mode,
.speed = board_config->led.speed,
.pull = board_config->led.pull
};
hal_gpio_configure_pin(&gpio_config);
}
/* Initialize Button */
if (board_config->button_init != NULL) {
board_config->button_init(&board_config->button);
}
/* Initialize UART */
if (board_config->uart_init != NULL) {
board_config->uart_init(&board_config->uart);
}
}
/**
* @brief Initialize board GPIO
* @brief Initialize board GPIO using configuration
*/
void bsp_gpio_init(void) {
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_TypeDef *gpio_port = NULL;
uint32_t gpio_pin = 0;
/* Get board configuration */
const bsp_board_config_t* board_config = bsp_board_get_config();
/* Convert HAL GPIO port to STM32 GPIO port */
switch (BSP_LED_PORT) {
case HAL_GPIO_PORT_A:
gpio_port = GPIOA;
__HAL_RCC_GPIOA_CLK_ENABLE();
break;
case HAL_GPIO_PORT_B:
gpio_port = GPIOB;
__HAL_RCC_GPIOB_CLK_ENABLE();
break;
case HAL_GPIO_PORT_C:
gpio_port = GPIOC;
__HAL_RCC_GPIOC_CLK_ENABLE();
break;
case HAL_GPIO_PORT_D:
gpio_port = GPIOD;
__HAL_RCC_GPIOD_CLK_ENABLE();
break;
case HAL_GPIO_PORT_E:
gpio_port = GPIOE;
__HAL_RCC_GPIOE_CLK_ENABLE();
break;
case HAL_GPIO_PORT_F:
gpio_port = GPIOF;
__HAL_RCC_GPIOF_CLK_ENABLE();
break;
case HAL_GPIO_PORT_G:
gpio_port = GPIOG;
__HAL_RCC_GPIOG_CLK_ENABLE();
break;
case HAL_GPIO_PORT_H:
gpio_port = GPIOH;
__HAL_RCC_GPIOH_CLK_ENABLE();
break;
case HAL_GPIO_PORT_I:
gpio_port = GPIOI;
__HAL_RCC_GPIOI_CLK_ENABLE();
break;
default: break;
}
/* Initialize LED GPIO */
hal_gpio_config_t gpio_config = {
.port = board_config->led.port,
.pin = board_config->led.pin,
.mode = board_config->led.mode,
.speed = board_config->led.speed,
.pull = board_config->led.pull
};
hal_gpio_configure_pin(&gpio_config);
/* Convert HAL GPIO pin to STM32 GPIO pin */
gpio_pin = 1 << BSP_LED_PIN;
if (gpio_port != NULL) {
/* Configure GPIO pin Output Level */
HAL_GPIO_WritePin(gpio_port, gpio_pin, GPIO_PIN_RESET);
/* Configure GPIO pin */
GPIO_InitStruct.Pin = gpio_pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(gpio_port, &GPIO_InitStruct);
/* Initialize Button GPIO if configured */
if (board_config->button.port != 0 && board_config->button.pin != 0) {
gpio_config.port = board_config->button.port;
gpio_config.pin = board_config->button.pin;
gpio_config.mode = board_config->button.mode;
gpio_config.speed = board_config->button.speed;
gpio_config.pull = board_config->button.pull;
hal_gpio_configure_pin(&gpio_config);
}
}
@ -89,5 +85,13 @@ void bsp_gpio_init(void) {
* @retval Board name string
*/
const char* bsp_get_board_name(void) {
return BOARD_NAME;
return bsp_board_get_name();
}
/**
* @brief Get current board configuration
* @retval Pointer to board configuration structure
*/
const bsp_board_config_t* bsp_get_board_config(void) {
return bsp_board_get_config();
}

171
BSP/Src/bsp_w25qxx.c Normal file
View File

@ -0,0 +1,171 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : bsp_w25qxx.c
* @brief : BSP layer for W25QXX flash memory
******************************************************************************
*/
/* USER CODE END Header */
#include "bsp_w25qxx.h"
#include "delay.h"
/**
* @brief SPI send function for W25QXX
* @param data Pointer to data buffer to send
* @param size Size of data to send
* @return true if successful, false otherwise
*/
static bool w25qxx_spi_send(const uint8_t *data, uint16_t size) {
return hal_spi_transmit(W25QXX_SPI_INSTANCE, data, size);
}
/**
* @brief SPI receive function for W25QXX
* @param data Pointer to data buffer to receive
* @param size Size of data to receive
* @return true if successful, false otherwise
*/
static bool w25qxx_spi_receive(uint8_t *data, uint16_t size) {
return hal_spi_receive(W25QXX_SPI_INSTANCE, data, size);
}
/**
* @brief SPI transmit and receive function for W25QXX
* @param tx_data Pointer to transmit data buffer
* @param rx_data Pointer to receive data buffer
* @param size Size of data to transfer
* @return true if successful, false otherwise
*/
static bool w25qxx_spi_transceive(const uint8_t *tx_data, uint8_t *rx_data, uint16_t size) {
return hal_spi_transmit_receive(W25QXX_SPI_INSTANCE, tx_data, rx_data, size);
}
/**
* @brief Chip select function for W25QXX
* @param state true for selected, false for deselected
*/
static void w25qxx_cs_set(bool state) {
hal_gpio_write_pin(W25QXX_CS_PORT, W25QXX_CS_PIN, state ? HAL_GPIO_PIN_RESET : HAL_GPIO_PIN_SET);
}
/**
* @brief Delay function for W25QXX
* @param ms Delay time in milliseconds
*/
static void w25qxx_delay_ms(uint32_t ms) {
delay_ms(ms);
}
/**
* @brief W25QXX SPI interface structure
*/
static w25qxx_spi_interface_t w25qxx_spi_interface = {
.spi_send = w25qxx_spi_send,
.spi_receive = w25qxx_spi_receive,
.spi_transceive = w25qxx_spi_transceive,
.cs_set = w25qxx_cs_set,
.delay_ms = w25qxx_delay_ms
};
/**
* @brief Initialize W25QXX flash memory
* @retval true if initialization is successful, false otherwise
*/
bool bsp_w25qxx_init(void) {
/* Initialize CS pin */
hal_gpio_config_t gpio_config = {
.port = W25QXX_CS_PORT,
.pin = W25QXX_CS_PIN,
.mode = HAL_GPIO_MODE_OUTPUT_PP,
.speed = HAL_GPIO_SPEED_HIGH,
.pull = HAL_GPIO_PULL_NO
};
hal_gpio_configure_pin(&gpio_config);
/* Deselect chip initially */
w25qxx_cs_set(false);
/* Initialize SPI */
hal_spi_config_t spi_config = {
.instance = W25QXX_SPI_INSTANCE,
.mode = HAL_SPI_MODE_MASTER,
.baudrate = 1000000, /* 1 MHz */
.polarity = HAL_SPI_POLARITY_LOW,
.phase = HAL_SPI_PHASE_1EDGE,
.databits = HAL_SPI_DATABITS_8
};
if (!hal_spi_init(W25QXX_SPI_INSTANCE, &spi_config)) {
return false;
}
/* Initialize W25QXX driver */
return w25qxx_init(&w25qxx_spi_interface);
}
/**
* @brief Get W25QXX device information
* @param info Pointer to device information structure to fill
* @retval true if successful, false otherwise
*/
bool bsp_w25qxx_get_device_info(w25qxx_device_info_t *info) {
return w25qxx_get_device_info(info);
}
/**
* @brief Read data from W25QXX flash memory
* @param address Starting address to read from
* @param data Pointer to data buffer to store read data
* @param size Size of data to read
* @retval true if read is successful, false otherwise
*/
bool bsp_w25qxx_read(uint32_t address, uint8_t *data, uint32_t size) {
return w25qxx_read(address, data, size);
}
/**
* @brief Write data to W25QXX flash memory
* @param address Starting address to write to
* @param data Pointer to data buffer to write
* @param size Size of data to write
* @retval true if write is successful, false otherwise
*/
bool bsp_w25qxx_write(uint32_t address, const uint8_t *data, uint32_t size) {
return w25qxx_write(address, data, size);
}
/**
* @brief Erase 4KB block
* @param address Address within the block to erase
* @retval true if erase is successful, false otherwise
*/
bool bsp_w25qxx_erase_block_4kb(uint32_t address) {
return w25qxx_erase_block_4kb(address);
}
/**
* @brief Erase 32KB block
* @param address Address within the block to erase
* @retval true if erase is successful, false otherwise
*/
bool bsp_w25qxx_erase_block_32kb(uint32_t address) {
return w25qxx_erase_block_32kb(address);
}
/**
* @brief Erase 64KB block
* @param address Address within the block to erase
* @retval true if erase is successful, false otherwise
*/
bool bsp_w25qxx_erase_block_64kb(uint32_t address) {
return w25qxx_erase_block_64kb(address);
}
/**
* @brief Erase entire chip
* @retval true if erase is successful, false otherwise
*/
bool bsp_w25qxx_erase_chip(void) {
return w25qxx_erase_chip();
}

View File

@ -0,0 +1,106 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : stm32f407vet6_board.c
* @brief : STM32F407VET6 board configuration implementation
******************************************************************************
*/
/* USER CODE END Header */
#include "bsp_board.h"
#include "bsp_config.h"
#include "hal_gpio.h"
#include "hal_uart.h"
/**
* @brief Default LED initialization function
* @param config: LED configuration structure
*/
static void default_led_init(const void* config) {
const bsp_led_config_t* led_config = (const bsp_led_config_t*)config;
hal_gpio_config_t gpio_config = {
.port = led_config->port,
.pin = led_config->pin,
.mode = led_config->mode,
.speed = led_config->speed,
.pull = led_config->pull
};
hal_gpio_configure_pin(&gpio_config);
}
/**
* @brief Default button initialization function
* @param config: Button configuration structure
*/
static void default_button_init(const void* config) {
const bsp_button_config_t* button_config = (const bsp_button_config_t*)config;
hal_gpio_config_t gpio_config = {
.port = button_config->port,
.pin = button_config->pin,
.mode = button_config->mode,
.speed = button_config->speed,
.pull = button_config->pull
};
hal_gpio_configure_pin(&gpio_config);
}
/**
* @brief Default UART initialization function
* @param config: UART configuration structure
*/
static void default_uart_init(const void* config) {
const bsp_uart_config_t* uart_config = (const bsp_uart_config_t*)config;
hal_uart_config_t uart_cfg = {
.instance = (hal_uart_instance_t)uart_config->instance,
.baudrate = uart_config->baudrate,
.parity = uart_config->parity,
.stopbits = uart_config->stopbits,
.databits = uart_config->databits
};
hal_uart_config(&uart_cfg);
}
/**
* @brief STM32F407VET6 board configuration
*/
const bsp_board_config_t stm32f407vet6_board_config = {
.name = BOARD_NAME,
.led = {
.port = BSP_LED_PORT,
.pin = BSP_LED_PIN,
.mode = HAL_GPIO_MODE_OUTPUT_PP,
.speed = HAL_GPIO_SPEED_MEDIUM,
.pull = HAL_GPIO_PULL_NO
},
.button = {
.port = 0, /* Not used */
.pin = 0, /* Not used */
.mode = HAL_GPIO_MODE_INPUT,
.speed = HAL_GPIO_SPEED_LOW,
.pull = HAL_GPIO_PULL_NO
},
.uart = {
.instance = BSP_UART_INSTANCE,
.baudrate = BSP_UART_BAUDRATE,
.parity = BSP_UART_PARITY,
.stopbits = BSP_UART_STOPBITS,
.databits = BSP_UART_DATABITS,
.tx_port = HAL_GPIO_PORT_A, /* USART1_TX - PA9 */
.tx_pin = HAL_GPIO_PIN_9,
.rx_port = HAL_GPIO_PORT_A, /* USART1_RX - PA10 */
.rx_pin = HAL_GPIO_PIN_10
},
.led_init = default_led_init,
.button_init = default_button_init,
.uart_init = default_uart_init,
.clock_speed = 168000000, /* 168 MHz */
.uart_count = 6
};
/**
* @brief Get board name
* @retval Board name string
*/
const char* bsp_board_get_name(void) {
return stm32f407vet6_board_config.name;
}