Arduino教程——编写Arduino类库(2)
Arduino教程——使用和编写类库 http://www.arduino.cn/thread-22293-1-1.htmlArduino教程——通过 库管理器 添加库 http://www.arduino.cn/thread-31719-1-1.html
Arduino教程——手动添加库并使用 http://www.arduino.cn/thread-31720-1-1.html
Arduino教程——编写Arduino类库(1) http://www.arduino.cn/thread-31721-1-1.html
Arduino教程——编写Arduino类库(2) http://www.arduino.cn/thread-31722-1-1.html
Arduino教程——编写Arduino类库(3) http://www.arduino.cn/thread-31723-1-1.html
上一篇:Arduino教程——编写Arduino类库(1) http://www.arduino.cn/thread-31721-1-1.html
编写头文件与源文件
通常,一个类库中包含两种后缀的文件:.h文件,和.cpp文件。
.h文件称作头文件,其用于声明类库及其成员;.cpp文件称作源文件,其用于定义类库及其成员。
编写头文件
首先我们需要建立一个SR04.h的头文件,在SR04.h这个文件中我们要声明一个SR04超声波类。
类的声明方法如下:
class SR04 {
public:
private:
};通常一个类可以包含两个部分——public和private。public中声明的函数和变量可以被外部程序所访问,而private中声明的函数和变量,只能从这个类的内部访问。
接着,根据我们的实际需求来设计这个类,SR04类的结构如图4-4所示。
图4-4 SR04类结构图
它包含两个成员函数和三个成员变量。
SR04() 函数是一个与类同名的构造函数,用于初始化对象。我们需要在public中声明这个函数。声明如下:
SR04(int TrigPin,int EchoPin);这个构造函数用来替代之前我们使用的void init_SR04(int TrigPin,int EchoPin) 函数。需要注意的是构造函数必须与类同名,且不能有返回类型。
我们还需要一个GetDistance函数来获取并处理超声波传感器返回的信息
float GetDistance();这个函数用来替代我们之前使用的 float GetDistance (int TrigPin,int EchoPin) 函数
还有一些程序运行过程中的函数或变量,用户在使用时并不会接触到他们,我们可以将其放在private部分中声明:
// 记录SR04使用的引脚
int Trig_pin;
int Echo_pin;
// 记录SR04返回的距离
float distance;
完整的SR04.h代码如下:
#ifndef SR04_H
#define SR04_H
#include "Arduino.h"
class SR04 {
public:
SR04(int TrigPin,int EchoPin);
float GetDistance();
private:
int Trig_pin;
int Echo_pin;
float distance;
};
#endif
预处理命令
以“#”开头的语句,为预处理命令。之前我们包含文件使用的#include,及常量定义时使用的#define均为预处理命令。
预处理命令并不是C/C++语言的组成部分,编译器不会直接对其进行编译,而是在编译前,系统会预先处理这些命令。
宏定义
如你的程序中用#define COL 1112 定义了一个名为COL的常量,实际在编译前,系统会将你代码中所有的COL替换为1112,再对替换后的代码进行编译。
这种定义方式称之为宏定义。即使用一个特定的标识符来代表一个字符串。其一般形式为:
#define 标识符字符串
在Arduino中,我们常用到HIGH、LOW、INPUT、OUTPUT等参数、及圆周率PI等常量都是通过宏的方式定义的。
文件包含若程序中使用#include包含了一个文件,例如#include <EEPROM.h>,在预处理时系统会将该命令替换成EEPROM.h文件中的实际内容,再对替换后的代码进行编译。文件包含命令的一般形式为:
#include<文件名>或
#include“文件名”两种形式的实际效果是一样的,只是使用<文件名>形式时,系统会优先在Arduino库文件中寻找目标文件,若没有找到,系统会再到当前Arduino项目的项目文件夹中查找;而使用“文件名”形式时,系统会优先在你的Arduino项目文件中查找目标文件,若没有找到,再查找Arduino库文件。
条件编译回到SR04.h,在其中,你会看到以下代码:
#ifndef SR04_H
#define SR04_H
.
.
.
#endif
其中
#ifndef标识符
程序段
#endif为条件编译命令。#ifndef SR04_H会查找标识符SR04_H是否在程序的其他位置被#define定义过。若没有被定义过,则定义该标识符。这个写法主要为了防止重复的包含某文件,避免程序编译出错。
编写源文件
接着,我们还要建立一个SR04.cpp源文件。在SR04.cpp文件中,我们需要写出了头文件中声明的成员函数的具体实现代码。
完整代码如下:
#include "Arduino.h"
#include "SR04.h"
SR04::SR04(int TP, int EP)
{
pinMode(TP,OUTPUT);
pinMode(EP,INPUT);
Trig_pin=TP;
Echo_pin=EP;
}
float SR04::GetDistance()
{
digitalWrite(Trig_pin, LOW);
delayMicroseconds(2);
digitalWrite(Trig_pin, HIGH);
delayMicroseconds(10);
digitalWrite(Trig_pin, LOW);
float distance = pulseIn(Echo_pin, HIGH) / 58.00;
return distance;
}
域操作符我们在SR04.h文件中声明了SR04类及其成员,在SR04.cpp中定义该函数的实现方法。在类声明以外定义成员函数时,需要使用域操作符::,说明该函数作用于SR04类。
下一篇:Arduino教程——编写Arduino类库(3) http://www.arduino.cn/thread-31723-1-1.html
奈何大神,逗人啊 好贴!! 本帖最后由 xiaoqiyli 于 2018-5-28 15:23 编辑
不错、感谢~ 大神,哪我编写库就一定要用类的形式吗 a10520596 发表于 2018-8-2 15:40
大神,哪我编写库就一定要用类的形式吗
不一定 写的不错,1毛花的值 为什么收费!! han88833162 发表于 2018-11-15 15:11
为什么收费!!
要是楼主这么多精品贴放到CSDN不知要收多少钱;P;P 回复后才可以支付