Arduino代码机制-Arduino.h
2016-02-14 16:04
232 查看
刚看到前两天写的博客竟然有两个人看了,还是很激动的,如果有评论那就更好啦。
这个头文件做的事情非常多,定义了一些常数,还定义了一些“函数”,申明了一些常用函数。
看到我们常用的min,max竟然是宏定义有没有一点震惊。被误导了很久了吧?明明是宏为什么不用大写!太误导人了!
现在来解释下为什么要这样写。
首先宏并不一定要大写,没有人这么告诉过我们宏一定要大写,只是我们常常见到的宏都是大写的,才会有这样的认识。由于宏不进行类型检查,所以它常常隐藏着不安全的问题,所以才将宏大写,来告诉使用者:这是个宏,它可能是不安全的,你使用它要非常小心。
那么上面这几个宏安全么?以min(a, b)为例来说,如果传递给a,b的都是char, int, float这样的类型的话,那肯定不会出现问题,结果是正确的。倘若一不小心将一个指针传递给了a,将int类型的对象传递给了b,就像这样:
会出问题么?将min(a, b)替换后是:
由于运算符<不能比较指针和整形,所以在编译期间编译器会报错,这个错误不会带到运行期间去,所以这方面来说,它是安全的。
更好的是,这个宏还能比较类的对象,只要在类中重载了这个运算符即可。
正因为这个宏很方便而且又是安全的,开发者并不希望用户关心它是个宏还是函数,就把它写成了这样。你就把它当作函数使用好了。
假如我们不使用宏定义而用函数来解决这个问题呢?那就非常麻烦了,因为函数要进行类型检查,就必须给每一种类型的比较提供一个函数,那将是很多个重载函数。有人会说可以用模板呀,是可以,但哪有宏定义来得简单呢。
还有这样的宏,看名字就能理解就不解释啦。大量的使用了移位操作和按位与或取反操作,这是因为这样的操作效率很高,比if判断效率高多了。使用宏定义还避免了调用函数时的参数压栈出栈操作,效率高。
可能对最后一个函数不了解,解释一下
函数实现:
就是将[in_min, in_max]中的一个数x映射到[out_min, out_max]中去。
其他函数都很熟悉吧,原来是在这里申明的,不用多说了吧?
Arduino.h源文件的路径为:
\hardware\arduino\avr\cores\arduino\Arduino.h
这个头文件做的事情非常多,定义了一些常数,还定义了一些“函数”,申明了一些常用函数。
宏定义常数
一些常用常数和设置
在注释中给出解释#define HIGH 0x1//定义高低电平,对引脚读写时用到 #define LOW 0x0//digitalWrite函数会用到 #define INPUT 0x0//设置引脚模式,输入 #define OUTPUT 0x1//输出 #define INPUT_PULLUP 0x2//输入上拉,pinMode函数 //一些常用常数 #define PI 3.1415926535897932384626433832795 #define HALF_PI 1.5707963267948966192313216916398 #define TWO_PI 6.283185307179586476925286766559 #define DEG_TO_RAD 0.017453292519943295769236907684886 #define RAD_TO_DEG 57.295779513082320876798154814105 #define EULER 2.718281828459045235360287471352 //串口通信中的设置,设置传输数据是高位在前还是低位在前 #define LSBFIRST 0 #define MSBFIRST 1 //外部中断模式 #define CHANGE 1//电平改变触发方式 #define FALLING 2//下降沿触发 #define RISING 3//上升沿触发
定义输出端口和读取Flash的宏
上一篇博客讲到啦就不说了宏定义“函数”
贴代码,这些看起来像函数的东西可不是函数啊,注意咯#define min(a,b) ((a)<(b)?(a):(b)) #define max(a,b) ((a)>(b)?(a):(b)) #define abs(x) ((x)>0?(x):-(x)) #define round(x) ((x)>=0?(long)((x)+0.5):(long)((x)-0.5))//四舍五入取整,写的巧妙吧,不用if来判断 #define radians(deg) ((deg)*DEG_TO_RAD)//角度弧度转换 #define degrees(rad) ((rad)*RAD_TO_DEG) #define sq(x) ((x)*(x))
看到我们常用的min,max竟然是宏定义有没有一点震惊。被误导了很久了吧?明明是宏为什么不用大写!太误导人了!
现在来解释下为什么要这样写。
首先宏并不一定要大写,没有人这么告诉过我们宏一定要大写,只是我们常常见到的宏都是大写的,才会有这样的认识。由于宏不进行类型检查,所以它常常隐藏着不安全的问题,所以才将宏大写,来告诉使用者:这是个宏,它可能是不安全的,你使用它要非常小心。
那么上面这几个宏安全么?以min(a, b)为例来说,如果传递给a,b的都是char, int, float这样的类型的话,那肯定不会出现问题,结果是正确的。倘若一不小心将一个指针传递给了a,将int类型的对象传递给了b,就像这样:
int *a = 1; int b = 2; min(a, b);
会出问题么?将min(a, b)替换后是:
(a < b)?a:b;
由于运算符<不能比较指针和整形,所以在编译期间编译器会报错,这个错误不会带到运行期间去,所以这方面来说,它是安全的。
更好的是,这个宏还能比较类的对象,只要在类中重载了这个运算符即可。
正因为这个宏很方便而且又是安全的,开发者并不希望用户关心它是个宏还是函数,就把它写成了这样。你就把它当作函数使用好了。
假如我们不使用宏定义而用函数来解决这个问题呢?那就非常麻烦了,因为函数要进行类型检查,就必须给每一种类型的比较提供一个函数,那将是很多个重载函数。有人会说可以用模板呀,是可以,但哪有宏定义来得简单呢。
还有这样的宏,看名字就能理解就不解释啦。大量的使用了移位操作和按位与或取反操作,这是因为这样的操作效率很高,比if判断效率高多了。使用宏定义还避免了调用函数时的参数压栈出栈操作,效率高。
#define lowByte(w) ((uint8_t) ((w) & 0xff)) #define highByte(w) ((uint8_t) ((w) >> 8)) #define bitRead(value, bit) (((value) >> (bit)) & 0x01) #define bitSet(value, bit) ((value) |= (1UL << (bit))) #define bitClear(value, bit) ((value) &= ~(1UL << (bit))) #define bitWrite(value, bit, bitvalue) (bitvalue ? bitSet(value, bit) : bitClear(value, bit))
申明的函数
这才是真的函数void pinMode(uint8_t, uint8_t); void digitalWrite(uint8_t, uint8_t); int digitalRead(uint8_t); int analogRead(uint8_t); void analogReference(uint8_t mode); void analogWrite(uint8_t, int); unsigned long millis(void); unsigned long micros(void); void delay(unsigned long); void delayMicroseconds(unsigned int us); void attachInterrupt(uint8_t, void (*)(void), int mode); void detachInterrupt(uint8_t); void setup(void); void loop(void); void tone(uint8_t _pin, unsigned int frequency, unsigned long duration = 0); void noTone(uint8_t _pin); long random(long); long random(long, long); void randomSeed(unsigned int); long map(long, long, long, long, long);
可能对最后一个函数不了解,解释一下
函数实现:
long map(long x, long in_min, long in_max, long out_min, long out_max) { return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; }
就是将[in_min, in_max]中的一个数x映射到[out_min, out_max]中去。
其他函数都很熟悉吧,原来是在这里申明的,不用多说了吧?
Arduino.h源文件的路径为:
\hardware\arduino\avr\cores\arduino\Arduino.h
相关文章推荐
- Android开发中无处不在的设计模式——Builder模式
- POJ 2524 Ubiquitous Religions
- Longest Increasing Subsequence
- ruiaijun人工智能理论纪录片:《反射算法与离散智能编程》《自编程自主学习算法》
- poj2926 Requirements
- API Guides(二)——Activity To AIDL
- iOS7 iOS8 UITableviewCell处于编辑状态,dismiss或者back崩溃
- WeUI logo专为微信设计的 UI 库 WeUI
- 在一般处理文件中访问Session需要添加IRequiresSessionState
- BlockingQueue简介
- 编译ionic项目的时候提示: Please install the Android build tools version 19.1.0 or higher.
- squirrel sql client 连接phoenix
- EasyUi 中datagrid 实现查询方法
- rpmbuild常用命令
- cf#ecr7-A. Infinite Sequence-暴力/二分-数学
- jmeter jdbc request使用详解
- 11.UIView的transform属性
- 【摘】 pt-query-digest工具一解
- UILabel textAlignment 居中 左右对齐
- 【转】Android低功耗蓝牙应用开发获取的服务UUID