Arduino语法详解

您所在的位置:网站首页 arduino与c语言的区别 Arduino语法详解

Arduino语法详解

2023-11-18 12:23| 来源: 网络整理| 查看: 265

Arduino 的程序可以划分为三个主要部分:结构、变量(变量与常量)、函数。

 

结构部分

 

一、结构

1.1 setup()

1.2 loop()

二、结构控制

2.1 if

2.2 if...else

2.3 for

2.4 switch case

2.5 while

2.6 do... while

2.7 break

2.8 continue

2.9 return

2.10 goto

三、扩展语法

3.1 ;(分号)

3.2 {}(花括号)

3.3 //(单行注释)

3.4 /* */(多行注释)

3.5 #define

3.6 #include

四、算数运算符

4.1 =(赋值运算符)

4.2 +(加)

4.3 -(减)

4.4 *(乘)

4.5 /(除)

4.6 %(模)

五、比较运算符

5.1 ==(等于)

5.2 !=(不等于)

5.3 (大于)

5.5 =(大于等于)

六、布尔运算符

6.1 &&(与)

6.2 ||(或)

6.3 !(非)

七、指针运算符

7.1 * 取消引用运算符

7.2 & 引用运算符

八、位运算符

8.1 & (bitwise and)

8.2 | (bitwise or)

8.3 ^ (bitwise xor)

8.4 ~ (bitwise not)

8.5 > (bitshift right)

九、复合运算符

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.1 HIGH|LOW(引脚电压定义)

10.2 INPUT|OUTPUT(数字引脚(Digital pins)定义)

10.3 true | false(逻辑层定义)

10.4 integer constants(整数常量)

10.5 floating point constants(浮点常量)

十一、数据类型

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.1 char()

12.2 byte()

12.3 int()

12.4 word()

12.5 long()

12.6 float()

十三、变量作用域 & 修饰符

13.1 variable scope(变量的作用域)

13.2 static(静态变量)

13.3 volatile

13.4 const

十四、辅助工具

14.1 sizeof()

 

 

函数部分

 

十五、数字 I/O

15.1 pinMode()

15.2 digitalWrite()

15.3 digitalRead()

十六、模拟 I/O

16.1 analogReference()

16.2 analogRead()

16.3 analogWrite()  PWM

十七、高级 I/O

17.1 tone()

17.2 noTone()

17.3 shiftOut()

17.4 shiftIn()

17.5 pulseIn()

十八、时间

18.1 millis()

18.2 micros()

18.3 delay()

18.4 delayMicroseconds()

十九、数学运算

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()

二十、三角函数

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()

二十一、随机数

21.1 randomSeed()

21.2 random()

二十二、位操作

22.1 lowByte()

22.2 highByte()

22.3 bitRead()

22.4 bitWrite()

22.5 bitSet()

22.6 bitClear()

22.7 bit()

二十三、设置中断函数

23.1 attachInterrupt()

23.2 detachInterrupt()

二十四、开关中断

24.1 interrupts()(中断)

24.2 noInterrupts()(禁止中断)

二十五、通讯

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

二十六、USB(仅适用于 Leonardo 和 Due)

26.1 Mouse(键盘)

26.2 Keyboard(鼠标)

以下是示例部分含详细注解

 

结构部分

一、结构

 

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.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)

警告:

注意使用赋值运算符的情况(如 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 -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 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.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

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.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.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)

警告

注意使用赋值运算符的情况(如 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.5 =(大于等于)

详见5.1 ==(等于)

 

六、布尔运算符

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 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 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

暂无说明。 

 

二十六、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()



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3