您的位置:首页 > 产品设计 > UI/UE

Arduino代码机制-Arduino.h

2016-02-14 16:04 232 查看
刚看到前两天写的博客竟然有两个人看了,还是很激动的,如果有评论那就更好啦。

这个头文件做的事情非常多,定义了一些常数,还定义了一些“函数”,申明了一些常用函数。

宏定义常数

一些常用常数和设置

在注释中给出解释

#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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: