实现串口驱动,移植方便
This commit is contained in:
21
HAL/CMakeLists.txt
Normal file
21
HAL/CMakeLists.txt
Normal file
@ -0,0 +1,21 @@
|
||||
cmake_minimum_required(VERSION 3.22)
|
||||
|
||||
# Add HAL library
|
||||
add_library(hal STATIC)
|
||||
|
||||
# Add HAL sources
|
||||
target_sources(hal PRIVATE
|
||||
Src/hal_gpio.c
|
||||
Src/hal_delay.c
|
||||
Src/hal_uart.c
|
||||
)
|
||||
|
||||
# Add HAL include directories
|
||||
target_include_directories(hal PUBLIC
|
||||
Inc
|
||||
)
|
||||
|
||||
# Link HAL dependencies
|
||||
target_link_libraries(hal PRIVATE
|
||||
stm32cubemx
|
||||
)
|
||||
32
HAL/Inc/hal_delay.h
Normal file
32
HAL/Inc/hal_delay.h
Normal file
@ -0,0 +1,32 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file : hal_delay.h
|
||||
* @brief : Delay hardware abstraction layer header file
|
||||
******************************************************************************
|
||||
*/
|
||||
/* USER CODE END Header */
|
||||
|
||||
#ifndef HAL_DELAY_H
|
||||
#define HAL_DELAY_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/**
|
||||
* @brief Initialize delay module
|
||||
*/
|
||||
void hal_delay_init(void);
|
||||
|
||||
/**
|
||||
* @brief Delay in milliseconds
|
||||
* @param ms: Delay time in milliseconds
|
||||
*/
|
||||
void hal_delay_ms(uint32_t ms);
|
||||
|
||||
/**
|
||||
* @brief Delay in microseconds
|
||||
* @param us: Delay time in microseconds
|
||||
*/
|
||||
void hal_delay_us(uint32_t us);
|
||||
|
||||
#endif /* HAL_DELAY_H */
|
||||
97
HAL/Inc/hal_gpio.h
Normal file
97
HAL/Inc/hal_gpio.h
Normal file
@ -0,0 +1,97 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file : hal_gpio.h
|
||||
* @brief : GPIO hardware abstraction layer header file
|
||||
******************************************************************************
|
||||
*/
|
||||
/* USER CODE END Header */
|
||||
|
||||
#ifndef HAL_GPIO_H
|
||||
#define HAL_GPIO_H
|
||||
|
||||
/**
|
||||
* @brief GPIO pin state definitions
|
||||
*/
|
||||
typedef enum {
|
||||
HAL_GPIO_PIN_RESET = 0U,
|
||||
HAL_GPIO_PIN_SET = 1U
|
||||
} hal_gpio_pin_state_t;
|
||||
|
||||
/**
|
||||
* @brief GPIO pin definitions
|
||||
*/
|
||||
typedef enum {
|
||||
HAL_GPIO_PIN_0 = 0U,
|
||||
HAL_GPIO_PIN_1 = 1U,
|
||||
HAL_GPIO_PIN_2 = 2U,
|
||||
HAL_GPIO_PIN_3 = 3U,
|
||||
HAL_GPIO_PIN_4 = 4U,
|
||||
HAL_GPIO_PIN_5 = 5U,
|
||||
HAL_GPIO_PIN_6 = 6U,
|
||||
HAL_GPIO_PIN_7 = 7U,
|
||||
HAL_GPIO_PIN_8 = 8U,
|
||||
HAL_GPIO_PIN_9 = 9U,
|
||||
HAL_GPIO_PIN_10 = 10U,
|
||||
HAL_GPIO_PIN_11 = 11U,
|
||||
HAL_GPIO_PIN_12 = 12U,
|
||||
HAL_GPIO_PIN_13 = 13U,
|
||||
HAL_GPIO_PIN_14 = 14U,
|
||||
HAL_GPIO_PIN_15 = 15U,
|
||||
HAL_GPIO_PIN_ALL = 0xFFFFU
|
||||
} hal_gpio_pin_t;
|
||||
|
||||
/**
|
||||
* @brief GPIO port definitions
|
||||
*/
|
||||
typedef enum {
|
||||
HAL_GPIO_PORT_A = 0U,
|
||||
HAL_GPIO_PORT_B = 1U,
|
||||
HAL_GPIO_PORT_C = 2U,
|
||||
HAL_GPIO_PORT_D = 3U,
|
||||
HAL_GPIO_PORT_E = 4U,
|
||||
HAL_GPIO_PORT_F = 5U,
|
||||
HAL_GPIO_PORT_G = 6U,
|
||||
HAL_GPIO_PORT_H = 7U,
|
||||
HAL_GPIO_PORT_I = 8U,
|
||||
HAL_GPIO_PORT_J = 9U,
|
||||
HAL_GPIO_PORT_K = 10U
|
||||
} hal_gpio_port_t;
|
||||
|
||||
/**
|
||||
* @brief GPIO configuration structure
|
||||
*/
|
||||
typedef struct {
|
||||
hal_gpio_port_t port;
|
||||
hal_gpio_pin_t pin;
|
||||
} hal_gpio_config_t;
|
||||
|
||||
/**
|
||||
* @brief Initialize GPIO hardware
|
||||
*/
|
||||
void hal_gpio_init(void);
|
||||
|
||||
/**
|
||||
* @brief Write GPIO pin state
|
||||
* @param port: GPIO port
|
||||
* @param pin: GPIO pin
|
||||
* @param state: GPIO pin state
|
||||
*/
|
||||
void hal_gpio_write_pin(hal_gpio_port_t port, hal_gpio_pin_t pin, hal_gpio_pin_state_t state);
|
||||
|
||||
/**
|
||||
* @brief Toggle GPIO pin state
|
||||
* @param port: GPIO port
|
||||
* @param pin: GPIO pin
|
||||
*/
|
||||
void hal_gpio_toggle_pin(hal_gpio_port_t port, hal_gpio_pin_t pin);
|
||||
|
||||
/**
|
||||
* @brief Read GPIO pin state
|
||||
* @param port: GPIO port
|
||||
* @param pin: GPIO pin
|
||||
* @retval GPIO pin state
|
||||
*/
|
||||
hal_gpio_pin_state_t hal_gpio_read_pin(hal_gpio_port_t port, hal_gpio_pin_t pin);
|
||||
|
||||
#endif /* HAL_GPIO_H */
|
||||
89
HAL/Inc/hal_uart.h
Normal file
89
HAL/Inc/hal_uart.h
Normal file
@ -0,0 +1,89 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file : hal_uart.h
|
||||
* @brief : UART hardware abstraction layer header file
|
||||
******************************************************************************
|
||||
*/
|
||||
/* USER CODE END Header */
|
||||
|
||||
#ifndef HAL_UART_H
|
||||
#define HAL_UART_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
/**
|
||||
* @brief UART parity definitions
|
||||
*/
|
||||
typedef enum {
|
||||
HAL_UART_PARITY_NONE = 0U,
|
||||
HAL_UART_PARITY_ODD = 1U,
|
||||
HAL_UART_PARITY_EVEN = 2U
|
||||
} hal_uart_parity_t;
|
||||
|
||||
/**
|
||||
* @brief UART stop bits definitions
|
||||
*/
|
||||
typedef enum {
|
||||
HAL_UART_STOPBITS_1 = 0U,
|
||||
HAL_UART_STOPBITS_2 = 1U
|
||||
} hal_uart_stopbits_t;
|
||||
|
||||
/**
|
||||
* @brief UART data bits definitions
|
||||
*/
|
||||
typedef enum {
|
||||
HAL_UART_DATABITS_8 = 0U,
|
||||
HAL_UART_DATABITS_9 = 1U
|
||||
} hal_uart_databits_t;
|
||||
|
||||
/**
|
||||
* @brief UART configuration structure
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t baudrate;
|
||||
hal_uart_parity_t parity;
|
||||
hal_uart_stopbits_t stopbits;
|
||||
hal_uart_databits_t databits;
|
||||
} hal_uart_config_t;
|
||||
|
||||
/**
|
||||
* @brief Initialize UART hardware
|
||||
*/
|
||||
void hal_uart_init(void);
|
||||
|
||||
/**
|
||||
* @brief Configure UART parameters
|
||||
* @param config: UART configuration structure
|
||||
*/
|
||||
void hal_uart_config(const hal_uart_config_t *config);
|
||||
|
||||
/**
|
||||
* @brief Send data over UART
|
||||
* @param data: Pointer to data buffer
|
||||
* @param length: Data length in bytes
|
||||
*/
|
||||
void hal_uart_send(const uint8_t *data, size_t length);
|
||||
|
||||
/**
|
||||
* @brief Receive data over UART
|
||||
* @param data: Pointer to data buffer
|
||||
* @param length: Data length to receive in bytes
|
||||
* @retval Number of bytes received
|
||||
*/
|
||||
size_t hal_uart_receive(uint8_t *data, size_t length);
|
||||
|
||||
/**
|
||||
* @brief Check if UART is ready to send
|
||||
* @retval 1 if ready, 0 otherwise
|
||||
*/
|
||||
uint8_t hal_uart_is_tx_ready(void);
|
||||
|
||||
/**
|
||||
* @brief Check if UART has data to receive
|
||||
* @retval 1 if data available, 0 otherwise
|
||||
*/
|
||||
uint8_t hal_uart_is_rx_ready(void);
|
||||
|
||||
#endif /* HAL_UART_H */
|
||||
43
HAL/Src/hal_delay.c
Normal file
43
HAL/Src/hal_delay.c
Normal file
@ -0,0 +1,43 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file : hal_delay.c
|
||||
* @brief : Delay hardware abstraction layer source file
|
||||
******************************************************************************
|
||||
*/
|
||||
/* USER CODE END Header */
|
||||
|
||||
#include "hal_delay.h"
|
||||
#include "stm32f4xx_hal.h"
|
||||
|
||||
/**
|
||||
* @brief Initialize delay module
|
||||
*/
|
||||
void hal_delay_init(void) {
|
||||
/* Delay initialization is handled by HAL_Init() */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Delay in milliseconds
|
||||
* @param ms: Delay time in milliseconds
|
||||
*/
|
||||
void hal_delay_ms(uint32_t ms) {
|
||||
HAL_Delay(ms);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Delay in microseconds
|
||||
* @param us: Delay time in microseconds
|
||||
*/
|
||||
void hal_delay_us(uint32_t us) {
|
||||
uint32_t ticks = 0;
|
||||
uint32_t start_tick = 0;
|
||||
uint32_t tick_freq = HAL_RCC_GetHCLKFreq() / 1000000;
|
||||
|
||||
ticks = us * tick_freq;
|
||||
start_tick = HAL_GetTick() * tick_freq;
|
||||
|
||||
while ((HAL_GetTick() * tick_freq - start_tick) < ticks) {
|
||||
/* Busy wait */
|
||||
}
|
||||
}
|
||||
104
HAL/Src/hal_gpio.c
Normal file
104
HAL/Src/hal_gpio.c
Normal file
@ -0,0 +1,104 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file : hal_gpio.c
|
||||
* @brief : GPIO hardware abstraction layer source file
|
||||
******************************************************************************
|
||||
*/
|
||||
/* USER CODE END Header */
|
||||
|
||||
#include "hal_gpio.h"
|
||||
#include "stm32f4xx_hal.h"
|
||||
|
||||
/**
|
||||
* @brief Convert HAL GPIO port to STM32 GPIO port
|
||||
* @param port: HAL GPIO port
|
||||
* @retval STM32 GPIO port
|
||||
*/
|
||||
static GPIO_TypeDef* hal_gpio_port_to_stm32(hal_gpio_port_t port) {
|
||||
switch (port) {
|
||||
case HAL_GPIO_PORT_A: return GPIOA;
|
||||
case HAL_GPIO_PORT_B: return GPIOB;
|
||||
case HAL_GPIO_PORT_C: return GPIOC;
|
||||
case HAL_GPIO_PORT_D: return GPIOD;
|
||||
case HAL_GPIO_PORT_E: return GPIOE;
|
||||
case HAL_GPIO_PORT_F: return GPIOF;
|
||||
case HAL_GPIO_PORT_G: return GPIOG;
|
||||
case HAL_GPIO_PORT_H: return GPIOH;
|
||||
case HAL_GPIO_PORT_I: return GPIOI;
|
||||
// case HAL_GPIO_PORT_J: return GPIOJ;
|
||||
// case HAL_GPIO_PORT_K: return GPIOK;
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Convert HAL GPIO pin to STM32 GPIO pin
|
||||
* @param pin: HAL GPIO pin
|
||||
* @retval STM32 GPIO pin
|
||||
*/
|
||||
static uint16_t hal_gpio_pin_to_stm32(hal_gpio_pin_t pin) {
|
||||
return (1U << pin);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Convert HAL GPIO state to STM32 GPIO state
|
||||
* @param state: HAL GPIO state
|
||||
* @retval STM32 GPIO state
|
||||
*/
|
||||
static GPIO_PinState hal_gpio_state_to_stm32(hal_gpio_pin_state_t state) {
|
||||
return (state == HAL_GPIO_PIN_SET) ? GPIO_PIN_SET : GPIO_PIN_RESET;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initialize GPIO hardware
|
||||
*/
|
||||
void hal_gpio_init(void) {
|
||||
/* GPIO initialization is handled by BSP layer */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write GPIO pin state
|
||||
* @param port: GPIO port
|
||||
* @param pin: GPIO pin
|
||||
* @param state: GPIO pin state
|
||||
*/
|
||||
void hal_gpio_write_pin(hal_gpio_port_t port, hal_gpio_pin_t pin, hal_gpio_pin_state_t state) {
|
||||
GPIO_TypeDef* stm32_port = hal_gpio_port_to_stm32(port);
|
||||
if (stm32_port == NULL) {
|
||||
return;
|
||||
}
|
||||
uint16_t stm32_pin = hal_gpio_pin_to_stm32(pin);
|
||||
GPIO_PinState stm32_state = hal_gpio_state_to_stm32(state);
|
||||
HAL_GPIO_WritePin(stm32_port, stm32_pin, stm32_state);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Toggle GPIO pin state
|
||||
* @param port: GPIO port
|
||||
* @param pin: GPIO pin
|
||||
*/
|
||||
void hal_gpio_toggle_pin(hal_gpio_port_t port, hal_gpio_pin_t pin) {
|
||||
GPIO_TypeDef* stm32_port = hal_gpio_port_to_stm32(port);
|
||||
if (stm32_port == NULL) {
|
||||
return;
|
||||
}
|
||||
uint16_t stm32_pin = hal_gpio_pin_to_stm32(pin);
|
||||
HAL_GPIO_TogglePin(stm32_port, stm32_pin);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Read GPIO pin state
|
||||
* @param port: GPIO port
|
||||
* @param pin: GPIO pin
|
||||
* @retval GPIO pin state
|
||||
*/
|
||||
hal_gpio_pin_state_t hal_gpio_read_pin(hal_gpio_port_t port, hal_gpio_pin_t pin) {
|
||||
GPIO_TypeDef* stm32_port = hal_gpio_port_to_stm32(port);
|
||||
if (stm32_port == NULL) {
|
||||
return HAL_GPIO_PIN_RESET;
|
||||
}
|
||||
uint16_t stm32_pin = hal_gpio_pin_to_stm32(pin);
|
||||
GPIO_PinState stm32_state = HAL_GPIO_ReadPin(stm32_port, stm32_pin);
|
||||
return (stm32_state == GPIO_PIN_SET) ? HAL_GPIO_PIN_SET : HAL_GPIO_PIN_RESET;
|
||||
}
|
||||
154
HAL/Src/hal_uart.c
Normal file
154
HAL/Src/hal_uart.c
Normal file
@ -0,0 +1,154 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file : hal_uart.c
|
||||
* @brief : UART hardware abstraction layer source file
|
||||
******************************************************************************
|
||||
*/
|
||||
/* USER CODE END Header */
|
||||
|
||||
#include "hal_uart.h"
|
||||
#include "stm32f4xx_hal.h"
|
||||
#include "stm32f4xx_hal_uart.h"
|
||||
|
||||
/* UART handle */
|
||||
static UART_HandleTypeDef huart1;
|
||||
|
||||
/**
|
||||
* @brief Initialize UART hardware
|
||||
*/
|
||||
void hal_uart_init(void) {
|
||||
/* UART initialization is handled by HAL_Init() */
|
||||
|
||||
/* Configure UART GPIO pins */
|
||||
GPIO_InitTypeDef GPIO_InitStruct = {0};
|
||||
|
||||
/* Enable UART clock */
|
||||
__HAL_RCC_USART1_CLK_ENABLE();
|
||||
|
||||
/* Enable GPIO clocks */
|
||||
__HAL_RCC_GPIOA_CLK_ENABLE();
|
||||
|
||||
/* Configure USART1 Tx (PA9) as alternate function push-pull */
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_9;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
|
||||
GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||
|
||||
/* Configure USART1 Rx (PA10) as alternate function push-pull */
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_10;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
|
||||
GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||
|
||||
/* Initialize UART */
|
||||
huart1.Instance = USART1;
|
||||
huart1.Init.BaudRate = 115200;
|
||||
huart1.Init.WordLength = UART_WORDLENGTH_8B;
|
||||
huart1.Init.StopBits = UART_STOPBITS_1;
|
||||
huart1.Init.Parity = UART_PARITY_NONE;
|
||||
huart1.Init.Mode = UART_MODE_TX_RX;
|
||||
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
|
||||
huart1.Init.OverSampling = UART_OVERSAMPLING_16;
|
||||
|
||||
if (HAL_UART_Init(&huart1) != HAL_OK) {
|
||||
/* Initialization Error */
|
||||
while (1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configure UART parameters
|
||||
* @param config: UART configuration structure
|
||||
*/
|
||||
void hal_uart_config(const hal_uart_config_t *config) {
|
||||
if (config == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Update UART configuration */
|
||||
huart1.Init.BaudRate = config->baudrate;
|
||||
|
||||
/* Convert parity */
|
||||
switch (config->parity) {
|
||||
case HAL_UART_PARITY_NONE:
|
||||
huart1.Init.Parity = UART_PARITY_NONE;
|
||||
break;
|
||||
case HAL_UART_PARITY_ODD:
|
||||
huart1.Init.Parity = UART_PARITY_ODD;
|
||||
break;
|
||||
case HAL_UART_PARITY_EVEN:
|
||||
huart1.Init.Parity = UART_PARITY_EVEN;
|
||||
break;
|
||||
default:
|
||||
huart1.Init.Parity = UART_PARITY_NONE;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Convert stop bits */
|
||||
huart1.Init.StopBits = (config->stopbits == HAL_UART_STOPBITS_1) ?
|
||||
UART_STOPBITS_1 : UART_STOPBITS_2;
|
||||
|
||||
/* Convert data bits */
|
||||
huart1.Init.WordLength = (config->databits == HAL_UART_DATABITS_8) ?
|
||||
UART_WORDLENGTH_8B : UART_WORDLENGTH_9B;
|
||||
|
||||
/* Re-initialize UART */
|
||||
if (HAL_UART_Init(&huart1) != HAL_OK) {
|
||||
/* Initialization Error */
|
||||
while (1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Send data over UART
|
||||
* @param data: Pointer to data buffer
|
||||
* @param length: Data length in bytes
|
||||
*/
|
||||
void hal_uart_send(const uint8_t *data, size_t length) {
|
||||
if (data == NULL || length == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
HAL_UART_Transmit(&huart1, (uint8_t *)data, length, HAL_MAX_DELAY);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Receive data over UART
|
||||
* @param data: Pointer to data buffer
|
||||
* @param length: Data length to receive in bytes
|
||||
* @retval Number of bytes received
|
||||
*/
|
||||
size_t hal_uart_receive(uint8_t *data, size_t length) {
|
||||
if (data == NULL || length == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
HAL_StatusTypeDef status = HAL_UART_Receive(&huart1, data, length, HAL_MAX_DELAY);
|
||||
|
||||
if (status == HAL_OK) {
|
||||
return length;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if UART is ready to send
|
||||
* @retval 1 if ready, 0 otherwise
|
||||
*/
|
||||
uint8_t hal_uart_is_tx_ready(void) {
|
||||
return (HAL_UART_GetState(&huart1) == HAL_UART_STATE_READY) ? 1 : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if UART has data to receive
|
||||
* @retval 1 if data available, 0 otherwise
|
||||
*/
|
||||
uint8_t hal_uart_is_rx_ready(void) {
|
||||
return (HAL_UART_GetState(&huart1) == HAL_UART_STATE_READY) ? 1 : 0;
|
||||
}
|
||||
Reference in New Issue
Block a user