Arduino教程——编写Arduino类库(2)-Arduino中文社区 - Powered by Discuz! Archiver

奈何col 发表于 2016-12-7 23:49

Arduino教程——编写Arduino类库(2)

Arduino教程——使用和编写类库   http://www.arduino.cn/thread-22293-1-1.html
Arduino教程——通过 库管理器 添加库 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



ezwyj 发表于 2016-12-8 09:10

奈何大神,逗人啊

gangguo 发表于 2016-12-13 21:43

好贴!!

xiaoqiyli 发表于 2018-5-28 15:21

本帖最后由 xiaoqiyli 于 2018-5-28 15:23 编辑

不错、感谢~

a10520596 发表于 2018-8-2 15:40

大神,哪我编写库就一定要用类的形式吗

奈何col 发表于 2018-8-2 20:31

a10520596 发表于 2018-8-2 15:40
大神,哪我编写库就一定要用类的形式吗

不一定

sfdsl 发表于 2018-10-19 09:18

写的不错,1毛花的值

han88833162 发表于 2018-11-15 15:11

为什么收费!!

chunhl 发表于 2019-7-28 10:20

han88833162 发表于 2018-11-15 15:11
为什么收费!!

要是楼主这么多精品贴放到CSDN不知要收多少钱;P;P

liutiansong 发表于 2019-7-29 09:36

回复后才可以支付
页: [1] 2 3
查看完整版本: Arduino教程——编写Arduino类库(2)