编译时条件处理
针对不同平台特性采用条件编译:c
运行
// 跨平台对齐解决方案
#ifdef STM32F103xx
// STM32允许非对齐,直接使用8位数组
uint8_t ws2812_buffer;
#define WS2812_BUF_ADDR (uint32_t)ws2812_buffer
#elif defined(GD32F130xx)
// GD32需要32位对齐,使用对齐数组
uint32_t ws2812_buffer[(WS2812_BUF_SIZE + 3) / 4];
#define WS2812_BUF_ADDR (uint32_t)ws2812_buffer
#define WS2812_BUF_8BIT ((uint8_t *)ws2812_buffer)
#elif defined(LPC1768)
// LPC系列使用特殊对齐属性
__attribute__((aligned(4))) uint8_t ws2812_buffer;
#define WS2812_BUF_ADDR (uint32_t)ws2812_buffer
#endif
// 统一的数据填充接口
void ws2812_set_led(uint32_t index, uint8_t r, uint8_t g, uint8_t b) {
#ifdef GD32F130xx
// 使用8位指针访问32位数组
uint32_t pos = index * 3;
WS2812_BUF_8BIT = g; // WS2812通常是GRB顺序
WS2812_BUF_8BIT = r;
WS2812_BUF_8BIT = b;
#else
// 其他平台的实现...
#endif
}
优势:针对不同平台优化,兼顾兼容性与效率缺点:增加了代码量,需要维护多平台适配代码
非常核心且实用的单片机开发技巧。 过多的 #if/#ifdef 会使代码结构变得复杂,难以阅读和维护 非常有用的防御性编程技巧。如果某个必要的宏未被定义或设置了错误的值,#error 可以强制编译失败,并给出明确的错误信息。 每个C程序员都必须掌握的技巧,用于防止头文件被重复包含。 在开发过程中,可能需要针对不同的硬件平台或配置编译不同的代码。 忘记 #endif 导致后续代码错位 处理不同编译器(Keil, IAR, GCC)之间的语法差异或特定关键字。 通过一系列以 # 开头的指令来实现。 尽量缩小条件编译的作用域,避免污染全局命名空间。 不同编译器对预处理器扩展支持不同。 #ifdef 如果指定宏已定义,则编译后续代码 使用 #ifndef / #define / #endif 防止头文件重复包含 在代码编译阶段,根据宏定义的真假,来决定某段代码是否被编译。 条件编译是指编译器根据实际的定义宏有选择性地对代码进行静态编译,可以根据表达式中的条件和某个特定宏是否被定义来确定编译条件 #ifdef 和 #ifndef:检查宏是否被定义 #elif defined(...) 是一种更安全的写法,即使宏未定义,也不会产生编译警告。 单片机编译时条件处理是嵌入式开发中一项至关重要的技术 对于多层嵌套的条件编译,在 #endif 后面加上注释,标明它结束的是哪个 #if 或 #ifdef,极大提高代码可读性。 不满足条件的代码根本不会出现在最终的程序文件中,因此不占用Flash空间。