Arduino 的程序能够划分为三个主要部分:结构、变量(变量与常量)、函数。git
结构部分程序员
1、结构算法
1.1 setup()express
1.2 loop()编程
2、结构控制数组
2.1 if缓存
2.2 if...else数据结构
2.3 for多线程
2.4 switch casedom
2.5 while
2.6 do... while
2.7 break
2.8 continue
2.9 return
2.10 goto
3、扩展语法
3.1 ;(分号)
3.2 {}(花括号)
3.3 //(单行注释)
3.4 /* */(多行注释)
3.5 #define
3.6 #include
4、算数运算符
4.1 =(赋值运算符)
4.2 +(加)
4.3 -(减)
4.4 *(乘)
4.5 /(除)
4.6 %(模)
5、比较运算符
5.1 ==(等于)
5.2 !=(不等于)
5.3 <(小于)
5.4 >(大于)
5.5 <=(小于等于)
5.6 >=(大于等于)
6、布尔运算符
6.1 &&(与)
6.2 ||(或)
6.3 !(非)
7、指针运算符
7.1 * 取消引用运算符
7.2 & 引用运算符
8、位运算符
8.1 & (bitwise and)
8.2 | (bitwise or)
8.3 ^ (bitwise xor)
8.4 ~ (bitwise not)
8.5 << (bitshift left)
8.6 >> (bitshift right)
9、复合运算符
9.1 ++ (increment)
9.2 -- (decrement)
9.3 += (compound addition)
9.4 -= (compound subtraction)
9.5 *= (compound multiplication)
9.6 /= (compound division)
9.6 &= (compound bitwise and)
9.8 |= (compound bitwise or)
变量部分
10、常量
10.1 HIGH|LOW(引脚电压定义)
10.2 INPUT|OUTPUT(数字引脚(Digital pins)定义)
10.3 true | false(逻辑层定义)
10.4 integer constants(整数常量)
10.5 floating point constants(浮点常量)
11、数据类型
11.1 void
11.2 boolean(布尔)
11.3 char(有号数据类型)
11.4 unsigned char(无符号数据类型)
11.5 byte(无符号数)
11.6 int(整型)
11.7 unsigned int(无符号整型)
11.8 word
11.9 long(长整数型)
11.10 unsigned long(无符号长整数型)
11.11 float(浮点型数)
11.12 double(双精度浮点数)
11.13 string(char array/字符串)
11.14 String object(String类)
11.15 array (数组)
12、数据类型转换
12.1 char()
12.2 byte()
12.3 int()
12.4 word()
12.5 long()
12.6 float()
十3、变量做用域 & 修饰符
13.1 variable scope(变量的做用域)
13.2 static(静态变量)
13.3 volatile
13.4 const
十4、辅助工具
14.1 sizeof()
函数部分
十5、数字 I/O
15.1 pinMode()
15.2 digitalWrite()
15.3 digitalRead()
十6、模拟 I/O
16.1 analogReference()
16.2 analogRead()
16.3 analogWrite() PWM
十7、高级 I/O
17.1 tone()
17.2 noTone()
17.3 shiftOut()
17.4 shiftIn()
17.5 pulseIn()
十8、时间
18.1 millis()
18.2 micros()
18.3 delay()
18.4 delayMicroseconds()
十9、数学运算
19.1 min()
19.2 max()
19.3 abs()
19.4 constrain()
19.5 map()
19.6 pow()
19.7 sqrt()
19.8 ceil()
19.9 exp()
19.10 fabs()
19.11 floor()
19.12 fma()
19.13 fmax()
19.14 fmin()
19.15 fmod()
19.16 ldexp()
19.17 log()
19.18 log10()
19.19 round()
19.20 signbit()
19.21 sq()
19.22 square()
19.23 trunc()
二10、三角函数
20.1 sin()
20.2 cos()
20.3 tan()
20.4 acos()
20.5 asin()
20.6 atan()
20.7 atan2()
20.8 cosh()
20.9 degrees()
20.10 hypot()
20.11 radians()
20.12 sinh()
20.13 tanh()
二11、随机数
21.1 randomSeed()
21.2 random()
二12、位操做
22.1 lowByte()
22.2 highByte()
22.3 bitRead()
22.4 bitWrite()
22.5 bitSet()
22.6 bitClear()
22.7 bit()
二十3、设置中断函数
23.1 attachInterrupt()
23.2 detachInterrupt()
二十4、开关中断
24.1 interrupts()(中断)
24.2 noInterrupts()(禁止中断)
二十5、通信
25.1 Serial
25.1.1 if (Serial)
25.1.2 Serial.available()
25.1.3 Serial.begin()
25.1.4 Serial.end()
25.1.5 Serial.find()
25.1.6 Serial.findUntil()
25.1.7 Serial.flush()
25.1.8 Serial.parseFloat()
25.1.9 Serial.parseInt()
25.1.10 Serial.peek()
25.1.11 Serial.print()
25.1.12 Serial.println()
25.1.13 Serial.read()
25.1.14 Serial.readBytes()
25.1.15 Serial.readBytesUntil()
25.1.16 Serial.setTimeout()
25.1.17 Serial.write()
25.1.18 Serial.SerialEvent()
25.2 Stream
二十6、USB(仅适用于 Leonardo 和 Due)
26.1 Mouse(键盘)
26.2 Keyboard(鼠标)
如下是示例部分含详细注解
结构部分
1、结构
1.1 setup()
在Arduino中程序运行时将首先调用 setup() 函数。用于初始化变量、设置针脚的输出\输入类型、配置串口、引入类库文件等等。每次 Arduino 上电或重启后,setup 函数只运行一次。
示例
int buttonPin = 3;//定义一个变量buttonPin为针脚3
void setup()
{
Serial.begin(9600);//定义初始串口波特率为9600
pinMode(buttonPin, INPUT);//定义buttonPin也就是前面定义的针脚3为input输入针脚
}
void loop()
{
// ...
}
1.2 loop()
在 setup() 函数中初始化和定义了变量,而后执行 loop() 函数。顾名思义,该函数在程序运行过程当中不断的循环,根据一些反馈,相应改变执行状况。经过该函数动态控制 Arduino 主控板。
示例
int buttonPin = 3; // setup 中初始化串口和按键针脚.
void setup()
{
beginSerial(9600);
pinMode(buttonPin, INPUT);
}
// loop 中每次都检查按钮,若是按钮被按下,就发送信息到串口
void loop()
{
if (digitalRead(buttonPin) == HIGH)//经过eigitalRead读取到针脚3的电平值是否为高
serialWrite('H');//是高就经过串口写出H
else
serialWrite('L');//若是不是就经过串口写出L
delay(1000);//延时1000毫秒,也就是1秒
}
2、结构控制
2.1 if
if(条件判断语句)和 ==、!=、<、>(比较运算符)
if 语句与比较运算符一块儿用于检测某个条件是否达成,如某输入值是否在特定值之上等。if 语句的语法是:
if (someVariable > 50)
{
// 执行某些语句
}
本程序测试 someVariable 变量的值是否大于 50。当大于 50 时,执行一些语句。换句话说,只要 if 后面括号里的结果(称之为测试表达式)为真,则执行大括号中的语句(称之为执行语句块);若为假,则跳过大括号中的语句。 if 语句后的大括号能够省略。若省略大括号,则只有一条语句(以分号结尾)成为执行语句。
下面几种写法都是正确的:
第一种:
if (x > 120) digitalWrite(LEDpin, HIGH);//判断x的值是否是大于120,是的话就让LEDpin这个针脚的电平成为高电平
第二种:
if (x > 120)
digitalWrite(LEDpin, HIGH);
第三种:
if (x > 120){ digitalWrite(LEDpin, HIGH); }
第四种:
if (x > 120){
digitalWrite(LEDpin1, HIGH);
digitalWrite(LEDpin2, HIGH);
}
在小括号里求值的表达式,须要如下操做符:
比较运算操做符:
x == y(x 等于 y)注意这是等于,并非赋值,赋值是=
x != y(x 不等于 y)
x < y(x 小于 y)
x > y(x 大于 y)
x <= y(x 小于等于 y)
x >= y(x 大于等于 y)
警告:
注意使用赋值运算符的状况(如 if (x = 10))。一个“=”表示的是赋值运算符,做用是将 x 的值设为 10(将值 10 放入 x 变量的内存中)。两个“=”表示的是比较运算符(如 if (x == 10)),用于测试 x 和 10 是否相等。后面这个语句只有 x 是 10 时才为真,而前面赋值的那个语句则永远为真。
这是由于 C 语言按如下规则进行运算 if (x=10):10 赋值给 x(只要非 0 的数赋值的语句,其赋值表达式的值永远为真),所以 x 如今值为 10。此时 if 的测试表达式值为 10,该值永远为真,由于非 0 值永远为真。因此,if (x = 10) 将永远为真,这就不是咱们运行 if 所期待的结果。另外,x 被赋值为 10,这也不是咱们所期待的结果。
if 的另一种分支条件控制结构是 if...else 形式。
2.2 if...else
if/else是比if更为高级的流程控制语句,它能够进行屡次条件测试。好比,检测模拟输入的值,当它小于500时该执行哪些操做,大于或等于500时执行另外的操做。代码以下:
if (pinFiveInput < 500)
{
// 执行A操做
}
else
{
// 执行B操做
}
else能够进行额外的if检测,因此多个互斥的条件能够同时进行检测。
测试将一个一个进行下去,直到某个测试结果为真,此时该测试相关的执行语句块将被运行,而后程序就跳过剩下的检测,直接执行到if/else的下一条语句。当全部检测都为假时,若存在else语句块,将执行默认的else语句块。
注意else if语句块能够没有else语句块。else if分支语句的数量无限制。
if (pinFiveInput < 500)
{
// 执行A操做
}
else if (pinFiveInput >= 1000)
{
// 执行B操做
}
else
{
// 执行C操做
}
另一种进行多种条件分支判断的语句是switch case语句。
2.3 for
for语句
描述
for语句用于重复执行一段在花括号以内的代码。一般使用一个增量计数器计数并终止循环。for语句用于重复性的操做很是有效,一般与数组结合起来使用来操做数据、引脚。
for循环开头有3个部分:
(初始化;条件;增量计数){
//语句
}
“初始化”只在循环开始执行一次。每次循环,都会检测一次条件;若是条件为真,则执行语句和“增量计数”,以后再检测条件。当条件为假时,循环终止。
例子
//用PWM引脚将LED变暗
int PWMpin = 10; //将一个LED与47Ω电阻串联接在10号针脚
void setup()
{
//无需设置
}
void loop()
{
for (int i=0; i <= 255; i++)//定义一个变量i,并赋值为0,当i小于等于255的时候i就加1,也可写成i+=5,这样每循环一次i就加5
{
analogWrite(PWMpin, i);//让10号针脚的电平改变为i
delay(10);//延时10毫秒
}
}
编程提示
C语言的for循环语句比BASIC和其余电脑编程语言的for语句更灵活。除了分号之外,其余3个元素都能省略。同时,初始化,条件,增量计算能够是任何包括无关变量的有效C语句,任何C数据类型包括float。这些不寻常的for语句可能会解决一些困难的编程问题。
例如,在增量计数中使用乘法能够获得一个等比数列:
for(int x = 2; x < 100; x = x * 1.5){//定义X为2,当X小于100的时候X从新赋值为它本身的1.5倍
println(x);//打印输出x的值
}
生成:2,3,4,6,9,13,19,28,42,63,94
另外一个例子,使用for循环使LED产生渐亮渐灭的效果:
int PWMpin = 10; //将一个LED与47Ω电阻串联接在10号针脚
void setup()
{
//无需设置
}
void loop()
{
int x = 1; //定义一个整数变量x赋值为1
for (int i = 0; i > -1; i = i + x) //定义i为0当i小于负一的时候,i的值为它本身加上X,也就是加上1,灯就依次变亮了
{
analogWrite(PWMpin, i); //让PWMpin针脚的电平变为i
if (i == 255) x = -1; // 当i等于最大值255的时候,把x改变为负一,这样再循环上去的时候i的值就会依次减一,就由亮变暗了
delay(10); //延时10毫秒,若是还想让灯由暗变亮的话就再写个判断
if(i==0) x=1; //当i减少到0的时候又把x变成1,这样i就又依次加1,灯由暗变亮了
delay(10);
}
}
2.4 switch case
switch / case语句
和if语句相同,switch…case经过程序员设定的在不一样条件下执行的代码控制程序的流程。特别地,switch语句将变量值和case语句中设定的值进行比较。当一个case语句中的设定值与变量值相同时,这条case语句将被执行。
关键字break可用于退出switch语句,一般每条case语句都以break结尾。若是没有break语句,switch语句将会一直执行接下来的语句(一直向下)直到碰见一个break,或者直到switch语句结尾。
语法也是先switch而后跟括号()括号内写上变量值,后面跟大括号,大括号里写上case分支
例子
switch (var) {
case 1: //case 1后面是冒号
//当var等于1时,执行一些语句
break;
case 2
//当var等于2时,执行一些语句
break;
default:
//若是没有任何匹配,执行default
//default可有可不有
}
语法
switch (var) { //定义检查var的值
case label1: //若是var的值是label1的就就执行下面的语句
// 程序语句
break;
case label2: //若是var的值是label2的就就执行下面的语句
//程序语句
break;
default: //若是var的值都不在上面的里面的话就执行下面的语句
//程序语句
}
参数
var: 用于与下面的case中的标签进行比较的变量值
label: 与变量进行比较的值
2.5 while
while循环
描述
while循环会无限的循环,直到括号内的判断语句变为假。必需要有能改变判断语句的东西,要否则while循环将永远不会结束。这在您的代码表现为一个递增的变量,或一个外部条件,如传感器的返回值。
语法
while(表达){
//语句
}
参数
表达:为真或为假的一个计算结果
例子
var = 0; //定义一个变量var赋值为0
while(var < 200){ //当var的值小于200的时候执行下面的语句
var++ //var依次加1,加200次,直到var的值不小于200为止
}
2.6 do...while
do…while循环与while循环运行的方式是相近的,不过它的条件判断是在每一个循环的最后,因此这个语句至少会被运行一次,而后才被结束。
do
{
//语句
}while(测试条件);
例子
do
{
delay(50); //延时50秒
X = readSensors(); //给X赋值
}while(X <100); //当x小于100时,继续运行,当x不小于100的时候就不运行了
2.7 break
break用于退出do,for,while循环,能绕过通常的判断条件。它也可以用于退出switch语句。
例子
for (x = 0; x < 255; x ++)
{
digitalWrite(PWMpin, x);
sens = analogRead(sensorPin);
if (sens > threshold){
x = 0;
break; //这里用break就打断循环了,至关于在此结束了,程序就再也不循环了
}
delay(50);
}
2.8 continue
continue语句跳过当前循环中剩余的迭代部分( do,for 或 while )。它经过检查循环条件表达式,并继续进行任何后续迭代。
例子
for (x = 0; x < 255; x ++)
{
if (x > 40 && x < 120){
continue; // 当x在40与120之间时,跳事后面两句,即迭代。
}
digitalWrite(PWMpin, x);
delay(50);
}
2.9 return
终止一个函数,若有返回值,将今后函数返回给调用函数。
语法
return;
return value; // 两种形式都可
参数
value:任何变量或常量的类型
例子
一个比较传感器输入阈值的函数
int checkSensor(){ //这儿定义了一个整数形函数checkSensor
if (analogRead(0) > 400) { //若是读取0针脚的数据大于400的话
return 1;} //返回1,至关于调用这个函数后获得的值是1
else{
return 0; //返回0,至关于调用这个函数后获得的值是0
}
}
return关键字能够很方便的测试一段代码,而无需“comment out(注释掉)” 大段的可能存在bug的代码。
void loop(){
//写入漂亮的代码来测试这里。
return;
//剩下的功能异常的程序
//return后的代码永远不会被执行
}
2.10 goto
程序将会从程序中已有的标记点开始运行,这个东西,少用
语法
label:
goto label; //从label处开始运行
提示
不要在C语言中使用goto编程,某些C编程做者认为goto语句永远是没必要要的,但用得好,它能够简化某些特定的程序。许多程序员不一样意使用goto的缘由是, 经过毫无节制地使用goto语句,很容易建立一个程序,这种程序拥有不肯定的运行流程,于是没法进行调试。感受就像你明明在1上一下就跳到了8上,并 不是从上而下的过程。
的确在有的实例中goto语句能够派上用场,并简化代码。例如在必定的条件用if语句来跳出高度嵌入的for循环。
例子
for(byte r = 0; r < 255; r++){
for(byte g = 255; g > -1; g--){
for(byte b = 0; b < 255; b++){
if (analogRead(0) > 250){
goto bailout; //这儿有一个goto语句因此程序会跳转到下一个bailout
}
//更多的语句...
}
}
}
bailout: //goto语句跳转到这儿继续执行
3、扩展语法
3.1 ;(分号)
用于表示一句代码的结束。
例子
int a = 13;
提示
在每一行忘记使用分号做为结尾,将致使一个编译错误。错误提示可能会清晰的指向缺乏分号的那行,也可能不会。若是弹出一个使人费解或看似不合逻辑的编译器错误,第一件事就是在错误附近检查是否缺乏分号。
3.2 {}(花括号也称大括号)
大括号(也称为“括号”或“大括号”)是C编程语言中的一个重要组成部分。它们被用来区分几个不一样的结构,下面列出的,有时可能使初学者混乱。
左大括号“{”必须与一个右大括号“}”造成闭合。这是一个经常被称为括号平衡的条件。在Arduino IDE(集成开发环境)中有一个方便的功能来检查大括号是否平衡。只需选择一个括号,甚至单击紧接括号的插入点,就能知道这个括号的“伴侣括号”。
目前此功能稍微有些错误,由于IDE会常常会认为在注释中的括号是不正确的。
对于初学者,以及由BASIC语言转向学习C语言的程序员,常常不清楚如何使用括号。毕竟,大括号还会在”return函数”、“endif条件句”以及“loop函数”中被使用到。
因为大括号被用在不一样的地方,这有一种很好的编程习惯以免错误:输入一个大括号后,同时也输入另外一个大括号以达到平衡。而后在你的括号之间输入回车,而后再插入语句。这样一来,你的括号就不会变得不平衡了。
不平衡的括号常可致使许多错误,好比使人费解的编译器错误,有时很难在一个程序找到这个错误。因为其不一样的用法,括号也是一个程序中很是重要的语法,若是括号发生错误,每每会极大地影响了程序的意义。
大括号中的主要用途
功能 函数
void myfunction(datatype argument){
statements(s)
}
循环
while (boolean expression)
{
statement(s)
}
do
{
statement(s)
}
while (boolean expression);
for (initialisation; termination condition; incrementing expr)
{
statement(s)
}
条件语句
if (boolean expression)
{
statement(s)
}
else if (boolean expression)
{
statement(s)
}
else
{
statement(s)
}
3.3 //(单行注释)
Comments(注释)
注释用于提醒本身或他人程序是如何工做的。它们会被编译器忽略掉,也不会传送给处理器,不会执行,因此它们在Atmega芯片上不占用体积。 注释的惟一做用就是使你本身理解或帮你回忆你的程序是怎么工做的或提醒他人你的程序是如何工做的。编写注释有两种写法:
例子
x = 5; // 这是一条注释斜杠后面本行内的全部东西是注释
/* 这是多行注释-用于注释一段代码
if (gwb == 0){ // 在多行注释内可以使用单行注释
x = 3; /* 但不容许使用新的多行注释-这是无效的
}
// 别忘了注释的结尾符号-它们是成对出现的!
*/
小提示
当测试代码的时候,注释掉一段可能有问题的代码是很是有效的方法。这能使这段代码成为注释而保留在程序中,而编译器能忽略它们。这个方法用于寻找问题代码或当编译器提示出错或错误很隐蔽时颇有效。
3.4 /* */(多行注释)
Comments(注释)
上面已经讲过了跟单行同类型
例子
x = 5; // 这是一条注释斜杠后面本行内的全部东西是注释
/* 这是多行注释-用于注释一段代码
if (gwb == 0){ // 在多行注释内可以使用单行注释
x = 3; /* 但不容许使用新的多行注释-这是无效的
}
// 别忘了注释的结尾符号-它们是成对出现的!
*/
小提示
当测试代码的时候,注释掉一段可能有问题的代码是很是有效的方法。这能使这段代码成为注释而保留在程序中,而编译器能忽略它们。这个方法用于寻找问题代码或当编译器提示出错或错误很隐蔽时颇有效。
3.5 #define
#define 是一个颇有用的C语法,它容许程序员在程序编译以前给常量命名。在Arduino中,定义的常量不会占用芯片上的任何程序内存空间。在编译时编译器会用事先定义的值来取代这些常量。
然而这样作会产生一些反作用,例如,一个已被定义的常量名已经包含在了其余常量名或者变量名中。在这种状况下,文本将被#defined 定义的数字或文本所取代。
一般状况下,优先考虑使用 const 关键字替代 #define 来定义常量。
Arduino 拥有和 C 相同的语法规范。
语法
#define 常量名 常量值 注意,#是必须的。
例子
#define ledPin 3
//在编译时,编译器将使用数值 3 取代任何用到 ledPin 的地方。
提示
在#define 声明后不能有分号。若是存在分号,编译器会抛出语义不明的错误,甚相当闭页面。
#define ledPin 3; //这是一种错误写法
相似的,在#define声明中包含等号也会产生语义不明的编译错误从而致使关闭页面。
#define ledPin = 3 //这是一种错误写法
不能包含等号只能用空格
3.6 #include
#include用于调用程序之外的库。这使得程序可以访问大量标准C库,也能访问用于arduino的库。 AVR C库(Arduino基于AVR标准语法)语法手册请点击这里。 注意#include和#define同样,不能在结尾加分号,若是你加了分号编译器将会报错。
例子
此例包含了一个库,用于将数据存放在flash空间内而不是ram内。这为动态内存节约了空间,大型表格查表更容易实现。
#include <avr/pgmspace.h>
prog_uint16_t myConstants[] PROGMEM = {0, 21140, 702 , 9128, 0, 25764, 8456,
0,0,0,0,0,0,0,0,29810,8968,29762,29762,4500};
4、算数运算符
4.1 =(赋值运算符)
= 赋值运算符(单等号) 注意:这个是赋值的=号并非相比较的==号
赋值运算符(单等号)
将等号右边的数值赋值给等号左边的变量
在C语言中,单等号被称为赋值运算符,它与数学上的等号含义不一样,赋值运算符告诉单片机,将等号的右边的数值或计算表达式的结果,存储在等号左边的变量中。
例子
int sensVal; //声明一个名为sensVal的整型变量
senVal = analogRead(0); //将模拟引脚0的输入电压存储在SensVal变量中
编程技巧
要确保赋值运算符(=符号)左侧的变量可以储存右边的数值。若是没有大到足以容纳右边的值,存储在变量中的值将会发生错误。
好比你要把一个浮点型小数赋值给一个整数就不对
不要混淆赋值运算符[=](单等号)与比较运算符[==](双等号),认为这两个表达式是相等的。
4.2 +(加)
加,减,乘,除
描述
这些运算符返回两个操做数的和,差,乘积,商。这些运算是根据操做数的数据类型来计算的,好比 9和4都是int类型,因此9 / 4 结果是 2.这也就表明若是运算结果比数据类型所能容纳的范围要大的话,就会出现溢出(例如. 1加上一个整数 int类型 32,767 结果变成-32,768)。若是操做数是不一样类型的,结果是”更大”的那种数据类型。若是操做数中的其中一个是 float类型或者double类型, 就变成了浮点数运算。
例子
y = y + 3; //这里的Y得是整数型 int 类型才行,若是y是2输出结果为5
y=y+"你好啊"; //这里的y得是字符串类型 str 才行,若是y是“逗B”,输出结果就是“逗B你好啊”
//加能够用来作字符串相加,减的话必须是主内容包含被减掉的内容才能够。
x = x - 7;
i = j * 6;
r = r / 5;
result = value1 + value2;
result = value1 - value2;
result = value1 * value2;
result = value1 / value2;
value1: 任何常量或者变量,value2: 任何常量或者变量
可是要注意,互相作运算的变量或是常得是同一类型,不是的话先转换成同一类型
编程小提示
整型常量的默认值是int类型,因此一些整型常量(定义中)的计算会致使溢出.(好比: 60 * 1000 会获得一个负数结果.那么if(60*1000 > 0) ,if获得的是一个false值。
在选择变量的数据类型时,必定要保证变量类型的范围要足够大,以致于能容纳下你的运算结果。
要知道你的变量在哪一个点会”翻身”,两个方向上都得注意.如: (0 - 1) 或 (0 - - 32768)
一些数学上的分数处理,要用浮点数,但其缺点是:占用字节长度大,运算速度慢。
使用类型转换符,例如 (int)myFloat 将一个变量强制转换为int类型。
4.3 -(减)
详见4.2 +(加)
4.4 *(乘)
详见4.2 +(加)
4.5 /(除)
详见4.2 +(加)
4.6 %(取模)
描述
一个整数除以另外一个数,其余数称为模。它有助于保持一个变量在一个特定的范围(例如数组的大小)。
语法
结果=被除数%除数
参数
被除数:一个被除的数字
除数:一个数字用于除以其余数
返回
余数(模)
举例
X = 7%5; // X为2,商为1余2
X = 9% 5;// X为4商为1余4
X = 5% 5;// X为0商为1余0
X = 4%5; // X为4除不动就为它自己4了
示例代码
/*经过循环计算1到10的模*/
int values[10];
int i = 0;
void setup () {
}
void loop()
{
values [i] = analogRead(0); //因此读取的值就是10之内的除以10以后的余数
i =(i + 1)%10; //取模运算
}
提示
模运算符对浮点数不起做用。
5、比较运算符
5.1 ==(等于)比较是否等于
if(条件判断语句)和 ==、!=、<、>(比较运算符)
复习一下if语句
if 语句与比较运算符一块儿用于检测某个条件是否达成,如某输入值是否在特定值之上等。if 语句的语法是:
if (someVariable > 50)
{
// 执行某些语句
}
本程序测试 someVariable 变量的值是否大于 50。当大于 50 时,执行一些语句。换句话说,只要 if 后面括号里的结果(称之为测试表达式)为真,则执行大括号中的语句(称之为执行语句块);若为假,则跳过大括号中的语句。 if 语句后的大括号能够省略。若省略大括号,则只有一条语句(以分号结尾)成为执行语句。
if (x > 120) digitalWrite(LEDpin, HIGH);
if (x > 120)
digitalWrite(LEDpin, HIGH);
if (x > 120){ digitalWrite(LEDpin, HIGH); }
if (x > 120){
digitalWrite(LEDpin1, HIGH);
digitalWrite(LEDpin2, HIGH);
} // 以上全部书写方式都正确
在小括号里求值的表达式,须要如下操做符:
比较运算操做符:
x == y(x 等于 y)
x != y(x 不等于 y)
x < y(x 小于 y)
x > y(x 大于 y)
x <= y(x 小于等于 y)
x >= y(x 大于等于 y)
警告
注意使用赋值运算符的状况(如 if (x = 10))。一个“=”表示的是赋值运算符,做用是将 x 的值设为 10(将值 10 放入 x 变量的内存中)。两个“=”表示的是比较运算符(如 if (x == 10)),用于测试 x 和 10 是否相等。后面这个语句只有 x 是 10 时才为真,而前面赋值的那个语句则永远为真。
这是由于 C 语言按如下规则进行运算 if (x=10):10 赋值给 x(只要非 0 的数赋值的语句,其赋值表达式的值永远为真),所以 x 如今值为 10。此时 if 的测试表达式值为 10,该值永远为真,由于非 0 值永远为真。因此,if (x = 10) 将永远为真,这就不是咱们运行 if 所期待的结果。另外,x 被赋值为 10,这也不是咱们所期待的结果。
if 的另一种分支条件控制结构是 if...else 形式。
5.2 !=(不等于)
详见5.1 ==(等于)
5.3 <(小于)
详见5.1 ==(等于)
5.4 >(大于)
详见5.1 ==(等于)
5.5 <=(小于等于)
详见5.1 ==(等于)
5.6 >=(大于等于)
详见5.1 ==(等于)
6、布尔运算符
6.1 &&(与)
布尔运算符
这些运算符能够用于if条件句中。不会打&不要紧英文输入状态按SHIFT+7
&&(逻辑与)就是同时的意思,小明买了一支笔&&买了一本书
只有两个运算对象为“真”,才为“真”,如:
if (digitalRead(2) == HIGH && digitalRead(3) == HIGH) { // 读取2号针脚和3号针脚的电平
}
若是当两个输入都为高电平,则为“真”。
||(逻辑或)
只要一个运算对象为“真”,就为“真”,如:
if (x > 0 || y > 0) {
//其中x大于0或是y大于0均可执行程序
}
若是x或y是大于0,则为“真”。
!(逻辑非)
若是运算对象为“假”,则为“真”,例如
if (!x) {
// ...
}
若是x为“假”,则为真(即若是x等于0)。
警告
千万不要误觉得,符号为&(单符号)的位运算符”与”就是布尔运算符的“与”符号为&&(双符号)。他们是彻底不一样的符号。
一样,不要混淆布尔运算符||(双竖)与位运算符“或”符号为| (单竖)。
位运算符〜(波浪号)看起来与布尔运算符not有很大的差异!(正如程序员说:“惊叹号”或“bang”),但你仍是要肯定哪个运算符是你想要的。
举例
if (a >= 10 && a <= 20){} // 若是a的值在10至20之间,则为“真”
6.2 ||(或)
详见6.1 &&(与)
6.3 !(非)
详见6.1 &&(与)
7、指针运算符
7.1 * 取消引用运算符
指针运算符
& (取地址) 和 * (取地址所指的值)
指针对C语言初学者来讲是一个比较复杂的内容,可是编写大部分arduino代码时能够不用涉及到指针。然而,操做某些数据结构时,使用指针可以简化代码,可是指针的操做知识很难在工具书中找到,能够参考C语言相关工具书。
7.2 & 引用运算符
详见7.1 *取消引用运算符
8、位运算符
8.1 & (按位与)
按位与(&)
按位操做符对变量进行位级别的计算。它们能解决不少常见的编程问题。下面的材料大多来自这个很是棒的按位运算指导。
说明和语法
下面是全部的运算符的说明和语法。进一步的详细资料,可参考教程。
按位与(&)
位操做符与在C + +中是一个&符,用在两个整型变量之间。按位与运算符对两侧的变量的每一位都进行运算,规则是:若是两个运算元都是1,则结果为1,不然输出0.另外一种表达方式:
0 0 1 1 运算元1
0 1 0 1 运算元2
----------
0 0 0 1(运算元1&运算元2)-返回结果
在Arduino中,int类型为16位,因此在两个int表达式之间使用&会进行16个并行按位与计算。代码片断就像这样:
int a = 92; //二进制: 0000000001011100
int b = 101; // 二进制: 0000000001100101
int c = a & b; // 结果: 0000000001000100, 或10进制的68
a和b的16位每位都进行按位与计算,计算结果存在c中,二进制结果是01000100,十进制结果是68.
按位与最多见的做用是从整型变量中选取特定的位,也就是屏蔽。见下方的例子。
按位或(|)
按位或操做符在C++中是|。和&操做符相似,|操做符对两个变量的为一位都进行运算,只是运算规则不一样。按位或规则:只要两个位有一个为1则结果为1,不然为0。换句话说:
0 0 1 1 运算元1
0 1 0 1 运算元2
----------
0 1 1 1(运算元1 | 运算元2) - 返回的结果
这里是一个按位或运算在C + +代码片断:
int a = 92; // 二进制: 0000000001011100
int b = 101; //二进制: 0000000001100101
int c = a | b; // 结果: 0000000001111101, 或十进制的125
示例程序
按位与和按位或运算经常使用于端口的读取-修改-写入。在微控制器中,一个端口是一个8位数字,它用于表示引脚状态。对端口进行写入能同时操做全部引脚。
PORTD是一个内置的常数,是指0,1,2,3,4,5,6,7数字引脚的输出状态。若是某一位为1,着对应管脚为HIGH。(此引脚须要先用pinMode()命令设置为输出)所以若是咱们这样写,PORTD=B00110001;则引脚二、三、7状态为HIGH。这里有个小陷阱,咱们可能同时更改了引脚0、1的状态,引脚0、1是Arduino串行通讯端口,所以咱们可能会干扰通讯。
咱们的算法的程序是:
读取PORT并用按位与清除咱们想要控制的引脚
用按位或对PORTD和新的值进行运算
int i; // 计数器
int j;
void setup()
DDRD = DDRD | B11111100; //设置引脚2~7的方向,0、1脚不变(xx|00==xx)
//效果和pinMode(pin,OUTPUT)设置2~7脚为输出同样
serial.begin(9600);
}
void loop () {
for (i=0; i<64; i++){
PORTD = PORTD & B00000011; // 清除2~7位,0、1保持不变(xx & 11 == xx)
j = (i << 2); //将变量左移为·2~7脚,避免0、1脚
PORTD = PORTD | j; //将新状态和原端口状态结合以控制LED脚
Serial.println(PORTD, BIN); // 输出掩盖以便调试
delay(100);
}
}
按位异或(^)
C++中有一个不常见的操做符叫按位异或,也叫作XOR(一般读做”eks-or“)。按位异或操做符用‘^'表示。此操做符和按位或(|)很类似,区别是若是两个位都为1则结果为0:
0 0 1 1 运算元1
0 1 0 1 运算元2
----------
0 1 1 0(运算元1 ^运算元2) - 返回的结果
按位异或的另外一种解释是若是两个位值相同则结果为0,不然为1。
下面是一个简单的代码示例:
int x = 12; // 二进制: 1100
int y = 10; // 二进制: 1010
int z = x ^ y; // 二进制: 0110, 或十进制 6
// Blink_Pin_5
//演示“异或”
void setup(){
DDRD = DDRD | B00100000; / /设置数字脚5设置为输出
serial.begin(9600);
}
void loop () {
PORTD = PORTD ^ B00100000; // 反转第5位(数字脚5),其余保持不变
delay(100);
}
8.2 | (按位或)
详见8.1 &(按位与)
8.3 ^ (按位异或)
详见8.1 &(按位与)
8.4 ~ (按位非)
按位取反 (~)
按位取反在C+ +语言中是波浪号~。与&(按位与)和|(按位或)不一样,按位取反使用在一个操做数的右侧。按位取反将操做数改变为它的“反面”:0变为1,1变成0。例如:
0 1 operand1
----------
1 0 ~ operand1
int a = 103; // 二进制: 0000000001100111
int b = ~a; // 二进制: 1111111110011000 = -104
你可能会惊讶地看到结果为像-104这样的数字。这是由于整数型变量的最高位,即所谓的符号位。若是最高位是1,这个数字将变为负数。这个正数和负数的编码被称为补。想了解更多信息,请参考Wikipedia文章two's complement.
顺便说一句,有趣的是,要注意对于任何整数型操做数X,〜X和-X-1是相同的。
有时,对带有符号的整数型操做数进行位操做能够形成一些没必要要的意外。
8.5 <<(左移位运算符)
bitshift left (<<), bitshift right (>>)
描述
出自Playground的 The Bitmath Tutorial 在C++语言中有两个移位运算符:左移位运算符(«)和右移运算符(»)。这些操做符可以使左运算元中的某些位移动右运算元中指定的位数。
语法
variable « number_of_bits variable » number_of_bits
参数
variable - (byte, int, long) number_of_bits integer ⇐ 32
例子
int a = 5; // 二进制数: 0000000000000101
int b = a << 3; // 二进制数: 0000000000101000, 或十进制数:40
int c = b >> 3; // 二进制数: 0000000000000101, 或者说回到开始时的5
//当你将x左移y位时(x«y),x中最左边的y位会逐个逐个的丢失:
int a = 5; // 二进制: 0000000000000101
int b = a << 14; // 二进制: 0100000000000000 - 101中最左边的1被丢弃
若是你肯定位移不会引发数据溢出,你能够简单的把左移运算当作对左运算元进行2的右运算元次方的操做。例如,要产生2的次方,可以使用下面的方式:
1 << 0 == 1
1 << 1 == 2
1 << 2 == 4
1 << 3 == 8
...
1 << 8 == 256
1 << 9 == 512
10 << 1 == 1024
...
当你将x右移y位(x»y),若是x最高位是1,位移结果将取决于x的数据类型。若是x是int类型,最高位为符号位,肯定是否x是负数或不是,正如咱们上面的讨论。若是x类型为int,则最高位是符号位,正如咱们之前讨论过,符号位表示x是正仍是负。在这种状况下,因为深奥的历史缘由,符号位被复制到较低位:
X = -16; //二进制:1111111111110000
Y = X >> 3 //二进制:1111111111111110
这种结果,被称为符号扩展,每每不是你想要的行为。你可能但愿左边被移入的数是0。右移操做对无符号整型来讲会有不一样结果,你能够经过数据强制转换改变从左边移入的数据:
X = -16; //二进制:1111111111110000
int y = (unsigned int)x >> 3; // 二进制: 0001111111111110
若是你能当心的避免符号扩展问题,你能够将右移操做当作对数据除2运算。例如:
INT = 1000;
Y = X >> 3; 8 1000 //1000整除8,使y=125
8.6 >> (右移位运算符)
详见 8.5 <<(左移位运算符)
9、复合运算符
9.1 ++ (递增)
++ (递增) / -- (递减)
描述
递增或递减一个变量
语法
x++; //x自增1返回x的旧值
++x; // x自增1返回x的新值
x--; // x自减1返回x的旧值
--x; //x自减1返回x的新值
参数
x: int或long(多是unsigned)
返回
变量进行自增/自减操做后的原值或新值。
例子
x = 2;
y = ++x; // 如今x=3,y=3
y = x--; // 如今x=2,y仍是3
9.2 -- (递减)
详见 9.1 ++ (递增)
9.3 += (复合加)
+= , -= , *= , /=
描述
执行常量或变量与另外一个变量的数学运算。+= 等运算符是如下扩展语法的速记。
语法
X += Y; //至关于表达式X = X + Y;
X -= Y; //至关于表达式X = X - Y;
X *= Y; //至关于表达式X = X * Y;
X /= Y; //至关于表达式X = X / Y;
参数
X:任何变量类型
Y:任何变量类型或常数
例子
x = 2;
x += 4; // x 如今等于6
x -= 3; // x 如今等于3
x *= 10; // x 如今等于30
x /= 2; // x 如今等于15
9.4 -= (复合减)
详见 9.3 += (复合加)
9.5 *= (复合乘)
详见 9.3 += (复合加)
9.6 /= (复合除)
详见 9.3 += (复合加)
9.6 &= (复合运算按位与)
描述
复合运算按位与运算符(&=)常常被用来将一个变量和常量进行运算使变量某些位变为0。这一般被称为“清算”或“复位”位编程指南。
语法
x &= y; // 等价于 x = x & y;
参数
x:char,int或long类型变量
Y:char,int或long类型常量
例如
首先,回顾一下按位与(&)运算符
0 0 1 1 运算元1
0 1 0 1 运算元2
----------
0 0 0 1(运算元1&运算元2) - 返回的结果
任何位与0进行按位与操做后被清零,若是myBite是变量
myByte&B00000000 = 0;
所以,任何位与1进行“按位与运算”后保持不变
myByte B11111111 = myByte;
注意:由于咱们用位操做符来操做位,因此使用二进制的变量会很方便。若是这些数值是其余值将会获得一样结果,只是不容易理解。一样,B00000000是为了标示清楚,0在任何进制中都是0(恩。。有些哲学的味道) 所以 - 清除(置零)变量的任意位0和1,而保持其他的位不变,可与常量B11111100进行复合运算按位与(&=)
1 0 1 0 1 0 1 0变量
1 1 1 1 1 1 0 0 mask
----------------------
1 0 1 0 1 0 0 0
变量不变 位清零
将变量替换为x可获得一样结果
X X X X X X X X变量
1 1 1 1 1 1 0 0 mask
----------------------
X X X X X X 0 0
变量不变 位清零
同理
myByte = 10101010;
myByte&= B1111100 == B10101000;
9.8 |= (复合运算按位或)
描述
复合按位或操做符(| =)常常用于变量和常量“设置”(设置为1),尤为是变量中的某一位。
语法
x |= y; //等价于 x = x | y;
参数
x: char,int或long类型
y:整数,int或long类型
例如
首先,回顾一下OR(|)运算符
0 0 1 1 运算元1
0 1 0 1 运算元2
----------
0 1 1 1(运算元1 | 运算元2) - 返回的结果
若是变量myByte中某一位与0通过按位或运算后不变。
myByte | B00000000 = myByte;
与1通过或运算的位将变为1.
myByte | B11111111 B11111111;
所以 - 设置变量的某些位为0和1,而变量的其余位不变,可与常量B00000011进行按位与运算(| =)
1 0 1 0 1 0 1 0变量
0 0 0 0 0 0 1 1
----------------------
1 0 1 0 1 0 1 1
变量保持不变 位设置
接下来的操做相同,只是将变量用x代替
X X X X X X X X变量
0 0 0 0 0 0 1 1 mask
----------------------
X X X X X X 1 1
变量保持不变 位设置
同上:
myByte = B10101010;
myByte | = B00000011 == B10101011;
变量部分
10、常量
10.1 HIGH|LOW(引脚电压定义)
引脚电压定义,HIGH和LOW
当读取(read)或写入(write)数字引脚时只有两个可能的值: HIGH 和 LOW 。
HIGH
HIGH(参考引脚)的含义取决于引脚(pin)的设置,引脚定义为INPUT或OUTPUT时含义有所不一样。当一个引脚经过pinMode被设置为INPUT,并经过digitalRead读取(read)时。若是当前引脚的电压大于等于3V,微控制器将会返回为HIGH。 引脚也能够经过pinMode被设置为INPUT,并经过digitalWrite设置为HIGH。输入引脚的值将被一个内在的20K上拉电阻 控制 在HIGH上,除非一个外部电路将其拉低到LOW。 当一个引脚经过pinMode被设置为OUTPUT,并digitalWrite设置为HIGH时,引脚的电压应在5V。在这种状态下,它能够 输出电流 。例如,点亮一个经过一串电阻接地或设置为LOW的OUTPUT属性引脚的LED。
LOW
LOW的含义一样取决于引脚设置,引脚定义为INPUT或OUTPUT时含义有所不一样。当一个引脚经过pinMode配置为INPUT,经过digitalRead设置为读取(read)时,若是当前引脚的电压小于等于2V,微控制器将返回为LOW。 当一个引脚经过pinMode配置为OUTPUT,并经过digitalWrite设置为LOW时,引脚为0V。在这种状态下,它能够 倒灌 电流。例如,点亮一个经过串联电阻链接到+5V,或到另外一个引脚配置为OUTPUT、HIGH的的LED。
10.2 INPUT|OUTPUT(数字引脚(Digital pins)定义)
数字引脚(Digital pins)定义,INPUT和OUTPUT
数字引脚看成 INPUT 或 OUTPUT均可以 。用pinMode()方法使一个数字引脚从INPUT到OUTPUT变化。
引脚(Pins)配置为输入(Inputs)
Arduino(Atmega)引脚经过pinMode()配置为 输入(INPUT) 便是将其配置在一个高阻抗的状态。配置为INPUT的引脚能够理解为引脚取样时对电路有极小的需求,即等效于在引脚前串联一个100兆欧姆(Megohms)的电阻。这使得它们很是利于读取传感器,而不是为LED供电。
引脚(Pins)配置为输出(Outputs)
引脚经过pinMode()配置为 输出(OUTPUT) 便是将其配置在一个低阻抗的状态。
这意味着它们能够为电路提供充足的电流。Atmega引脚能够向其余设备/电路提供(提供正电流positive current)或倒灌(提供负电流negative current)达40毫安(mA)的电流。这使得它们利于给LED供电,而不是读取传感器。输出(OUTPUT)引脚被短路的接地或5V电路上会受到损坏甚至烧毁。Atmega引脚在为继电器或电机供电时,因为电流不足,将须要一些外接电路来实现供电。
10.3 true | false(逻辑层定义)
逻辑层定义,true与false(布尔Boolean常量)
在Arduino内有两个常量用来表示真和假:true和 false。
false
在这两个常量中false更容易被定义。false被定义为0(零)。
true
true一般被定义为1,这是正确的,但true具备更普遍的定义。在布尔含义(Boolean sense)里任何 非零 整数 为true。因此在布尔含义内-1,2和-200都定义为ture。 须要注意的是true和false常量,不一样于HIGH,LOW,INPUT和OUTPUT,须要所有小写。
10.4 integer constants(整数常量)
整数常量是直接在程序中使用的数字,如123。默认状况下,这些数字被视为int,但你能够经过U和L修饰符进行更多的限制(见下文)。 一般状况下,整数常量默认为十进制,但能够加上特殊前缀表示为其余进制。
进制 |
例子 |
格式 |
备注 |
10(十进制) |
123 |
无 |
|
2(二进制) |
B1111011 |
前缀'B' |
只适用于8位的值(0到255)字符0-1有效 |
8(八进制) |
0173 |
前缀”0” |
字符0-7有效 |
16(十六进制) |
0x7B |
前缀”0x” |
字符0-9,A-F,A-F有效 |
小数是十进制数。这是数学常识。若是一个数没有特定的前缀,则默认为十进制。
二进制以2为基底,只有数字0和1是有效的。
示例
101 //和十进制5等价 (1*2^2 + 0*2^1 + 1*2^0)
二进制格式只能是8位的,即只能表示0-255之间的数。若是输入二进制数更方便的话,你能够用如下的方式:
myInt = (B11001100 * 256) + B10101010; // B11001100 做为高位。
八进制是以8为基底,只有0-7是有效的字符。前缀“0”(数字0)表示该值为八进制。
0101 // 等同于十进制数65 ((1 * 8^2) + (0 * 8^1) + 1)
警告:八进制数0前缀极可能无心产生很难发现的错误,由于你可能不当心在常量前加了个“0”,结果就悲剧了。
十六进制以16为基底,有效的字符为0-9和A-F。十六进制数用前缀“0x”(数字0,字母爱克斯)表示。请注意,A-F不区分大小写,就是说你也能够用a-f。
示例
0x101 // 等同于十进制257 ((1 * 16^2) + (0 * 16^1) + 1)
U & L 格式
默认状况下,整型常量被视做int型。要将整型常量转换为其余类型时,请遵循如下规则:
'u' or 'U' 指定一个常量为无符号型。(只能表示正数和0) 例如: 33u
'l' or 'L' 指定一个常量为长整型。(表示数的范围更广) 例如: 100000L
'ul' or 'UL' 这个你懂的,就是上面两种类型,称做无符号长整型。 例如:32767ul
10.5 floating point constants(浮点常量)
和整型常量相似,浮点常量能够使得代码更具可读性。浮点常量在编译时被转换为其表达式所取的值。
例子
n = .005; 浮点数能够用科学记数法表示。'E'和'e'均可以做为有效的指数标志。
浮点数 |
被转换为 |
被转换为 |
10.0 |
10 |
|
2.34E5 |
2.34 * 10^5 |
234000 |
67E-12 |
67.0 * 10^-12 |
0.000000000067 |
11、数据类型
11.1 void
void只用在函数声明中。它表示该函数将不会被返回任何数据到它被调用的函数中。
例子
//功能在“setup”和“loop”被执行
//但没有数据被返回到高一级的程序中
void setup()
{
// ...
}
void loop()
{
// ...
}
11.2 boolean (布尔)
一个布尔变量拥有两个值,true或false。(每一个布尔变量占用一个字节的内存。)
例子
int LEDpin = 5; // LED与引脚5相连
int switchPin = 13; // 开关的一个引脚链接引脚13,另外一个引脚接地。
boolean running = false;
void setup()
{
pinMode(LEDpin, OUTPUT);
pinMode(switchPin, INPUT);
digitalWrite(switchPin, HIGH); // 打开上拉电阻
}
void loop()
{
if (digitalRead(switchPin) == LOW)
{ // 按下开关 - 使引脚拉向高电势
delay(100); // 经过延迟,以滤去开关抖动产生的杂波
running = !running; // 触发running变量
digitalWrite(LEDpin, running) //点亮LED
}
}
11.3 char(字符或字符串)
一个数据类型,占用1个字节的内存存储一个字符值。字符都写在单引号,如'A';(多个字符(字符串)使用双引号,如“ABC”)。
字符以编号的形式存储。你能够在ASCII表中看到对应的编码。这意味着字符的ASCII值能够用来做数学计算。(例如'A'+ 1,由于大写A的ASCII值是65,因此结果为66)。如何将字符转换成数字参考serial.println命令。
char数据类型是有符号的类型,这意味着它的编码为-128到127。对于一个无符号一个字节(8位)的数据类型,使用byte数据类型。
例如
char myChar = 'A';
char myChar = 65; // both are equivalent
11.4 unsigned char(无符号数据类型)
一个无符号数据类型占用1个字节的内存。与byte的数据类型相同。
无符号的char数据类型能编码0到255的数字。
为了保持Arduino的编程风格的一致性,byte数据类型是首选。
例子
unsigned char myChar = 240;
11.5 byte(无符号数)
一个字节存储8位无符号数,从0到255。
例子
byte b = B10010; // "B" 是二进制格式(B10010等于十进制18)
11.6 int(整型)
整数是基本数据类型,占用2字节。整数的范围为-32,768到32,767( -2^15 ~(2^15)-1)。
整数类型使用2的补码方式存储负数。最高位一般为符号位,表示数的正负。其他位被“取反加1”(此处请参考补码相关资料,再也不赘述)。
Arduino为您处理负数计算问题,因此数学计算对您是透明的(术语:实际存在,但不可操做。至关于“黑盒”)。可是,当处理右移位运算符(»)时,可能有未预期的编译过程。
示例
int ledPin = 13;
语法
int var = val;
var - 变量名
val - 赋给变量的值
提示
当变量数值过大而超过整数类型所能表示的范围时(-32,768到32,767),变量值会“回滚”(详情见示例)。
int x
x = -32,768;
x = x - 1; // x 如今是 32,767。
x = 32,767;
x = x + 1; // x 如今是 -32,768。
11.7 unsigned int(无符号整型)
描述
无符号整型变量扩充了变量容量以存储更大的数据,它能存储32位(4字节)数据。与标准长整型不一样无符号长整型没法存储负数,其范围从0到4,294,967,295(2 ^ 32 - 1)。
例子
unsigned long time;
void setup()
{
Serial.begin(9600);
}
void loop()
{
Serial.print("Time: ");
time = millis();
//程序开始后一直打印时间
Serial.println(time);
//等待一秒钟,以避免发送大量的数据
delay(1000);
}
语法
unsigned long var = val;
var - 你所定义的变量名
val - 给变量所赋的值
11.8 word
描述
一个存储一个16字节无符号数的字符,取值范围从0到65535,与unsigned int相同。
例子
word w = 10000;
11.9 long(长整数型)
描述
长整数型变量是扩展的数字存储变量,它能够存储32位(4字节)大小的变量,从-2,147,483,648到2,147,483,647。
例子
long speedOfLight = 186000L; //参见整数常量‘L’的说明
语法
long var = val;
var - 长整型变量名
var - 赋给变量的值
11.10 unsigned long(无符号长整数型)
描述
无符号长整型变量扩充了变量容量以存储更大的数据,它能存储32位(4字节)数据。与标准长整型不一样无符号长整型没法存储负数,其范围从0到4,294,967,295(2 ^ 32 - 1)。
例子
unsigned long time;
void setup()
{
Serial.begin(9600);
}
void loop()
{
Serial.print("Time: ");
time = millis();
//程序开始后一直打印时间
Serial.println(time);
//等待一秒钟,以避免发送大量的数据
delay(1000);
}
语法
unsigned long var = val;
var - 你所定义的变量名
val - 给变量所赋的值
11.11 float(浮点型数)
描述
float,浮点型数据,就是有一个小数点的数字。浮点数常常被用来近似的模拟连续值,由于他们比整数更大的精确度。浮点数的取值范围在3.4028235 E+38 ~ -3.4028235E +38。它被存储为32位(4字节)的信息。
float只有6-7位有效数字。这指的是总位数,而不是小数点右边的数字。与其余平台不一样的是,在那里你能够使用double型获得更精确的结果(如15位),在Arduino上,double型与float型的大小相同。
浮点数字在有些状况下是不许确的,在数据大小比较时,可能会产生奇怪的结果。例如 6.0 / 3.0 可能不等于 2.0。你应该使两个数字之间的差额的绝对值小于一些小的数字,这样就能够近似的获得这两个数字相等这样的结果。
浮点运算速度远远慢于执行整数运算,例如,若是这个循环有一个关键的计时功能,并须要以最快的速度运行,就应该避免浮点运算。程序员常用较长的程式把浮点运算转换成整数运算来提升速度。
举例
float myfloat;
float sensorCalbrate = 1.117;
语法
float var = val;
var——您的float型变量名称
val——分配给该变量的值
示例代码
int x;
int y;
float z;
x = 1;
y = x / 2; // Y为0,由于整数不能容纳分数
z = (float)x / 2.0; // Z为0.5(你必须使用2.0作除数,而不是2)
11.12 double(双精度浮点数)
描述
双精度浮点数。占用4个字节。
目前的arduino上的double实现和float相同,精度并未提升。
提示
若是你从其余地方获得的代码中包含了double类变量,最好检查一遍代码以确认其中的变量的精确度可否在arduino上达到。
11.13 string(char array/字符串)
string(字符串)
描述
文本字符串能够有两种表现形式。你能够使用字符串数据类型(这是0019版本的核心部分),或者你能够作一个字符串,由char类型的数组和空终止字符('\0')构成。(求助,待润色-Leo)本节描述了后一种方法。而字符串对象(String object)将让你拥有更多的功能,同时也消耗更多的内存资源,关于它的详细信息,请参阅页面(String object)[超连接]
举例
如下全部字符串都是有效的声明。
char Str1[15];
char Str2[8] = {'a', 'r', 'd', 'u', 'i', 'n', 'o'};
char Str3[8] = {'a', 'r', 'd', 'u', 'i', 'n', 'o', '\0'};
char Str4[ ] = "arduino";
char Str5[8] = "arduino";
char Str6[15] = "arduino";
声明字符串的解释
在Str1中 声明一个没有初始化的字符数组
在Str2中 声明一个字符数组(包括一个附加字符),编译器会自动添加所需的空字符
在Str3中 明确加入空字符
在Str4中 用引号分隔初始化的字符串常数,编译器将调整数组的大小,以适应字符串常量和终止空字符
在Str5中 初始化一个包括明确的尺寸和字符串常量的数组
在Str6中 初始化数组,预留额外的空间用于一个较大的字符串
空终止字符
通常来讲,字符串的结尾有一个空终止字符(ASCII代码0)。以此让功能函数(例如Serial.pring())知道一个字符串的结束。不然,他们将从内存继续读取后续字节,而这些并不属于所需字符串的一部分。
这意味着,你的字符串比你想要的文字包含更多的个字符空间。这就是为何Str2和Str5须要八个字符,即便“Arduino”只有七个字符 - 最后一个位置会自动填充空字符。str4将自动调整为八个字符,包括一个额外的空。在Str3的,咱们本身已经明确地包含了空字符(写入'\ 0')。
须要注意的是,字符串可能没有一个最后的空字符(例如在Str2中您已定义字符长度为7,而不是8)。这会破坏大部分使用字符串的功能,因此不要故意而为之。若是你注意到一些奇怪的现象(在字符串中操做字符),基本就是这个缘由致使的了。
单引号?仍是双引号?
定义字符串时使用双引号(例如“ABC”),而定义一个单独的字符时使用单引号(例如'A')
包装长字符串
你能够像这样打包长字符串: char myString[] = “This is the first line” ” this is the second line” ” etcetera”;
字符串数组
当你的应用包含大量的文字,如带有液晶显示屏的一个项目,创建一个字符串数组是很是便利的。由于字符串自己就是数组,它其实是一个两维数组的典型。
在下面的代码,”char*”在字符数据类型char后跟了一个星号'*'表示这是一个“指针”数组。全部的数组名其实是指针,因此这须要一个数组的数组。指针对于C语言初学者而言是很是深奥的部分之一,但咱们没有必要了解详细指针,就能够有效地应用它。
样例
char* myStrings[]={
"This is string 1", "This is string 2", "This is string 3",
"This is string 4", "This is string 5","This is string 6"};
void setup(){
Serial.begin(9600);
}
void loop(){
for (int i = 0; i < 6; i++){
Serial.println(myStrings[i]);
delay(500);
}
}
11.14 String object(String类)
描述
String类,是0019版的核心的一部分,容许你实现比运用字符数组更复杂的文字操做。你能够链接字符串,增长字符串,寻找和替换子字符串以及其余操做。它比使用一个简单的字符数组须要更多的内存,但它更方便。
仅供参考,字符串数组都用小写的string表示而String类的实例一般用大写的String表示。注意,在“双引号”内指定的字符常量一般被做为字符数组,并不是String类实例。
函数
String
charAt()
compareTo()
concat()
endsWith()
equals()
equalsIgnoreCase()
GetBytes()
indexOf()
lastIndexOf
length
replace()
setCharAt()
startsWith()
substring()
toCharArray()
toLowerCase()
toUpperCase()
trim()
操做符
[](元素访问)
+(串连)
==(比较)
举例
StringConstructors
StringAdditionOperator
StringIndexOf
StringAppendOperator
StringLengthTrim
StringCaseChanges
StringReplace
StringCharacters
StringStartsWithEndsWith
StringComparisonOperators
StringSubstring
11.15 array (数组)
数组是一种可访问的变量的集合。Arduino的数组是基于C语言的,所以这会变得很复杂,但使用简单的数组是比较简单的。
建立(声明)一个数组
下面的方法均可以用来建立(声明)数组。
myInts [6];
myPins [] = {2,4,8,3,6};
mySensVals [6] = {2,4,-8,3,2};
char message[6] = "hello";
你声明一个未初始化数组,例如myPins。
在myPins中,咱们声明了一个没有明确大小的数组。编译器将会计算元素的大小,并建立一个适当大小的数组。
固然,你也能够初始化数组的大小,例如在mySensVals中。请注意,当声明一个char类型的数组时,你初始化的大小必须大于元素的个数,以容纳所需的空字符。
访问数组
数组是从零开始索引的,也就说,上面所提到的数组初始化,数组第一个元素是为索引0,所以:
mySensVals [0] == 2,mySensVals [1] == 4,
依此类推 。
这也意味着,在包含十个元素的数组中,索引九是最后一个元素。所以,
int myArray[10] = {9,3,2,4,3,2,7,8,9,11};
// myArray[9]的数值为11
// myArray[10],该索引是无效的,它将会是任意的随机信息(内存地址)
出于这个缘由,你在访问数组应该当心。若访问的数据超出数组的末尾(即索引数大于你声明的数组的大小- 1),则将从其余内存中读取数据。从这些地方读取的数据,除了产生无效的数据外,没有任何做用。向随机存储器中写入数据绝对是一个坏主意,一般会致使不愉快的结果,如致使系统崩溃或程序故障。要排查这样的错误是也是一件难事。 不一样于Basic或JAVA,C语言编译器不会检查你访问的数组是否大于你声明的数组。
指定一个数组的值
mySensVals [0] = 10;
从数组中访问一个值:
X = mySensVals [4];
数组和循环
数组每每在for循环中进行操做,循环计数器可用于访问每一个数组元素。例如,将数组中的元素经过串口打印,你能够这样作:
int i;
for (i = 0; i < 5; i = i + 1) {
Serial.println(myPins[i]);
}
例子
若是你须要一个演示数组的完整程序,请参考Knight Rider exampel。
12、数据类型转换
12.1 char()
描述
将一个变量的类型变为char。
语法
char(x)
参数
x:任何类型的值
返回
char
12.2 byte()
描述
将一个值转换为字节型数值。
语法
byte(x)
参数
X:任何类型的值
返回
字节
12.3 int()
描述
将一个值转换为int类型。
语法
int(x)
参数
x:一个任何类型的值
返回值
int类型的值
12.4 word()
描述
把一个值转换为word数据类型的值,或由两个字节建立一个字符。
语法
word(x)
word(h, l)
参数
X:任何类型的值
H:高阶(最左边)字节
L:低序(最右边)字节
返回值
字符
12.5 long()
描述
将一个值转换为长整型数据类型。
语法
long(x)
参数
x:任意类型的数值
返回值
长整型数
12.6 float()
描述
将一个值转换为float型数值。
语法
float(x)
参数
X:任何类型的值
返回值
float型数
注释
见float中关于Arduino浮点数的精度和限制的详细信息。
十3、变量做用域 & 修饰符
13.1 variable scope(变量的做用域)
变量的做用域
在Arduino使用的C编程语言的变量,有一个名为 做用域(scope) 的属性 。这一点与相似BASIC的语言造成了对比,在BASIC语言中全部变量都是 全局(global) 变量。
在一个程序内的全局变量是能够被全部函数所调用的。局部变量只在声明它们的函数内可见。在Arduino的环境中,任何在函数(例如,setup(),loop()等)外声明的变量,都是全局变量。
当程序变得更大更复杂时,局部变量是一个有效肯定每一个函数只能访问其本身变量的途径。这能够防止,当一个函数无心中修改另外一个函数使用的变量的程序错误。
有时在一个for循环内声明并初始化一个变量也是很方便的选择。这将建立一个只能从for循环的括号内访问的变量。
例子
int gPWMval; // 任何函数均可以调用此变量
void setup()
{
// ...
}
void loop()
{
int i; // "i" 只在 "loop" 函数内可用
float f; // "f" 只在 "loop" 函数内可用
// ...
for (int j = 0; j <100; j++){
//变量j只能在循环括号内访问
}
}
13.2 static(静态变量)
static关键字用于建立只对某一函数可见的变量。然而,和局部变量不一样的是,局部变量在每次调用函数时都会被建立和销毁,静态变量在函数调用后仍然保持着原来的数据。
静态变量只会在函数第一次调用的时候被建立和初始化。
例子
/* RandomWalk
* Paul Badger 2007
* RandomWalk函数在两个终点间随机的上下移动
* 在一个循环中最大的移动由参数“stepsize”决定
*一个静态变量向上和向下移动一个随机量
*这种技术也被叫作“粉红噪声”或“醉步”
*/
#define randomWalkLowRange -20
#define randomWalkHighRange 20
int stepsize;
int thisTime;
int total;
void setup()
{
Serial.begin(9600);
}
void loop()
{ // 测试randomWalk 函数
stepsize = 5;
thisTime = randomWalk(stepsize);
serial.println(thisTime);
delay(10);
}
int randomWalk(int moveSize){
static int place; // 在randomwalk中存储变量
// 声明为静态所以它在函数调用之间能保持数据,但其余函数没法改变它的值
place = place + (random(-moveSize, moveSize + 1));
if (place < randomWalkLowRange){ //检查上下限
place = place + (randomWalkLowRange - place); // 将数字变为正方向
}
else if(place > randomWalkHighRange){
place = place - (place - randomWalkHighRange); // 将数字变为负方向
}
return place;
}
13.3 volatile
volatile这个关键字是变量修饰符,经常使用在变量类型的前面,以告诉编译器和接下来的程序怎么对待这个变量。
声明一个volatile变量是编译器的一个指令。编译器是一个将你的C/C++代码转换成机器码的软件,机器码是arduino上的Atmega芯片能识别的真正指令。
具体来讲,它指示编译器编译器从RAM而非存储寄存器中读取变量,存储寄存器是程序存储和操做变量的一个临时地方。在某些状况下,存储在寄存器中的变量值多是不许确的。
若是一个变量所在的代码段可能会意外地致使变量值改变那此变量应声明为volatile,好比并行多线程等。在arduino中,惟一可能发生这种现象的地方就是和中断有关的代码段,成为中断服务程序。
例子
//当中断引脚改变状态时,开闭LED
int pin = 13;
volatile int state = LOW;
void setup()
{
pinMode(pin, OUTPUT);
attachInterrupt(0, blink, CHANGE);
}
void loop()
{
digitalWrite(pin, state);
}
void blink()
{
state = !state;
}
13.4 const
const关键字表明常量。它是一个变量限定符,用于修改变量的性质,使其变为只读状态。这意味着该变量,就像任何相同类型的其余变量同样使用,但不能改变其值。若是尝试为一个const变量赋值,编译时将会报错。
const关键字定义的常量,遵照 variable scoping 管辖的其余变量的规则。这一点加上使用 #define的缺陷 ,使 const 关键字成为定义常量的一个的首选方法。
例子
const float pi = 3.14;
float x;
// ....
x = pi * 2; // 在数学表达式中使用常量不会报错
pi = 7; // 错误的用法 - 你不能修改常量值,或给常量赋值。
#define 或 const
您能够使用 const 或 #define 建立数字或字符串常量。但 arrays, 你只能使用 const。 通常 const 相对 的#define是首选 的定义常量语法。
十4、辅助工具
14.1 sizeof()
描述
sizeof操做符返回一个变量类型的字节数,或者该数在数组中占有的字节数。
语法
sizeof(variable)
参数
variable: 任何变量类型或数组(如int,float,byte)
示例代码
sizeof操做符用来处理数组很是有效,它能很方便的改变数组的大小而不用破坏程序的其余部分。
这个程序一次打印出一个字符串文本的字符。尝试改变一下字符串。
char myStr[] = "this is a test";
int i;
void setup(){
Serial.begin(9600);
}
{0}void{/0}{1} {/1}{2}loop{/2}{1}() {{/1}
for (i = 0; i < sizeof(myStr) - 1; i++){
Serial.print(i, DEC);
Serial.print(" = ");
Serial.println(myStr[i], BYTE);
}
}
请注意sizeof返回字节数总数。所以,较大的变量类型,如整数,for循环看起来应该像这样。
for (i = 0; i < (sizeof(myInts)/sizeof(int)) - 1; i++) {
//用myInts[i]来作些事
}
函数部分
十5、数字 I/O
15.1 pinMode()
描述
将指定的引脚配置成输出或输入。详情请见digital pins。
语法
pinMode(pin, mode)
参数
pin:要设置模式的引脚
mode:INPUT或OUTPUT
返回
无
例子
ledPin = 13 // LED链接到数字脚13
void setup()
{
pinMode(ledPin,OUTPUT); //设置数字脚为输出
}
void loop()
{
digitalWrite(ledPin,HIGH); //点亮LED
delay(1000); // 等待一秒
digitalWrite(ledPin, LOW); // 灭掉LED
延迟(1000); //等待第二个
}
注意
模拟输入脚也能当作数字脚使用,参见A0,A1等
15.2 digitalWrite()
描述
给一个数字引脚写入HIGH或者LOW。
若是一个引脚已经使用pinMode()配置为OUTPUT模式,其电压将被设置为相应的值,HIGH为5V(3.3V控制板上为3.3V),LOW为0V。
若是引脚配置为INPUT模式,使用digitalWrite()写入HIGH值,将使内部20K上拉电阻(详见数字引脚教程)。写入LOW将会禁用上拉。上拉电阻能够点亮一个LED让其微微亮,若是LED工做,可是亮度很低,多是由于这个缘由引发的。补救的办法是 使用pinMode()函数设置为输出引脚。
注意:数字13号引脚难以做为数字输入使用,由于大部分的控制板上使用了一颗LED与一个电阻链接到他。若是启动了内部的20K上拉电阻,他的电压将在1.7V左右,而不是正常的5V,由于板载LED串联的电阻把他使他降了下来,这意味着他返回的值老是LOW。若是必须使用数字13号引脚的输入模式,须要使用外部上拉下拉电阻。
语法
digitalWrite(pin, value)
参数
pin: 引脚编号(如1,5,10,A0,A3)
value: HIGH or LOW
返回
无
例子
int ledPin = 13; // LED链接到数字13号端口
void setup()
{
pinMode(ledPin, OUTPUT); // 设置数字端口为输入模式
}
void loop()
{
digitalWrite(ledPin, HIGH); // 使LED亮
delay(1000); // 延迟一秒
digitalWrite(ledPin, LOW); // 使LED灭
delay(1000); // 延迟一秒
}
13号端口设置为高电平,延迟一秒,而后设置为低电平。
注释
模拟引脚也能够当作数字引脚使用,使用方法是输入端口A0,A1,A2等。
15.3 digitalRead()
描述
读取指定引脚的值,HIGH或LOW。
语法
digitalRead(PIN)
参数
pin:你想读取的引脚号(int)
返回
HIGH 或 LOW
例子
ledPin = 13 // LED链接到13脚
int inPin = 7; // 按钮链接到数字引脚7
int val = 0; //定义变量存以储读值
void setup()
{
pinMode(ledPin, OUTPUT); // 将13脚设置为输出
pinMode(inPin, INPUT); // 将7脚设置为输入
}
void loop()
{
val = digitalRead(inPin); // 读取输入脚
digitalWrite(ledPin, val); //将LED值设置为按钮的值
}
将13脚设置为输入脚7脚的值。
注意
若是引脚悬空,digitalRead()会返回HIGH或LOW(随机变化)。
模拟输入脚能当作数字脚使用,参见A0,A1等。
十6、模拟 I/O
16.1 analogReference()
描述
配置用于模拟输入的基准电压(即输入范围的最大值)。选项有:
DEFAULT:默认5V(Arduino板为5V)或3.3伏特(Arduino板为3.3V)为基准电压。
INTERNAL:在ATmega168和ATmega328上以1.1V为基准电压,以及在ATmega8上以2.56V为基准电压(Arduino Mega无此选项)
INTERNAL1V1:以1.1V为基准电压(此选项仅针对Arduino Mega)
INTERNAL2V56:以2.56V为基准电压(此选项仅针对Arduino Mega)
EXTERNAL:以AREF引脚(0至5V)的电压做为基准电压。
参数
type:使用哪一种参考类型(DEFAULT, INTERNAL, INTERNAL1V1, INTERNAL2V56, 或者 EXTERNAL)。
返回
无
注意事项
改变基准电压后,以前从analogRead()读取的数据可能不许确。
警告
不要在AREF引脚上使用使用任何小于0V或超过5V的外部电压。若是你使用AREF引脚上的电压做为基准电压,你在调用analogRead()前必须设置参考类型为EXTERNAL。不然,你将会削短有效的基准电压(内部产生)和AREF引脚,这可能会损坏您Arduino板上的单片机。
另外,您能够在外部基准电压和AREF引脚之间链接一个5K电阻,使你能够在外部和内部基准电压之间切换。请注意,总阻值将会发生改变,由于AREF引脚内部有一个32K电阻。这两个电阻都有分压做用。因此,例如,若是输入2.5V的电压,最终在在AREF引脚上的电压将为2.5 * 32 /(32 + 5)= 2.2V。
16.2 analogRead()
描述
从指定的模拟引脚读取数据值。 Arduino板包含一个6通道(Mini和Nano有8个通道,Mega有16个通道),10位模拟数字转换器。这意味着它将0至5伏特之间的输入电压映射到0至1023之间的整数值。这将产生读数之间的关系:5伏特/ 1024单位,或0.0049伏特(4.9 mV)每单位。输入范围和精度能够使用analogReference()改变。 它须要大约100微秒(0.0001)来读取模拟输入,因此最大的阅读速度是每秒10000次。
语法
analogRead(PIN)
数值的读取
引脚:从输入引脚(大部分板子从0到5,Mini和Nano从0到7,Mega从0到15)读取数值
返回
从0到1023的整数值
注意事项
若是模拟输入引脚没有连入电路,由analogRead()返回的值将根据多项因素(例如其余模拟输入引脚,你的手靠近板子等)产生波动。
例子
int analogPin = 3; //电位器(中间的引脚)链接到模拟输入引脚3
//另外两个引脚分别接地和+5 V
int val = 0; //定义变量来存储读取的数值
void setup()
{
serial.begin(9600); //设置波特率(9600)
}
void loop()
{
val = analogRead(analogPin); //从输入引脚读取数值
serial.println(val); //显示读取的数值
}
16.3 analogWrite() PWM
描述
从一个引脚输出模拟值(PWM)。可用于让LED以不一样的亮度点亮或驱动电机以不一样的速度旋转。analogWrite()输出结束后,该引脚将产生一个稳定的特殊占空比方波,直到下次调用analogWrite()(或在同一引脚调用digitalRead()或digitalWrite())。PWM信号的频率大约是490赫兹。
在大多数arduino板(ATmega168或ATmega328),只有引脚3,5,6,9,10和11能够实现该功能。在aduino Mega上,引脚2到13能够实现该功能。老的Arduino板(ATmega8)的只有引脚九、十、11能够使用analogWrite()。在使用analogWrite()前,你不须要调用pinMode()来设置引脚为输出引脚。
analogWrite函数与模拟引脚、analogRead函数没有直接关系。
语法
analogWrite(pin,value)
参数
pin:用于输入数值的引脚。
value:占空比:0(彻底关闭)到255(彻底打开)之间。
返回
无
说明和已知问题
引脚5和6的PWM输出将高于预期的占空比(输出的数值偏高)。这是由于millis()和delay()功能,和PWM输出共享相同的内部定时器。这将致使大多时候处于低占空比状态(如:0 - 10),并可能致使在数值为0时,没有彻底关闭引脚5和6。
例子
经过读取电位器的阻值控制LED的亮度
int ledPin = 9; // LED链接到数字引脚9
int analogPin = 3; //电位器链接到模拟引脚3
int val = 0; //定义变量存以储读值
void setup()
{
pinMode(ledPin,OUTPUT); //设置引脚为输出引脚
}
void loop()
{
val = analogRead(analogPin); //从输入引脚读取数值
analogWrite(ledPin,val / 4); // 以val / 4的数值点亮LED(由于analogRead读取的数值从0到1023,而analogWrite输出的数值从0到255)
}
十7、高级 I/O
17.1 tone()
描述
在一个引脚上产生一个特定频率的方波(50%占空比)。持续时间能够设定,不然波形会一直产生直到调用noTone()函数。该引脚能够链接压电蜂鸣器或其余喇叭播放声音。
在同一时刻只能产生一个声音。若是一个引脚已经在播放音乐,那调用tone()将不会有任何效果。若是音乐在同一个引脚上播放,它会自动调整频率。
使用tone()函数会与3脚和11脚的PWM产生干扰(Mega板除外)。
注意:若是你要在多个引脚上产生不一样的音调,你要在对下一个引脚使用tone()函数前对此引脚调用noTone()函数。
语法
tone(pin, frequency)
tone(pin, frequency, duration)
参数
pin:要产生声音的引脚
frequency: 产生声音的频率,单位Hz,类型unsigned int
duration:声音持续的时间,单位毫秒(可选),类型unsigned long
17.2 noTone()
描述
中止由tone()产生的方波。若是没有使用tone()将不会有效果。
注意:若是你想在多个引脚上产生不一样的声音,你要在对下个引脚使用tone()前对刚才的引脚调用noTone().
语法
noTone(pin)
参数
pin: 所要中止产生声音的引脚
17.3 shiftOut()
描述
将一个数据的一个字节一位一位的移出。从最高有效位(最左边)或最低有效位(最右边)开始。依次向数据脚写入每一位,以后时钟脚被拉高或拉低,指示刚才的数据有效。
注意:若是你所链接的设备时钟类型为上升沿,你要肯定在调用shiftOut()前时钟脚为低电平,如调用digitalWrite(clockPin, LOW)。
注意:这是一个软件实现;Arduino提供了一个硬件实现的SPI库,它速度更快但只在特定脚有效。
语法
shiftOut(dataPin, clockPin, bitOrder, value)
参数
dataPin:输出每一位数据的引脚(int)
clockPin:时钟脚,当dataPin有值时此引脚电平变化(int)
bitOrder:输出位的顺序,最高位优先或最低位优先
value: 要移位输出的数据(byte)
返回
无
注意
dataPin和clockPin要用pinMode()配置为输出。 shiftOut目前只能输出1个字节(8位),因此若是输出值大于255须要分两步。
//最高有效位优先串行输出
int 数据= 500;
//移位输出高字节
shiftOut(dataPin, clock, MSBFIRST, (data >> 8));
//移位输出低字节
shiftOut(data, clock, MSBFIRST, data);
//最低有效位优先串行输出
data = 500;
//移位输出低字节
shiftOut(dataPin, clock, LSBFIRST, data);
//移位输出高字节
shiftOut(dataPin, clock, LSBFIRST, (data >> 8));
例子
相应电路,查看tutorial on controlling a 74HC595 shift register
// ************************************************ ************** //
// Name : shiftOut代码, Hello World //
// Author : Carlyn Maw,Tom Igoe //
// Date : 25 Oct, 2006 //
// 版本 : 1.0 //
// 注释:使用74HC595移位寄存器从0到255计数 //
//
// ************************************************ ****************
//引脚链接到74HC595的ST_CP
int latchPin = 8;
//引脚链接到74HC595的SH_CP
int clockPin = 12;
// //引脚链接到74HC595的DS
int dataPin = 11;
void setup() {
//设置引脚为输出
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);
}
void loop() {
//向上计数程序
(J = 0; J <256; J + +){
//传输数据的时候将latchPin拉低
digitalWrite(latchpin, LOW);
shiftOut的 (dataPin,clockPin,LSBFIRST,J);
//以后将latchPin拉高以告诉芯片
//它不须要再接受信息了
digitalWrite(latchpin, HIGH);
delay(1000);
}
}
17.4 shiftIn()
描述
将一个数据的一个字节一位一位的移入。从最高有效位(最左边)或最低有效位(最右边)开始。对于每一个位,先拉高时钟电平,再从数据传输线中读取一位,再将时钟线拉低。
注意:这是一个软件实现;Arduino提供了一个硬件实现的SPI库,它速度更快但只在特定脚有效。
语法
shiftIn(dataPin,clockPin,bitOrder)
参数
dataPin:输出每一位数据的引脚(int)
clockPin:时钟脚,当dataPin有值时此引脚电平变化(int)
bitOrder:输出位的顺序,最高位优先或最低位优先
17.5 pulseIn()
描述
读取一个引脚的脉冲(HIGH或LOW)。例如,若是value是HIGH,pulseIn()会等待引脚变为HIGH,开始计时,再等待引脚变为LOW并中止计时。返回脉冲的长度,单位微秒。若是在指定的时间内无脉冲函数返回。
此函数的计时功能由经验决定,长时间的脉冲计时可能会出错。计时范围从10微秒至3分钟。(1秒=1000毫秒=1000000微秒)
语法
pulseIn(pin, value)
pulseIn(pin, value, timeout)
参数
pin:你要进行脉冲计时的引脚号(int)。
value:要读取的脉冲类型,HIGH或LOW(int)。
timeout (可选):指定脉冲计数的等待时间,单位为微秒,默认值是1秒(unsigned long)
返回
脉冲长度(微秒),若是等待超时返回0(unsigned long)
例子
int pin = 7;
unsigned long duration;
void setup()
{
pinMode(pin, INPUT);
}
void loop()
{
duration = pulseIn(pin, HIGH);;
}
十8、时间
18.1 millis()
描述
返回Arduino开发板从运行当前程序开始的毫秒数。这个数字将在约50天后溢出(归零)。
参数
无
返回
返回从运行当前程序开始的毫秒数(无符号长整数)。
例子
unsigned long time;
void setup(){
Serial.begin(9600);
}
void loop(){
serial.print("Time:");
time = millis();
//打印从程序开始到如今的时间
serial.println(time);
//等待一秒钟,以避免发送大量的数据
delay(1000);
}
提示
注意,参数 millis 是一个无符号长整数,试图和其余数据类型(如整型数)作数学运算可能会产生错误。
当中断函数发生时,millis()的数值将不会继续变化。
18.2 micros()
描述
返回 Arduino 开发板从运行当前程序开始的微秒数。这个数字将在约70分钟后溢出(归零)。在 16MHz 的 Arduino 开发板上(好比 Duemilanove 和 Nano),这个函数的分辨率为四微秒(即返回值老是四的倍数)。在 8MHz 的 Arduino 开发板上(好比 LilyPad),这个函数的分辨率为八微秒。
注意 :每毫秒是1,000微秒,每秒是1,000,000微秒。
参数
无
返回
返回从运行当前程序开始的微秒数(无符号长整数)。
例子
unsigned long time;
void setup(){
Serial.begin(9600);
}
void loop(){
Serial.print(“Time:”);
time = micros();
//打印从程序开始的时间
Serial.println(time);
//等待一秒钟,以避免发送大量的数据
delay(1000);
}
18.3 delay()
描述
使程序暂定设定的时间(单位毫秒)。(一秒等于1000毫秒)
语法
delay(ms)
参数
ms:暂停的毫秒数(unsigned long)
返回
无
例子
ledPin = 13 / / LED链接到数字13脚
void setup()
{
pinMode(ledPin, OUTPUT); // 设置引脚为输出
}
void loop()
{
digitalWrite(ledPin, HIGH); // 点亮LED
delay(1000); // 等待1秒
digitalWrite(ledPin, LOW); // 灭掉LED
delay(1000); // 等待一秒
}
警告
虽然建立一个使用delay()的闪烁LED很简单,而且许多例子将很短的delay用于消除开关抖动,delay()确实拥有不少显著的缺点。在delay函数使用的过程当中,读取传感器值、计算、引脚操做均没法执行,所以,它所带来的后果就是使其余大多数活动暂停。其余操做定时的方法请参加millis()函数和它下面的例子。大多数熟练的程序员一般避免超过10毫秒的delay(),除非arduino程序很是简单。
但某些操做在delay()执行时任然可以运行,由于delay函数不会使中断失效。通讯端口RX接收到得数据会被记录,PWM(analogWrite)值和引脚状态会保持,中断也会按设定的执行。
18.4 delayMicroseconds()
描述
使程序暂停指定的一段时间(单位:微秒)。一秒等于1000000微秒。 目前,可以产生的最大的延时准确值是16383。这可能会在将来的Arduino版本中改变。对于超过几千微秒的延迟,你应该使用delay()代替。
语法
delayMicroseconds(us)
参数
us:暂停的时间,单位微秒(unsigned int)
返回
无
例子
int outPin = 8; // digital pin 8
void setup()
{
pinMode(outPin,OUTPUT); //设置为输出的数字管脚
}
void loop()
{
digitalWrite(outPin,HIGH); //设置引脚高电平
delayMicroseconds(50); // 暂停50微秒
digitalWrite(outPin, LOW); // 设置引脚低电平
delayMicroseconds(50); // 暂停50微秒
}
将8号引脚配置为输出脚。它会发出一系列周期100微秒的方波。
警告和已知问题
此函数在3微秒以以上工做的很是准确。咱们不能保证,delayMicroseconds在更小的时间内延时准确。
Arduino0018版本后,delayMicroseconds()再也不会使中断失效。
十9、数学运算
19.1 min()
min(x, y)
描述
计算两个数字中的最小值。
参数
X:第一个数字,任何数据类型
Y:第二个数字,任何数据类型
返回
两个数字中的较小者。
举例
sensVal = min(sensVal,100); //将 sensVal 或 100 中较小者赋值给 sensVal
//确保它永远不会大于 100。
注释
直观的比较,max() 方法常被用来约束变量的下限,而 min() 常被用来约束变量的上限。
警告
因为 min() 函数的实现方式,应避免在括号内出现其余函数,这将致使不正确的结果。
min(a++, 100); //避免这种状况 - 会产生不正确的结果
a++;
min(a, 100); //使用这种形式替代 - 将其余数学运算放在函数以外
19.2 max()
max(x,y)
描述
计算两个数的最大值。
参数
X:第一个数字,任何数据类型
Y:第二个数字,任何数据类型
返回
两个参数中较大的一个。
例子
sensVal = max(senVal, 20); // 将20或更大值赋给sensVal
//(有效保障它的值至少为20)
注意
和直观相反,max()一般用来约束变量最小值,而min()一般用来约束变量的最大值。
警告
因为max()函数的实现方法,要避免在括号内嵌套其余函数,这可能会致使不正确的结果。
max(a--, 0); //避免此用法,这会致使不正确结果
a--; // 用此方法代替
max(a, 0); // 将其余计算放在函数外
19.3 abs()
ABS(X)
描述
计算一个数的绝对值。
参数
X:一个数
返回
若是x大于或等于0,则返回它自己。 若是x小于0,则返回它的相反数。
警告
因为实现ABS()函数的方法,避免在括号内使用任何函数(括号内只能是数字),不然将致使不正确的结果。
ABS(a+ +); //避免这种状况,不然它将产生不正确的结果
a ++; //使用这段代码代替上述的错误代码
ABS(a); //保证其余函数放在括号的外部
19.4 constrain()
描述
将一个数约束在一个范围内
参数
x:要被约束的数字,全部的数据类型适用。
a:该范围的最小值,全部的数据类型适用。
b:该范围的最大值,全部的数据类型适用。
返回值
x:若是 x是介于 a 和 b之间
a:若是 x小于a
b:若是 x大于b
例子
sensVal = constrain(sensVal, 10, 150);
//传感器返回值的范围限制在10到150之间
19.5 map()
map(value, fromLow, fromHigh, toLow, toHigh)
描述
将一个数从一个范围映射到另一个范围。也就是说,会将 fromLow 到 fromHigh 之间的值映射到 toLow 在 toHigh 之间的值。
不限制值的范围,由于范围外的值有时是刻意的和有用的。若是须要限制的范围, constrain() 函数能够用于此函数以前或以后。
注意,两个范围中的“下限”能够比“上限”更大或者更小,所以 map() 函数能够用来翻转数值的范围,例如:
y = map(x, 1, 50, 50, 1);
这个函数一样能够处理负数,请看下面这个例子:
y = map(x, 1, 50, 50, -100);
是有效的而且能够很好的运行。
map() 函数使用整型数进行运算所以不会产生分数,这时运算应该代表它须要这样作。小数的余数部分会被舍去,不会四舍五入或者平均。
参数
value:须要映射的值
fromLow:当前范围值的下限
fromHigh:当前范围值的上限
toLow:目标范围值的下限
toHigh:目标范围值的上限
返回值
被映射的值。
例子
/*映射一个模拟值到8位(0到255)*/
void setup(){}
void loop()
{
int val = analogRead(0);
val = map(val, 0, 1023, 0, 255);
analogWrite(9, val);
}
附录
关于数学的实现,这里是完整函数
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;
}
19.6 pow()
pow(base, exponent)
描述
计算一个数的幂次方。Pow()能够用来计算一个数的分数幂。这用来产生指数幂的数或曲线很是方便。
参数
base:底数(float)
exponent:幂(float)
返回
一个数的幂次方值(double)
例子
详情见 库代码中的fscale函数。
19.7 sqrt()
sqrt(x)
描述
计算一个数的平方根。
参数
x:被开方数,任何类型
返回值
此数的平方根,类型double
二10、三角函数
20.1 sin()
sin(rad)
描述
计算角度的正弦(弧度)。其结果在-1和1之间。
参数
rad: 弧度制的角度(float)
返回
角度的正弦值(double)
20.2 cos()
cos(rad)
描述
计算一个角度的余弦值(用弧度表示)。返回值在 -1 和 1 之间。
参数
rad:用弧度表示的角度 (浮点数)
返回
角度的余弦值 (双精度浮点数)
20.3 tan()
tan(rad)
描述
计算角度的正切(弧度)。结果在负无穷大和无穷大之间。
参数
rad:弧度制的角度(float)
返回值
角度的正切值
二11、随机数
21.1 randomSeed()
randomSeed(seed)
描述
使用randomSeed()初始化伪随机数生成器,使生成器在随机序列中的任意点开始。这个序列,虽然很长,而且是随机的,但始终是同一序列。
如须要在一个random()序列上生成真正意义的随机数,在执行其子序列时使用randomSeed()函数预设一个绝对的随机输入,例如在一个断开引脚上的analogRead()函数的返回值。
反之,有些时候伪随机数的精确重复也是有用的。这能够在一个随机系列开始前,经过调用一个使用固定数值的randomSeed()函数来完成。
参数
long,int - 经过数字生成种子。
返回
没有返回值
例子
long randNumber;
void setup(){
Serial.begin(9600);
randomSeed(analogRead(0));
}
void loop(){
randNumber = random(300);
Serial.println(randNumber);
delay(50);
}
21.2 random()
random()
描述
使用random()函数将生成伪随机数。
语法
random(max)
random(min, max)
参数
min - 随机数的最小值,随机数将包含此值。 (此参数可选)
max - 随机数的最大值,随机数不包含此值。
返回
min和max-1之间的随机数( 数据类型为long )
注意
如须要在一个random()序列上生成真正意义的随机数,在执行其子序列时使用randomSeed()函数预设一个绝对的随机输入,例如在一个断开引脚上的analogRead()函数的返回值。
反之,有些时候伪随机数的精确重复也是有用的。这能够在一个随机系列开始前,经过调用一个使用固定数值的randomSeed()函数来完成。
例子
long randNumber;
void setup(){
Serial.begin(9600);
//若是模拟输入引脚0为断开,随机的模拟噪声
//将会调用randomSeed()函数在每次代码运行时生成
//不一样的种子数值。
//randomSeed()将随机打乱random函数。
randomSeed(analogRead(0));
}
void loop() {
//打印一个0到299之间的随机数
randNumber = random(300);
Serial.println(randNumber);
//打印一个10到19之间的随机数
randNumber = random(10, 20);
Serial.println(randNumber);
delay(50);
}
二12、位操做
22.1 lowByte()
描述
提取一个变量(例如一个字)的低位(最右边)字节。
语法
lowByte(x)
参数
x:任何类型的值
返回
字节
22.2 highByte()
描述
提取一个字节的高位(最左边的),或一个更长的字节的第二低位。
语法
highByte(x)
参数
x:任何类型的值
返回
byte
22.3 bitRead()
描述
读取一个数的位。
语法
bitRead(x, n)
参数
X:想要被读取的数 N:被读取的位,0是最低有效位(最右边)
返回
该位的值(0或1)。
22.4 bitWrite()
描述
在位上写入数字变量。
语法
bitWrite(x, n, b)
参数
X:要写入的数值变量
N:要写入的数值变量的位,从0开始是最低(最右边)的位
B:写入位的数值(0或1)
返回
无
22.5 bitSet()
描述
为一个数字变量设置一个位。
语句
bitSet(x, n)
语法
X:想要设置的数字变量
N:想要设置的位,0是最重要(最右边)的位
返回
无
22.6 bitClear()
描述
清除一个数值型数值的指定位(将此位设置成 0)
语法
bitClear(x, n)
参数
X:指定要清除位的数值 N:指定要清除位的位置,从0开始,0 表示最右端位
返回值
无
22.7 bit()
描述
计算指定位的值(0位是1,1位是2,2位4,以此类推)。
语法
bit(n)
参数
n:须要计算的位
返回值
位值
二十3、设置中断函数
23.1 attachInterrupt()
attachInterrupt(interrupt, function, mode)
描述
当发生外部中断时,调用一个指定函数。当中断发生时,该函数会取代正在执行的程序。大多数的Arduino板有两个外部中断:0(数字引脚2)和1(数字引脚3)。
arduino Mege有四个外部中断:数字2(引脚21),3(20针),4(引脚19),5(引脚18)。
语法
interrupt:中断引脚数
function:中断发生时调用的函数,此函数必须不带参数和不返回任何值。该函数有时被称为中断服务程序。
mode:定义什么时候发生中断如下四个contstants预约有效值:
LOW 当引脚为低电平时,触发中断
CHANGE 当引脚电平发生改变时,触发中断
RISING 当引脚由低电平变为高电平时,触发中断
FALLING 当引脚由高电平变为低电平时,触发中断.
返回
无
注意事项
当中断函数发生时,delay()和millis()的数值将不会继续变化。当中断发生时,串口收到的数据可能会丢失。你应该声明一个变量来在未发生中断时储存变量。
使用中断
在单片机自动化程序中当突发事件发生时,中断是很是有用的,它能够帮助解决时序问题。一个使用中断的任务可能会读一个旋转编码器,监视用户的输入。
若是你想以确保程序始终抓住一个旋转编码器的脉冲,历来不缺乏一个脉冲,它将使写一个程序作任何事情都要很是棘手,由于该计划将须要不断轮询的传感器线编码器,为了遇上脉冲发生时。其余传感器也是如此,如试图读取一个声音传感器正试图遇上一按,或红外线槽传感器(照片灭弧室),试图抓住一个硬币降低。在全部这些状况下,使用一个中断能够释放的微控制器来完成其余一些工做。
程序示例
int pin = 13;
volatile int state = LOW;
void setup()
{
pinMode(pin, OUTPUT);
attachInterrupt(0, blink, CHANGE);
}
void loop()
{
digitalWrite(pin, state);
}
void blink()
{
state = !state;
}
23.2 detachInterrupt()
detachInterrupt(interrupt)
描述
关闭给定的中断。
参数
interrupt: 中断禁用的数(0或者1).
二十4、开关中断
24.1 interrupts()(中断)
描述
从新启用中断(使用noInterrupts()命令后将被禁用)。中断容许一些重要任务在后台运行,默认状态是启用的。禁用中断后一些函数可能没法工做,并传入信息可能会被忽略。中断会稍微打乱代码的时间,可是在关键部分能够禁用中断。
参数
无
返回
无
例子
void setup() {
}
void loop()
{
noInterrupts();
//重要、时间敏感的代码
interrupts();
//其余代码写在这里
}
24.2 noInterrupts()(禁止中断)
描述
禁止中断(从新使能中断interrupts())。中断容许在后台运行一些重要任务,默认使能中断。禁止中断时部分函数会没法工做,通讯中接收到的信息也可能会丢失。
中断会稍影响计时代码,在某些特定的代码中也会失效。
参数
无
返回
无
例子
void setup()
void loop()
{
noInterrupts();
//关键的、时间敏感的代码放在这
interrupts();
//其余代码放在这
}
二十5、通信
25.1 Serial
用于Arduino控制板和一台计算机或其余设备之间的通讯。全部的Arduino控制板有至少一个串口(又称做为UART或USART)。它经过0(RX)和1(TX)数字引脚通过串口转换芯片链接计算机USB端口与计算机进行通讯。所以,若是你使用这些功能的同时你不能使用引脚0和1做为输入或输出。
您能够使用Arduino IDE内置的串口监视器与Arduino板通讯。点击工具栏上的串口监视器按钮,调用begin()函数(选择相同的波特率)。
Arduino Mega 有三个额外的串口:Serial 1使用19(RX)和18(TX),Serial 2使用17(RX)和16(TX),Serial3使用15(RX)和14(TX)。 若要使用这三个引脚与您的我的电脑通讯,你须要一个额外的USB转串口适配器,由于这三个引脚没有链接到Mega上的USB转串口适配器。若要用它们来与外部的TTL串口设备进行通讯,将TX引脚链接到您的设备的RX引脚,将RX引脚链接到您的设备的TX引脚,将GND链接到您的设备的GND。(不要直接将这些引脚直接链接到RS232串口;他们的工做电压在+/- 12V,可能会损坏您的Arduino控制板。)
Arduino Leonardo板使用Serial 1经过0(RX)和1(TX)与viaRS-232通讯,。Serial预留给使用Mouse and Keyboard libarariies的USB CDC通讯 。更多信息,请参考Leonardo 开始使用页和硬件页。
函数
25.1.1 if (Serial)
25.1.2 available()
25.1.3 begin()
25.1.4 end()
25.1.5 find()
25.1.6 findUntil()
25.1.7 flush()
25.1.8 parseFloat()
25.1.9 parseInt()
25.1.10 peek()
25.1.11 print()
25.1.12 println()
25.1.13 read()
25.1.14 readBytes()
25.1.15 readBytesUntil()
25.1.16 setTimeout()
25.1.17 write()
25.1.18 SerialEvent()
25.1.1 if (Serial)
说明
表示指定的串口是否准备好。
在Leonardo上,if(Serial)表示不论有无USB CDC,串行链接都是开放的。对于全部其余的状况,包括Leonardo上的if(Serial1),将一直返回true。 这来自于 Arduino 1.0.1 版本的介绍.
语法
对于全部的arduino板:
if (Serial)
Arduino Leonardo 特有:
if (Serial1)
Arduino Mega 特有:
if (Serial1)
if (Serial2)
if (Serial3)
参数
无
返回
布尔值:若是指定的串行端口是可用的,则返回true。若是查询Leonardo的USB CDC串行链接以前,它是准备好的,将只返回false。
例子
void setup() {
//初始化串口和等待端口打开:
Serial.begin(9600);
while (!Serial) {
//等待串口链接。只有 Leonardo 须要。
}
}
void loop() {
//正常进行
}
25.1.2 Serial.available()
说明
获取从串口读取有效的字节数(字符)。这是已经传输到,并存储在串行接收缓冲区(可以存储64个字节)的数据。 available()继承了 Stream类。
语法
Serial.available()
仅适用于Arduino Mega :
Serial1.available()
Serial2.available()
Serial3.available()
参数
无
返回
可读取的字节数
例子
incomingByte = 0; //传入的串行数据
void setup() {
Serial.begin(9600); // 打开串行端口,设置传输波特率为9600 bps
}
void loop() {
//只有当你接收到数据时才会发送数据,:
if (Serial.available() > 0) {
//读取传入的字节:
incomingByte = Serial.read();
//显示你获得的数据:
Serial.print("I received: ");
Serial.println(incomingByte, DEC);
}
}
Arduino Mega 的例子:
void setup() {
Serial.begin(9600);
Serial1.begin(9600);
}
void loop() {
//读取端口0,发送到端口1:
if (Serial.available()) {
int inByte = Serial.read();
Serial1.print(inByte, BYTE);
}
//读端口1,发送到端口0:
if (Serial1.available()) {
int inByte = Serial1.read();
Serial.print(inByte, BYTE);
}
}
25.1.3 Serial.begin() 初始化串口波特率
说明
将串行数据传输速率设置为位/秒(波特)。与计算机进行通讯时,能够使用这些波特率:300,1200,2400,4800,9600,14400,19200,28800,38400,57600或115200。固然,您也能够指定其余波特率 - 例如,引脚0和1和一个元件进行通讯,它须要一个特定的波特率。
语法
Serial.begin(speed) 仅适用于Arduino Mega : Serial1.begin(speed) Serial2.begin(speed) Serial3.begin(speed)
参数
speed: 位/秒 (波特) - long
返回
无
例子
void setup() {
Serial.begin(9600); // 打开串口,设置数据传输速率为9600bps
}
void loop() {
Arduino Mega 的例子:
// Arduino Mega 能够使用四个串口
// (Serial, Serial1, Serial2, Serial3),
// 从而设置四个不一样的波特率:
void setup(){
Serial.begin(9600);
Serial1.begin(38400);
Serial2.begin(19200);
Serial3.begin(4800);
Serial.println("Hello Computer");
Serial1.println("Hello Serial 1");
Serial2.println("Hello Serial 2");
Serial3.println("Hello Serial 3");
}
void loop() {}
25.1.4 Serial.end()
说明
停用串行通讯,使RX和TX引脚用于通常输入和输出。要从新使用串行通讯, 须要 Serial.begin()语句。
语法
Serial.end()
仅适用于Arduino Mega: Serial1.end() Serial2.end() Serial3.end()
参数
无
返回
无
25.1.5 Serial.find()
说明
Serial.find() 从串行缓冲器中读取数据,直到发现给定长度的目标字符串。若是找到目标字符串,该函数返回true,若是超时则返回false。
Serial.flush() 继承了 Stream 类.
语法
Serial.find(target)
参数
target : 要搜索的字符串(字符)
返回
布尔型
25.1.6 Serial.findUntil()
说明
Serial.findUntil()从串行缓冲区读取数据,直到找到一个给定的长度或字符串终止位。
若是目标字符串被发现,该函数返回true,若是超时则返回false。
Serial.findUntil()继承了Stream类。
语法
Serial.findUntil(target, terminal)
参数
target : 要搜索的字符串(char) terminal : 在搜索中的字符串终止位 (char)
返回
布尔型
25.1.7 Serial.flush()
说明
等待超出的串行数据完成传输。(在1.0及以上的版本中,flush()语句的功能再也不是丢弃全部进入缓存器的串行数据。)
flush()继承了Stream类.
语法
Serial.flush()
仅 Arduino Mega 能够使用的语法:
Serial1.flush()
Serial2.flush()
Serial3.flush()
参数
无
返回
无
25.1.8 Serial.parseFloat()
描述
Serial.parseFloat()命令从串口缓冲区返回第一个有效的浮点数. Characters that are not digits (or the minus sign) are skipped. parseFloat() is terminated by the first character that is not a floating point number.
Serial.parseFloat()继承了Stream类。
语法
Serial.parseFloat()
参数
无
返回
float
25.1.9 Serial.parseInt()
说明
查找传入的串行数据流中的下一个有效的整数。 parseInt()继承了Stream类。
语法
Serial.parseInt()
下面三个命令仅适用于Arduino Mega:
Serial1.parseInt()
Serial2.parseInt()
Serial3.parseInt()
参数
无
返回
int : 下一个有效的整数
25.1.10 Serial.peek()
说明
返回传入的串行数据的下一个字节(字符),而不是进入内部串行缓冲器调取。也就是说,连续调用 peek()将返回相同的字符,与调用read()方法相同。peek()继承自 Stream类。
语法
Serial.peek()
仅适用于Arduino Mega :
Serial1.peek()
Serial2.peek()
Serial3.peek()
参数
无
返回
传入的串行数据的第一个字节(或-1,若是没有可用的数据的话)- int
25.1.11 Serial.print() 从串口打印输出数据
说明
以人们可读的ASCII文本形式打印数据到串口输出。此命令能够采起多种形式。每一个数字的打印输出使用的是ASCII字符。浮点型一样打印输出的是ASCII字符,保留到小数点后两位。Bytes型则打印输出单个字符。字符和字符串原样打印输出。Serial.print()打印输出数据不换行,Serial.println()打印输出数据自动换行处理。例如
Serial.print(78)输出为“78”
Serial.print(1.23456)输出为“1.23”
Serial.print(“N”)输出为“N”
Serial.print(“Hello world.”)输出为“Hello world.”
也能够本身定义输出为几进制(格式);能够是BIN(二进制,或以2为基数),OCT(八进制,或以8为基数),DEC(十进制,或以10为基数),HEX(十六进制,或以16为基数)。对于浮点型数字,能够指定输出的小数数位。例如
Serial.print(78,BIN)输出为“1001110”
Serial.print(78,OCT)输出为“116”
Serial.print(78,DEC)输出为“78”
Serial.print(78,HEX)输出为“4E”
Serial.println(1.23456,0)输出为“1”
Serial.println(1.23456,2)输出为“1.23”
Serial.println(1.23456,4)输出为“1.2346”
你能够经过基于闪存的字符串来进行打印输出,将数据放入F()中,再放入Serial.print()。例如 Serial.print(F(“Hello world”)) 若要发送一个字节,则使用 Serial.write()。
语法
Serial.print(val)
Serial.print(val,格式)
参数
val:打印输出的值 - 任何数据类型
格式:指定进制(整数数据类型)或小数位数(浮点类型)
返回
字节 print()将返回写入的字节数,可是否使用(或读出)这个数字是可设定的
例子
/ *
使用for循环打印一个数字的各类格式。
* /
int x = 0; // 定义一个变量并赋值
void setup() {
Serial.begin(9600); // 打开串口传输,并设置波特率为9600
}
void loop() {
/ /打印标签
Serial.print("NO FORMAT"); // 打印一个标签
Serial.print("\t"); // 打印一个转义字符
Serial.print("DEC");
Serial.print("\t");
Serial.print("HEX");
Serial.print("\t");
Serial.print("OCT");
Serial.print("\t");
Serial.print("BIN");
Serial.print("\t");
for(x=0; x< 64; x++){ // 打印ASCII码表的一部分, 修改它的格式获得须要的内容
/ /打印多种格式:
Serial.print(x); // 以十进制格式将x打印输出 - 与 "DEC"相同
Serial.print("\t"); // 横向跳格
Serial.print(x, DEC); // 以十进制格式将x打印输出
Serial.print("\t"); // 横向跳格
Serial.print(x, HEX); // 以十六进制格式打印输出
Serial.print("\t"); // 横向跳格
Serial.print(x, OCT); // 以八进制格式打印输出
Serial.print("\t"); // 横向跳格
Serial.println(x, BIN); // 以二进制格式打印输出
//而后用 "println"打印一个回车
delay(200); // 延时200ms
}
Serial.println(""); // 打印一个空字符,并自动换行
}
编程技巧 做为1.0版本,串行传输是异步的; Serial.print()将返回以前接收到的任何字符。
25.1.12 Serial.println()
说明
打印数据到串行端口,输出人们可识别的ASCII码文本并回车 (ASCII 13, 或 '\r') 及换行(ASCII 10, 或 '\n')。此命令采用的形式与Serial.print ()相同 。
语法
Serial.println(val)
Serial.println(val, format)
参数
val: 打印的内容 - 任何数据类型均可以
format: 指定基数(整数数据类型)或小数位数(浮点类型)
返回
字节(byte)
println()将返回写入的字节数,但能够选择是否使用它。
例子
/*
模拟输入信号
读取模拟口0的模拟输入,打印输出读取的值。
由 Tom Igoe建立于2006年3月24日
*/
int analogValue = 0; // 定义一个变量来保存模拟值
void setup() {
//设置串口波特率为9600 bps:
Serial.begin(9600);
}
void loop() {
analogValue = analogRead(0); //读取引脚0的模拟输入:
//打印g各类格式:
Serial.println(analogValue); //打印ASCII编码的十进制
Serial.println(analogValue, DEC); //打印ASCII编码的十进制
Serial.println(analogValue, HEX); //打印ASCII编码的十六进制
Serial.println(analogValue, OCT); //打印ASCII编码的八进制
Serial.println(analogValue, BIN); //打印一个ASCII编码的二进制
delay(10); // 延时10毫秒:
}
25.1.13 Serial.read()
说明
读取传入的串口的数据。read() 继承自 Stream 类。
语法
serial.read()
Arduino Mega独有:
serial1.read()
serial2.read()
serial3.read()
参数
无
返回
传入的串口数据的第一个字节(或-1,若是没有可用的数据)- int
例子
int incomingByte = 0; // 传入的串行数据
void setup() {
Serial.begin(9600); // 打开串口,设置数据传输速率9600
}
void loop() {
// 当你接收数据时发送数据
if (Serial.available() > 0) {
// 读取传入的数据:
incomingByte = Serial.read();
//打印你获得的:
Serial.print("I received: ");
Serial.println(incomingByte, DEC);
}
}
25.1.14 Serial.readBytes()
说明
Serial.readBytes()从串口读字符到一个缓冲区。若是预设的长度读取完毕或者时间到了 (参见 Serial.setTimeout()),函数将终止.
Serial.readBytes()返回放置在缓冲区的字符数。返回0意味着没有发现有效的数据。
Serial.readBytes()继承自 Stream 类.
语法
Serial.readBytes(buffer, length)
参数
buffer:用来存储字节(char[]或byte[])的缓冲区
length:读取的字节数(int)
返回
byte
25.1.15 Serial.readBytesUntil()
说明
Serial.readBytesUntil()将字符从串行缓冲区读取到一个数组。若是检测到终止字符,或预设的读取长度读取完毕,或者时间到了 (参见 Serial.setTimeout())函数将终止。
Serial.readBytesUntil()返回读入数组的字符数。返回0意味着没有发现有效的数据。
Serial.readBytesUntil()继承自 Stream类。
语法
Serial.readBytesUntil(character, buffer, length)
参数
character :要搜索的字符(char)
buffer :缓冲区来存储字节(char[]或byte[])
length:读的字节数(int)
返回
byte
25.1.16 Serial.setTimeout()
说明
Serial.setTimeout()设置使用Serial.readBytesUntil() 或Serial.readBytes()时等待串口数据的最大毫秒值. 默认为1000毫秒。
Serial.setTimeout()继承自Stream 类。
语法
Serial.setTimeout(time)
参数
time :以毫秒为单位的超时时间(long)。
返回
无
25.1.17 Serial.write()
说明
写入二级制数据到串口。发送的数据以一个字节或者一系列的字节为单位。若是写入的数字为字符,需使用print()命令进行代替。
语法
Serial.write(val)
Serial.write(str)
Serial.write(buf, len)
Arduino Mega还支持:Serial1,Serial2,Serial3 (替代Serial)
参数
val: 以单个字节形式发的值
str: 以一串字节的形式发送的字符串
buf: 以一串字节的形式发送的数组
len: 数组的长度
返回
byte
write() 将返回写入的字节数,可是否使用这个数字是可选的
例子
void setup(){
Serial.begin(9600);
}
void loop(){
Serial.write(45); // 发送一个值为45的字节
int bytesSent = Serial.write(“hello”); //发送字符串“hello”,返回该字符串的长度.
}
25.1.18 Serial.SerialEvent()
暂无说明。
25.2 Stream
暂无说明。
二十6、USB(仅适用于 Leonardo 和 Due)
26.1 Mouse(键盘)
Mouse.begin()
Mouse.click()
Mouse.end()
Mouse.move()
Mouse.press()
Mouse.release()
Mouse.isPressed()
26.2 Keyboard(鼠标)
Keyboard.begin()
Keyboard.end()
Keyboard.press()
Keyboard.print()
Keyboard.println()
Keyboard.release()
Keyboard.releaseAll()
Keyboard.write()