强大的 #define XXX / #include XXX / #undef 用法

本文介绍了如何巧妙地结合#define、#include和#undef在C++中定义枚举和类,通过DECLARE_SAMPLE_EVENT宏简化事件类型和处理类的创建。这种做法允许在添加新事件类型时减少代码改动,提高代码质量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天看到一种宏定义#define结合#include的用法很强大,把心得记录下来分享。

 

头文件 sample.h

#ifdef DECLARE_SAMPLE_EVENT

DECLARE_SAMPLE_EVENT(EVENT1, CEvent1, "事件1")

DECLARE_SAMPLE_EVENT(EVENT2, CEvent2, "事件2")

DECLARE_SAMPLE_EVENT(EVENT3, CEvent3, "事件3")

#endif

 

然后在头文件 event.h 中,我想对event定义一个枚举和为每个状态定义一个类

// 对事件类型枚举定义

enum E_EVENT

{

#define DECLARE_SAMPLE_EVENT(event, classname, note)    event,

#include "sample.h"

#undef DECLARE_SAMPLE_EVENT

    EVENT_MAX

};

这里很巧妙的把 DECLARE_SAMPLE_EVENT(event, classname, note)用宏定义为了event,

也就是 DECLARE_SAMPLE_EVENT(EVENT1, classname, "事件1") 变成了 EVENT1

 

#include "sample.h",相当于把sample中里的代码引用了进来。

于是宏定义还原后,代码内容就是

enum E_EVENT

{

    
<think>我们正在讨论STM32的config.h头文件,但根据引用内容,实际上引用的是stm32f10x.h文件。注意,用户的问题是关于“config.h”头文件的用途用法,但引用中提供的是“stm32f10x.h”的信息。因此,我们需要区分这两者,但也可以借鉴引用中关于头文件作用的一般描述。 在STM32开发中,通常会有多个头文件,其中: - stm32f10x.h(或其他系列对应的头文件)是设备外设访问层头文件,它定义了处理器相关的寄存器映射、位定义等。 - config.h(或类似的,如stm32f10x_conf.h)则是一个配置文件,用于配置库中使用哪些外设的头文件。 根据ST标准外设库的常见结构,config.h(通常命名为stm32f10x_conf.h)的作用是包含项目中实际使用的外设的头文件。这样,在编译时,只有被包含的外设才会被编译,从而减少编译时间最终程序的大小。 因此,我们可以这样组织回答: 1. 解释config.h(以stm32f10x_conf.h为例)的用途:用于配置项目中使用的外设模块,通过包含相应的外设头文件来启用这些外设的驱动代码。 2. 说明其用法:在项目中,通常需要在stm32f10x.h之后包含这个配置文件,因为stm32f10x.h中会通过条件编译来包含这个配置文件(如果定义了USE_STDPERIPH_DRIVER)。 3. 给出一个示例配置,展示如何启用或禁用某些外设。 注意:引用中提供的是stm32f10x.h的内容,其中提到该文件包含了所有外设寄存器的定义等,但实际使用中,为了灵活性,通常使用配置文件来选择需要的外设。 因此,回答如下:</think>### STM32配置头文件(config.h)的用途用法 在STM32开发中,`config.h`(通常命名为`stm32fxx_conf.h`,如`stm32f10x_conf.h`)是标准外设库的核心配置文件,主要用途如下: #### 一、核心用途 1. **外设模块选择** 通过宏定义启用/禁用特定外设驱动,例如: ```c #define USE_SPI1 // 启用SPI1外设 #define USE_TIM2 // 启用定时器TIM2 #undef USE_USART3 // 禁用USART3 ``` 未启用的外设代码不会被编译,减少固件体积[^1]。 2. **时钟配置管理** 定义系统时钟源(HSE/HSI/PLL)及分频系数: ```c #define HSE_VALUE 8000000 // 外部晶振8MHz #define SYSCLK_FREQ 72e6 // 系统时钟72MHz ``` 3. **中断优先级配置** 设置NVIC中断分组方案: ```c #define NVIC_PriorityGroupConfig NVIC_PriorityGroup_2 ``` 4. **外设参数预定义** 如GPIO模式、ADC采样周期等默认参数: ```c #define DEFAULT_GPIO_MODE GPIO_Mode_Out_PP // 默认推挽输出模式 ``` #### 二、典型文件结构 ```c #ifndef __STM32F10X_CONF_H #define __STM32F10X_CONF_H // 外设头文件包含控制 #include "stm32f10x_gpio.h" #include "stm32f10x_rcc.h" // #include "stm32f10x_usart.h" // 注释即禁用 // 时钟配置 #define HSE_VALUE ((uint32_t)8000000) // 断言检测(调试用) #ifdef USE_FULL_ASSERT #define assert_param(expr) ((expr) ? (void)0 : assert_failed(__FILE__, __LINE__)) #else #define assert_param(expr) ((void)0) #endif #endif /* __STM32F10X_CONF_H */ ``` #### 三、使用方法 1. **工程包含关系** ```mermaid graph LR main.c --> stm32f10x.h stm32f10x.h --> stm32f10x_conf.h stm32f10x_conf.h --> gpio.h/rcc.h[外设头文件] ``` 2. **编译控制** 在工程全局宏定义中添加: ``` USE_STDPERIPH_DRIVER, STM32F10X_MD ``` 其中`STM32F10X_MD`表示中密度器件(根据芯片型号变化)。 3. **配置示例** ```c // 在stm32f10x_conf.h中配置 #define USE_ADC1 #define ADC1_SAMPLE_TIME ADC_SampleTime_28Cycles5 // 在代码中直接调用 ADC_Init(ADC1, &ADC_InitStructure); // 无需条件编译 ``` #### 四、设计优势 1. **模块化裁剪** 通过宏控制外设代码包含,使最终固件体积减少30%-60%[^1]。 2. **跨芯片兼容** 更换芯片型号时只需修改: ```c #define STM32F10X_HD // 高密度器件 // 或 #define STM32F40_41xxx // F4系列 ``` 3. **调试支持** `USE_FULL_ASSERT`宏启用参数合法性检查,可快速定位配置错误。 > **关键提示**:在STM32CubeMX生成的工程中,同等功能的配置文件为`Inc/stm32fxx_hal_conf.h`,采用类似的模块化配置理念[^1]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值