feat: 新增LED的CPP支持,优化LED的C模块结构,新增interface

This commit is contained in:
2025-11-10 00:19:57 +08:00
parent c6365a7548
commit a49d1df0d5
12 changed files with 317 additions and 103 deletions

View File

@@ -11,12 +11,13 @@ cmake_minimum_required(VERSION 3.22)
set(CMAKE_C_STANDARD 11)
set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_C_EXTENSIONS ON)
option(DRIVER_CPP "cpp driver" OFF)
# Define the build type
if(NOT CMAKE_BUILD_TYPE)
if (NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "Debug")
endif()
endif ()
# Set the project name
set(CMAKE_PROJECT_NAME CLion_STM32)
@@ -35,26 +36,26 @@ enable_language(C ASM)
add_executable(${CMAKE_PROJECT_NAME})
# Add STM32CubeMX generated sources
add_subdirectory(cmake/stm32cubemx)
add_subdirectory(Core/driver/led)
add_subdirectory(Core/driver)
# Link directories setup
target_link_directories(${CMAKE_PROJECT_NAME} PRIVATE
# Add user defined library search paths
# Add user defined library search paths
)
# Add sources to executable
target_sources(${CMAKE_PROJECT_NAME} PRIVATE
# Add user sources here
# Add user sources here
)
# Add include paths
target_include_directories(${CMAKE_PROJECT_NAME} PRIVATE
# Add user defined include paths
# Add user defined include paths
)
# Add project symbols (macros)
target_compile_definitions(${CMAKE_PROJECT_NAME} PRIVATE
# Add user defined symbols
# Add user defined symbols
)
# Remove wrong libob.a library dependency when using cpp files
@@ -62,11 +63,7 @@ list(REMOVE_ITEM CMAKE_C_IMPLICIT_LINK_LIBRARIES ob)
# Add linked libraries
target_link_libraries(${CMAKE_PROJECT_NAME}
stm32cubemx
# Add user defined libraries
stm32cubemx
# Add user defined libraries
driver
)
if (FEATURE_LED)
target_link_libraries(${CMAKE_PROJECT_NAME}
led_lib
)
endif ()

View File

@@ -19,12 +19,10 @@
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "gpio.h"
#ifdef FEATURE_LED
#include "led.h"
#endif
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "interface.h"
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
@@ -50,6 +48,7 @@
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
@@ -63,9 +62,7 @@ void SystemClock_Config(void);
* @brief The application entry point.
* @retval int
*/
int main(void)
{
int main(void) {
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
@@ -89,74 +86,64 @@ int main(void)
/* Initialize all configured peripherals */
MX_GPIO_Init();
/* USER CODE BEGIN 2 */
interface();
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
while (1) {
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
#ifdef FEATURE_LED
led_off();
HAL_Delay(200);
led_on();
HAL_Delay(200);
#endif
}
#if 0
/* USER CODE END 3 */
}
/**
* @brief System Clock Configuration
* @retval None
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
/**
* @brief System Clock Configuration
* @retval None
*/
void SystemClock_Config(void) {
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
/** Configure the main internal regulator output voltage
*/
__HAL_RCC_PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
/** Configure the main internal regulator output voltage
*/
__HAL_RCC_PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
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 = 4;
RCC_OscInitStruct.PLL.PLLN = 168;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 4;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
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 = 4;
RCC_OscInitStruct.PLL.PLLN = 168;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 4;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
Error_Handler();
}
/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK
| 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();
}
}
/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|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();
}
}
/* USER CODE BEGIN 4 */
/* USER CODE BEGIN 4 */
#endif
}
@@ -164,8 +151,7 @@ void SystemClock_Config(void)
* @brief System Clock Configuration
* @retval None
*/
void SystemClock_Config(void)
{
void SystemClock_Config(void) {
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
@@ -176,8 +162,7 @@ void SystemClock_Config(void)
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
{
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK) {
Error_Handler();
}
/** Initializes the RCC Oscillators according to the specified parameters
@@ -191,38 +176,35 @@ void SystemClock_Config(void)
RCC_OscInitStruct.PLL.PLLN = 168;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 4;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
Error_Handler();
}
/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK
| 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)
{
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK) {
Error_Handler();
}
}
/* USER CODE END 4 */
/**
* @brief This function is executed in case of error occurrence.
* @retval None
*/
void Error_Handler(void)
{
void Error_Handler(void) {
/* USER CODE BEGIN Error_Handler_Debug */
/* User can add his own implementation to report the HAL error return state */
__disable_irq();
while (1)
{
while (1) {
}
/* USER CODE END Error_Handler_Debug */
}
@@ -234,8 +216,7 @@ void Error_Handler(void)
* @param line: assert_param error line source number
* @retval None
*/
void assert_failed(uint8_t *file, uint32_t line)
{
void assert_failed(uint8_t *file, uint32_t line) {
/* USER CODE BEGIN 6 */
/* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */

View File

@@ -0,0 +1,12 @@
add_subdirectory(led)
add_library(driver INTERFACE)
target_link_libraries(driver INTERFACE led_lib)
target_sources(driver INTERFACE ./base/interface.cpp)
target_include_directories(driver INTERFACE ./base)
if (DRIVER_CPP)
add_subdirectory(base/gpio)
target_compile_definitions(driver INTERFACE DRIVER_CPP)
endif ()

View File

@@ -0,0 +1,3 @@
add_library(gpio INTERFACE)
target_sources(gpio PUBLIC include/gpio_base.hpp)
target_include_directories(gpio INTERFACE ./include)

View File

@@ -0,0 +1,79 @@
//
// Created by Wind on 2025/11/9.
//
#ifndef CLION_STM32_GPIO_H
#define CLION_STM32_GPIO_H
#include "main.h"
class Gpio {
public:
enum class Mode {
Input,
Output,
Alternate,
Analog
};
enum class PULL {
None,
PullUp,
PullDown,
};
Gpio(GPIO_TypeDef *port, const uint16_t pin) : port_(port), pin_(pin) {
enableClock();
}
void setMode(const Mode mode, const PULL pull) const {
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = pin_;
switch (mode) {
case Mode::Input: GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
break;
case Mode::Output: GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
break;
case Mode::Alternate: GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
break;
case Mode::Analog: GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
break;
}
switch (pull) {
case PULL::None: GPIO_InitStruct.Pull = GPIO_NOPULL;
break;
case PULL::PullUp: GPIO_InitStruct.Pull = GPIO_PULLUP;
break;
case PULL::PullDown: GPIO_InitStruct.Pull = GPIO_PULLDOWN;
break;
}
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(port_, &GPIO_InitStruct);
}
void write(const bool v) const { HAL_GPIO_WritePin(port_, pin_, v ? GPIO_PIN_SET : GPIO_PIN_RESET); }
void toggle() const { HAL_GPIO_TogglePin(port_, pin_); }
bool read() const { return HAL_GPIO_ReadPin(port_, pin_); }
private:
GPIO_TypeDef *port_{};
uint16_t pin_{};
void enableClock() const {
if (port_ == GPIOA)
__HAL_RCC_GPIOA_CLK_ENABLE();
else if (port_ == GPIOB)
__HAL_RCC_GPIOB_CLK_ENABLE();
else if (port_ == GPIOC)
__HAL_RCC_GPIOC_CLK_ENABLE();
else if (port_ == GPIOD)
__HAL_RCC_GPIOD_CLK_ENABLE();
else if (port_ == GPIOE)
__HAL_RCC_GPIOE_CLK_ENABLE();
}
};
#endif //CLION_STM32_GPIO_H

View File

@@ -0,0 +1,33 @@
//
// Created by Wind on 2025/11/9.
//
#include "interface.h"
#include "led.h"
#ifdef DRIVER_CPP
#include "led_cpp.h"
void cpp_interface() {
const auto led = LED(LED_GPIO_Port, LED_Pin);
while (true) {
led.toggle();
HAL_Delay(50);
}
}
#endif
void interface() {
#ifdef DRIVER_CPP
cpp_interface();
#else
const led_t led = {
LED_GPIO_Port, LED_Pin
};
led_init(&led);
while (true) {
led_toggle(&led);
HAL_Delay(1000);
}
#endif
}

View File

@@ -0,0 +1,17 @@
//
// Created by Wind on 2025/11/9.
//
#ifndef CLION_STM32_CPP_INTERFACE_H
#define CLION_STM32_CPP_INTERFACE_H
#ifdef __cplusplus
extern "C" {
#endif
void interface();
#ifdef __cplusplus
}
#endif
#endif //CLION_STM32_CPP_INTERFACE_H

View File

@@ -1,11 +1,12 @@
option(FEATURE_LED "Build LED Module" ON)
if (FEATURE_LED)
add_library(led_lib INTERFACE)
add_library(led_lib INTERFACE)
target_sources(led_lib PUBLIC led.c)
if (FEATURE_LED)
if (DRIVER_CPP)
target_link_libraries(led_lib INTERFACE gpio)
target_sources(led_lib INTERFACE led_cpp.cpp)
endif ()
target_include_directories(led_lib INTERFACE ./include)
target_sources(led_lib INTERFACE led.c)
target_compile_definitions(led_lib INTERFACE FEATURE_LED)
endif ()

View File

@@ -5,10 +5,28 @@
#ifndef CLION_STM32_LED_H
#define CLION_STM32_LED_H
void led_on(void);
#include "main.h"
#ifdef __cplusplus
extern "C" {
void led_off(void);
#endif
typedef struct {
GPIO_TypeDef *port;
uint16_t pin;
} led_t;
void led_init(const led_t *led);
void led_on(const led_t *led);
void led_off(const led_t *led);
void led_toggle(const led_t *led);
#ifdef __cplusplus
}
#endif
#endif //CLION_STM32_LED_H

View File

@@ -0,0 +1,29 @@
//
// Created by Wind on 2025/11/9.
//
#ifndef CLION_STM32_LED_CPP_H
#define CLION_STM32_LED_CPP_H
#ifdef __cplusplus
#include "gpio_base.hpp"
class LED : public Gpio {
public:
LED(GPIO_TypeDef *port, uint16_t pin);
~LED();
void ledOn() const;
void ledOff() const;
void ledToggle() const;
};
#endif
#endif //CLION_STM32_LED_CPP_H

View File

@@ -4,13 +4,35 @@
#include "led.h"
#include "main.h"
void led_on(void) {
HAL_GPIO_WritePin(LED_GPIO_Port,LED_Pin,GPIO_PIN_SET);
void led_init(const led_t *led) {
const GPIO_TypeDef *port_ = led->port;
if (port_ == GPIOA)
__HAL_RCC_GPIOA_CLK_ENABLE();
else if (port_ == GPIOB)
__HAL_RCC_GPIOB_CLK_ENABLE();
else if (port_ == GPIOC)
__HAL_RCC_GPIOC_CLK_ENABLE();
else if (port_ == GPIOD)
__HAL_RCC_GPIOD_CLK_ENABLE();
else if (port_ == GPIOE)
__HAL_RCC_GPIOE_CLK_ENABLE();
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = led->pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(led->port, &GPIO_InitStruct);
}
void led_off(void) {
HAL_GPIO_WritePin(LED_GPIO_Port,LED_Pin,GPIO_PIN_RESET);
}
void led_on(const led_t *led) {
HAL_GPIO_WritePin(led->port, led->pin, GPIO_PIN_SET);
}
void led_off(const led_t *led) {
HAL_GPIO_WritePin(led->port, led->pin, GPIO_PIN_RESET);
}
void led_toggle(const led_t *led) {
HAL_GPIO_TogglePin(led->port, led->pin);
}

View File

@@ -0,0 +1,22 @@
//
// Created by Wind on 2025/11/9.
//
#include "include/led_cpp.h"
LED::LED(GPIO_TypeDef *port, const uint16_t pin) : Gpio(port, pin) {
}
LED::~LED() = default;
void LED::ledOn() const {
this->write(true);
}
void LED::ledOff() const {
this->write(false);
}
void LED::ledToggle() const {
this->toggle();
}