嵌入式开发常见宏定义

目录

一、编译器预定义的宏

二、c语言内置宏

三、实用宏定义


一、编译器预定义的宏

        在stm32系列单片机里的core_cmx.h(x:0/3/4/7)头文件里有如下一段宏定义:

/* define compiler specific symbols */
#if defined ( __CC_ARM   )
  #define __ASM            __asm          /*!< asm keyword for ARM Compiler          */
  #define __INLINE         __inline       /*!< inline keyword for ARM Compiler       */
  #define __STATIC_INLINE  static __inline

#elif defined (  __GNUC__  )
  #define __ASM            __asm          /*!< asm keyword for GNU Compiler          */
  #define __INLINE         inline         /*!< inline keyword for GNU Compiler       */
  #define __STATIC_INLINE  static inline

#elif defined ( __ICCARM__ )
  #define __ASM            __asm          /*!< asm keyword for IAR Compiler          */
  #define __INLINE         inline         /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */
  #define __STATIC_INLINE  static inline

#elif defined ( __TMS470__ )
  #define __ASM            __asm          /*!< asm keyword for TI CCS Compiler       */
  #define __STATIC_INLINE  static inline

#elif defined (  __TASKING__  )
  #define __ASM            __asm          /*!< asm keyword for TASKING Compiler      */
  #define __INLINE         inline         /*!< inline keyword for TASKING Compiler   */
  #define __STATIC_INLINE  static inline

#elif defined ( __CSMC__ )
  #define __packed
  #define __ASM            _asm           /*!< asm keyword for COSMIC Compiler      */
  #define __INLINE         inline         /*use -pc99 on compile line !< inline keyword for COSMIC Compiler   */
  #define __STATIC_INLINE  static inline

#endif

        在嵌入式开发中,单片机可以在不同的平台上进行使用,例如stm32单片机可以在IAR平台上进行开发,也可以在KEIL平台上开发。不同的开发平台有不同的编译器,不同的编译器所使用的工具链也不同。在不同的工具链中,c文件和汇编文件中inline和asm关键字的写法也不同。为了兼容不同平台,增强代码的可移植性,在代码里使用宏定义替代,这样就能在不同编译器预处理时产生适用于该工具链的代码。

PS:   __CC_ARM                       // ARM编译器预定义宏
         __GNUC__                       // GNU 编译器的预定义宏
         __ICCARM__                    // IAR编译器预定义宏
         __TMS470__                    // CCS编译器预定义宏
         __TASKING__                  // TASKING编译器预定义宏
         __CSMC__                       // COSMIC编译器预定义宏

二、c语言内置宏

        C语言中有许多内置宏,在嵌入式开发中,这些内置宏常用在代码的跟踪调试,输入日志或者版本控制等等,下面列举一些常用的内置宏:

__DATE__     当前日期,输出格式为 "MMM DD YYYY"
__TIME__      当前时间,输出格式为 "HH:MM:SS"
__FILE__       当前文件名
__LINE__       当前行号
__STDC__     当编译器以 ANSI 标准编译时,则输出 1
__FUNCTION__(或者__func__ )   所在函数名的字符串

其中,__DATE__ 和__TIME__常用来输出软件版本信息。

#include 
 
const char Version[]="Version 0.0.1 ";
 
int main(void) 
{
    printf("%s,%s,%s",Version,__DATE__,__TIME__);
	
    return 0;
}

__FILE__和__LINE__常用来定位,跟踪调试。

//stm32f10x_conf.h
#ifdef  USE_FULL_ASSERT
  #define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__))
  void assert_failed(uint8_t* file, uint32_t line);
#else
  #define assert_param(expr) ((void)0)
#endif /* USE_FULL_ASSERT */

//stm32f10x_adc.c
void ADC_DeInit(ADC_TypeDef* ADCx)
{
  /* Check the parameters */
  assert_param(IS_ADC_ALL_PERIPH(ADCx));
  ...
}

上面两个代码片段只是简单的说明内置宏的用法,在实际的项目开发中,灵活地去运用这些内置宏对我们在调试阶段有很大帮助。

三、实用宏定义

1.最大值和最小值

#define MAX(x, y) (((x)>(y))?(x):(y))
#define MIN(x, y) (((x)<(y))?(x):(y))

2.交换两个变量的值

//加减法实现
#define SWAP(x, y)\
do\ 
{\
    x = x + y;\
    y = x - y;\
    x = x - y;\
}while(0)

3.数组元素个数

#define ARRAY_SIZE(array) (sizeof((array))/sizeof((array[0])))

4.位操作

//将data的第bit位置为1
#define SET_BIT(data,bit)   ((data) |= (1<<(bit)))

//将data的第bit位清零
#define CLR_BIT(data,bit)   ((data) &= (~(1<<(bit))))

//将data的第bit位取反
#define CPL_BIT(data,bit)   ((data) ^= ((1<<(bit))))

//获取data的第bit位
#define GET_BIT(data,bit)   ((data) & (1<<(bit)))

你可能感兴趣的:(嵌入式编程,c语言,单片机)