写出高效优美的单片机C语言代码
WO(X,n)=X%(2^n) #define MOD_BY_POWER_OF_TWO( val, mod_by ) ( (dword)(val) (dword)((mod_by)-1) ) 18,对于IO空间映射在存储空间的结构,输入输出处理 #define inp(port) (*((volatile byte *) (port))) #define inpw(port) (*((volatile word *) (port))) #define inpdw(port) (*((volatile dword *)(port))) #define outp(port, val) (*((volatile byte *) (port)) = ((byte) (val))) #define outpw(port, val) (*((volatile word *) (port)) = ((word) (val))) #define outpdw(port, val) (*((volatile dword *) (port)) = ((dword) (val))) 19,使用一些宏跟踪调试 A N S I标准说明了五个预定义的宏名。它们是: _ L I N E _ _ F I L E _ _ D A T E _ _ T I M E _ _ S T D C _ 如果编译不是标准的,则可能仅支持以上宏名中的几个,或根本不支持。记住编译程序也许还提供其它预定义的宏名。 _ L I N E _及_ F I L E _宏指令在有关# l i n e的部分中已讨论,这里讨论其余的宏名。 _ D AT E _宏指令含有形式为月/日/年的串,表示源文件被翻译到代码时的日期。 源代码翻译到目标代码的时间作为串包含在_ T I M E _中。串形式为时:分:秒。 如果实现是标准的,则宏_ S T D C _含有十进制常量1。如果它含有任何其它数,则实现是非标准的。 可以定义宏,例如: 当定义了_DEBUG,输出数据信息和所在文件所在行 #ifdef _DEBUG #define DEBUGMSG(msg,date) printf(msg);printf(“%d%d%d”,date,_LINE_,_FILE_) #else #define DEBUGMSG(msg,date) #endif 20,宏定义防止使用时错误用小括号包含。 例如:#define ADD(a,b) (a+b) 用do{}while(0)语句包含多语句防止错误 例如:#difne DO(a,b) a+b; a++; 应用时:if(….) DO(a,b); //产生错误 else 解决方法: #difne DO(a,b) do{a+b; a++;}while(0) 宏中"#"和"##"的用法 一、一般用法 我们使用#把宏参数变为一个字符串,用##把两个宏参数贴合在一起. 用法: #include #include using namespace std; #define STR(s) #s #define CONS(a,b) int(a##e##b) int main() { printf(STR(vck)); // 输出字符串"vck" printf("%dn", CONS(2,3)); // 2e3 输出:2000 return 0; } 二、当宏参数是另一个宏的时候 需要注意的是凡宏定义里有用'#'或'##'的地方宏参数是不会再展开. 1, 非'#'和'##'的情况 #define TOW (2) #define MUL(a,b) (a*b) printf("%d*%d=%dn", TOW, TOW, MUL(TOW,TOW)); 这行的宏会被展开为: printf("%d*%d=%dn", (2), (2), ((2)*(2))); MUL里的参数TOW会被展开为(2). 2, 当有'#'或'##'的时候 #define A (2) #define STR(s) #s #define CONS(a,b) int(a##e##b) printf("int max: %sn", STR(INT_MAX)); // INT_MAX #include 这行会被展开为: printf("int max: %sn", "INT_MAX"); printf("%sn", CONS(A, A)); // compile error 这一行则是: printf("%sn", int(AeA)); INT_MAX和A都不会再被展开, 然而解决这个问题的方法很简单. 加多一层中间转换宏. 加这层宏的用意是把所有宏的参数在这层里全部展开, 那么在转换宏里的那一个宏(_STR)就能得到正确的宏参数. #define A (2) #define _STR(s) #s #define STR(s) _STR(s) // 转换宏 #define _CONS(a,b) int(a##e##b) #define CONS(a,b) _CONS(a,b) // 转换宏 printf("int max: %sn", STR(INT_MAX)); // INT_MAX,int型的最大值,为一个变量 #include 输出为: int max: 0x7fffffff STR(INT_MAX) --> _STR(0x7fffffff) 然后再转换成字符串; printf("%dn", CONS(A, A)); 输出为:200 CONS(A, A) --> _CONS((2), (2)) --> int((2)e(2)) 三、'#'和'##'的一些应用特例 1、合并匿名变量名 #define ___ANONYMOUS1(type, var, line) type var##line #define __ANONYMOUS0(type, line) ___ANONYMOUS1(type, _anonymous, line) #define ANONYMOUS(type) __ANONYMOUS0(type, __LINE__) 例:ANONYMOUS(static int); 即: static int _anonymous70; 70表示该行行号; 第一层:ANONYMOUS(static int); --> __ANONYMOUS0(static int, __LINE__); 第二层: --> ___ANONYMOUS1(static int, _anonymous, 70); 第三层: --> static int _anonymous70; 即每次只能解开当前层的宏,所以__LINE__在第二层才能被解开; 2、填充结构 #define FILL(a) {a, #a} enum IDD{OPEN, CLOSE}; typedef struct MSG{ IDD id; const char * msg; }MSG; MSG _msg[] = {FILL(OPEN), FILL(CLOSE)}; 相当于: MSG _msg[] = {{OPEN, "OPEN"}, {CLOSE, "CLOSE"}}; 3、记录文件名 #define _GET_FILE_NAME(f) #f #define GET_
- 3DES算法的FPGA高速实现(06-21)
- 巴西的新电视机顶盒采用意法半导体(ST)的最先进的解码器技术(03-24)
- 基于DSP和USB的高速数据采集与处理系统设计(05-01)
- 用DSP56F805 PWM模块输出高频正弦波(05-25)
- SHARC引领第四代通用DSP高端应用潮流(09-27)
- 基于DSP的光纤高温测量仪的软件设计 (04-08)