弄完上个20天后,突然懈怠了,今天开始重新20天
Arduino使用的语言就是C语言
以下内容是建立在学过一定的C语言的基础上,我们只是用来学习Arduino的函数与C语言的不同之处,还有和89C51不同的地方。
1、程序结构
Arduino程序最基本结构必要代码如下:、
这段程序我们可以看做两部分,由两个void函数组成,分别称为“初始化”和“循环体”。当我们在Arduino中运行程序时,我们先运行初始化部分,然后运行循环体部分,之后便一直在循环体中重复运行。
也就是说,我们在编程过程中,可以把需要运行一次的程序放入初始化部分,把需要循环运行的代码放入循环体部分。
举例:LED闪烁示例
void setup() {
pinMode(13,OUTPUT); //将数字输出口13设置为电平输出模式,执行一次即可完成设置
}
void loop() {
digitalWrite(13,HIGH); //将数字输出口13设置为高电平,LED将会亮起
delay(1000); //等待一段时间
digitalWrite(13,LOW); //将数字输出口13设置为低电平,LED将会熄灭
delay(1000); //等待一段时间
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
注意:初始化和循环体部分即使不需要用到其中的功能,也不能将其删去,可以在大括号内留空。循环体部分虽然可以一直重复运行,但也可以通过代码停止运行 。
2、变量定义
上面的例子中,我们对输出口13进行了多次操作,在编程中一般会把需要重复使用多次的内容用变量来定义,使用的时候在需要的地方用变量名表示,适当使用变量能让程序更简便和灵活。
把上面的例子改一下,把13放入名为“n”的变量中
int n =13; //定义变量,并将数字输出口的值“13”放入变量
void setup() {
pinMode(n,OUTPUT); //将数字输出口13设置为电平输出模式,执行一次即可完成设置
}
void loop() {
digitalWrite(n,HIGH); //将数字输出口13设置为高电平,LED将会亮起
delay(1000); //等待一段时间
digitalWrite(n,LOW); //将数字输出口13设置为低电平,LED将会熄灭
delay(1000); //等待一段时间
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
这个地方和C语言的一模一样,就不再赘述了
3、 函数和类库
pinMode():设置某个数字输出口的电平模式;
digitalWrite():设置某个数字输出口的电平;
digitalWrite(参数pin,参数value),pin:设置一个引脚;value:电平,常量为HIGH或者LOW;
delay():让程序暂停一段时间,单位为ms;
Serial类库函数begin():设置串口通信的波特率;
Serial类库函数println():通过串口发送一行字符;
例如
void setup(){
Serial.begin(9600); //设置通信波特率
}
void loop(){
Serial.println("Hello,PC!"); //发送“Hello,PC!”
delay(1000);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
这类函数在名称中间有“.”号分隔,点号前面表示一个对象(这里是默认的串口对象Serial),后面表示一个函数(也称为“方法”)。Serial对象是由Serial类库创建的,由于这个类库是被Arduino默认添加包含的,在编译过程中会自动加入,所以不需要用语句在程序中指定加入哪个类库。
4、自定义函数
函数和变量一样,程序编写者可以自定义需要的函数。虽然Arduino语言中已经有了基本能解决大部分需要的函数,但对于特殊的实例,有可能需要用到能达到特定功能的函数。
例如,有一套装置如图4-5所示,6个LED从左至右接7~2号引脚。其程序在执行开始,会得到3个变量LED1、LED2、LED3,为1~6之间的数字,现在需要编写程序的主要部分,将所给变量值对应序号的LED点亮。
我们只需要switch语句或者数组就可以解决,但是在Arduino中并没有适合的函数,那么我们只能自定义了。
定义这个函数的代码如下:
void LED(int one,int two,int thr){
int leds[]={0,7,6,5,4,3,2} //数组下标1~6分别对应7~2,用于序号值对应引脚值
pinMode(7,OUTPUT);
pinMode(6,OUTPUT);
pinMode(5,OUTPUT);
pinMode(4,OUTPUT);
pinMode(3,OUTPUT);
pinMode(2,OUTPUT); //以上代码设置2~7号因及哦啊为电平输出模式
digitalWrite(leds[one],HIGH);
digitalWrite(leds[two],HIGH);
digitalWrite(leds[two],HIGH);//设置各个要亮的LED对应引脚为高电平
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
将这段函数的代码放入程序后,在程序初始化或循环体部分使用这个函数
LED (LED1,LED2,LED3);
便可以实现点亮对应小灯的效果
自定义函数的代码要注意以下两点:
- 不能放在初始化或循环体部分内。
- 只能与初始化或循环体部分并列放置,一般是后面。
大致如下
void setup(){
}
void loop(){
}
void LED(int one,int two,int thr){
}
- 1
- 2
- 3
- 4
- 5
- 6
自定义函数在程序中可以按需要定义,没有定义数量限制,其定义语法如下:
数值类型 函数名(参数类型 参数名,参数类型 参数名······){
函数内部代码
}
- 1
- 2
- 3
- 数值类型可以设置函数输出值类型,void表示没有输出值。
- 函数名命名规则同变量名命名一致。
- 参数可以按需要设置,可以设置多个或者不设置,设置参数规则同变量设置语法,但参数之间不能用分号分隔,要用逗号分隔。
学了自定义函数后,我们可以发现,初始化和循环体两部分的语法和自定义函数的语法是一致的。其实,初始化部分和循环体部分就是定义两个类型为void的并且没有参数的函数,也可以分别称二者为:
- setup()函数;
- loop()函数;
Arduino运行时其实就是运行一遍setup函数和其他的自定义函数,然后循环运行loop函数,编写Arduino程序的过程就是把一系列语句整合入setup函数和loop函数中。
前面的函数都是没有输出值,也就是C语言中所谓的返回值,这里的输出值使用方法和C语言中一样
return 输出的数据;
这个语句可以在函数中的任意位置使用,但使用后意味着这个函数运行结束了。
例如下面的自定义函数的输出数据会在串口监视器中显示
void setup(){
Serial.begin(9600); //设置通行波特率
}
void loop(){
int value=myfuction();
Serial.println(value);
delay(1000);
}
int myfuction(){
int val=9;
return val;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
5、 自定义类库
类库是由一系列变量和函数构成的集合,用于将复杂的功能封装成能简单调用的对象。类库初始化后叫做实例,编程中操作的各种实例称为对象。为了方便区分类库内的变量和函数与类库外的,我们把类库中的变量叫做属性,函数称为方法。
类库封装了一系列方法或者一些底层编程,所以使用起来非常简便且容易移植。IDE自带类库不需要安装即可调用,如果要用第三方的类库,则需要导入才可以使用。
导入流程:
- 获得类库大包文件
- 在IDE界面Sketch(草图)菜单下展开“导入库”子菜单
- 单机“添加库”选项,然后在弹出的窗口中选择类库安装。
以下为一个简单的摩斯电码程序
int pin=13;
void setup ()
{
pinMode(pin,OUTPUT);
}
void loop()
{
dot();dot();dot();
dash();dash();dash();
dot();dot();dot();
delay(3000);
}
void dot()
{
digitalWrite(pin,HIGH);
delay(250);
digitalWrite(pin,LOW);
delay(250);
}
void dash()
{
digitalWrite(pin,HIGH);
delay(100);
digitalWrite(pin,LOW);
delay(250);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
该代码中的以下部分可以整理到类库:
- 用于闪烁的dot()和dash()两个功能函数;
- 用于指定使用哪个管脚的灯的pin变量;
- 初始化管脚的pinMode()函数调用。
一个类库至少包含两个文件:头文件(扩展名为“.h”)和源代码文件(扩展名为“.cpp”)。头文件包含类库的声明,即类库的功能说明列表,源代码文件包含类库的实际实现。
我们不妨给上面的类库起一个类库名Morse,那么需要在代码库目录里(项目文件下的libraries目录),创建一个名为“Morse”的子目录用于放置类库文件。新建头文件命名为“”。
1.头文件
头文件核心内筒,是一个封装了成员函数与相关变量的类声明:
class Morse //声明类和类名
{
public; //表明以下为类库内、外部方可调用的公共成分
Morse(int pin); //构造函数
void dot();
void dash();
private; //表明以下为类库内部方可调用的私有成分
int _pin;
}; //注意分好“:”不能忽略
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
类里的函数与变量,其访问权限可以使public,也可以是private。类有个特殊的函数——构造函数,用于类实例化时执行一些工作,如不需要可以省略。构造函数的数据类型与类相同,且没有返回值。
头文件里还有些其他杂项。
如,为了使用标准类型和Arduino语言的常量,编写库时需要include导入这些类库(IDE会在编译时自动为ino格式程序文件加上这些#include语句,类库等文件则需要手动编写#include语句)例如
#include ""
这里和89c52那边有点不一样,那边是#include<>
,注意一下就好。
最后,为了防止多次引用头文件造成的各种问题,还需要封装整个头文件结构:
#ifndef Morse_h
#define Morse_h
//类库声明主题
#endif
- 1
- 2
- 3
- 4
最终完成的头文件内容如下:
#ifndef Morse_h
#define Morse_h
#include ""
class Morse
{
public;
Morse(int pin);
void dot();
void dash();
private;
int _pin;
};
#endif
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
2. 源代码文件
开头仍是一些#include语句。这些语句让下面的程序能够使用Arduino的标准函数和刚才在中声明的类。
#include ""
#include ""
- 1
- 2
接下来是构造函数
明天再说啦