STM32C/C++/预处理指令/#define/#include/#if、#ifdef、#ifndef、#else、#endif/#pragma

STM32 中C 预处理指令:

#define

  1. #define BOOTLOADER_ADDRESS 0x08000000

  • 定义常量
    • 例如:#define BOOTLOADER_ADDRESS 0x08000000,在程序中使用BOOTLOADER_ADDRESS就相当于使用0x08000000。用于数学计算或者配置参数中,比如设置定时器的分频系数等。#define TIM_PRESCALER_VALUE 7199预处理指令定义了定时器的分频系数为7199
  • 定义宏
    • 可以定义带参数的宏来实现简单的函数功能。例如:#define  getFlashUint8Value(address)   (*((unsigned char *)(address)))getFlashUint8Value(0x08007000)就会被替换为(*((unsigned char *)(0x08007000)))。在 STM32 编程中,可能用于对寄存器操作进行简单的封装,比如#define  LED1_1  GPIOA->BSRR = GPIO_Pin_8,用于设置某个寄存器的指定位。

#include

  • 包含头文件
    • 例如:#include "stm32f10x.h",这是 STM32 编程中常见的,用于包含特定芯片型号的标准外设库头文件,其中定义了芯片的寄存器映射、外设结构体等。
    • 也可以使用<>包含标准库头文件,如#include <stdio.h>用于在程序中使用标准输入输出函数。

#if、#ifdef、#ifndef、#else、#endif

  • 条件编译
    • #if用于根据条件判断是否编译某段代码。例如:#if defined(STM32F103) &&!defined(DEBUG),只有当定义了STM32F103且没有定义DEBUG时,才会编译后续的代码块。
    • #ifdef#ifndef分别用于判断某个标识符是否已经定义。例如,在不同的开发阶段可能需要不同的配置,#ifdef DEBUG可以用来在调试阶段执行一些额外的调试输出代码,而在正式发布版本中不编译这些代码。

#pragma

在 STM32 编程中,#pragma 指令有以下一些常见的用法:

1. 控制结构体的字节对齐方式

  • 作用
    • 在与硬件寄存器交互或者进行数据序列化时,需要精确控制结构体的内存布局,确保数据在内存中的存储方式与硬件的预期相符。
  • 示例代码
// 设置结构体成员按 1 字节对齐
#pragma pack(1)
typedef struct {
    uint8_t field1;
    uint16_t field2;
    uint32_t field3;
} MyStruct;
// 恢复默认对齐方式
#pragma pack()

在上述代码中,#pragma pack(1) 强制结构体 MyStruct 的成员按 1 字节对齐。这样,field1field2 和 field3 在内存中是连续存储的,没有额外的填充字节。#pragma pack() 用于恢复编译器默认的字节对齐方式。

2. 控制代码的优化选项

  • 作用
    • 可以根据程序的具体需求,通过 #pragma 指令来调整编译器的优化级别,以平衡代码的执行效率和可调试性。
  • 示例代码
// 禁用当前函数的优化
#pragma GCC optimize ("O0")
void myFunction() {
    // 函数体
}
// 恢复默认优化级别
#pragma GCC optimize ("O2")

在这个例子中,#pragma GCC optimize ("O0") 禁用了对 myFunction 函数的优化,这在调试时可能很有用,因为优化后的代码可能会导致调试信息不准确。#pragma GCC optimize ("O2") 恢复了编译器的默认优化级别(假设默认是 - O2)。

3. 控制中断函数的编译

  • 作用
    • 在 STM32 中,中断服务函数需要特殊的编译处理,以确保它们能够正确响应中断并遵循特定的编程模型。
  • 示例代码
// 指定函数为中断服务函数
#pragma vector = TIM2_IRQn
__interrupt void TIM2_IRQHandler(void) {
    // 中断处理代码
}

这里,#pragma vector = TIM2_IRQn 告诉编译器该函数是定时器 2 中断(TIM2_IRQn)的服务函数。__interrupt 是特定编译器用于标识中断函数的关键字。不同的编译器可能有不同的方式来实现这一点。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值