查看: 13290|回复: 21

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

[复制链接]
  • TA的每日心情
    郁闷
    2018-12-6 22:21
  • 签到天数: 48 天

    [LV.5]常住居民I

    发表于 2016-12-7 23:49 | 显示全部楼层 |阅读模式
    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

    [sf]
    编写头文件与源文件
    通常,一个类库中包含两种后缀的文件:.h文件,和.cpp文件。
    .h文件称作头文件,其用于声明类库及其成员;.cpp文件称作源文件,其用于定义类库及其成员。

    编写头文件

    首先我们需要建立一个SR04.h的头文件,在SR04.h这个文件中我们要声明一个SR04超声波类。

    类的声明方法如下:
    通常一个类可以包含两个部分——public和private。public中声明的函数和变量可以被外部程序所访问,而private中声明的函数和变量,只能从这个类的内部访问。

    接着,根据我们的实际需求来设计这个类,SR04类的结构如图4-4所示。

    图4-4 SRO4 类结构图

    图4-4 SRO4 类结构图
    4-4 SR04类结构图

    它包含两个成员函数和三个成员变量。

    SR04() 函数是一个与类同名的构造函数,用于初始化对象。我们需要在public中声明这个函数。声明如下:
    这个构造函数用来替代之前我们使用的void init_SR04(int TrigPin,int EchoPin) 函数。需要注意的是构造函数必须与类同名,且不能有返回类型。


    我们还需要一个GetDistance函数来获取并处理超声波传感器返回的信息
    这个函数用来替代我们之前使用的 float GetDistance (int TrigPin,int EchoPin) 函数

    还有一些程序运行过程中的函数或变量,用户在使用时并不会接触到他们,我们可以将其放在private部分中声明:

    kittenblock中小学创客名师推荐的图形化编程软件

    
    // 记录SR04使用的引脚
    int Trig_pin;
    int Echo_pin;
    // 记录SR04返回的距离
    float distance;

    完整的SR04.h代码如下:

    kittenblock中小学创客名师推荐的图形化编程软件

    
    #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,再对替换后的代码进行编译。
    这种定义方式称之为宏定义。即使用一个特定的标识符来代表一个字符串。其一般形式为:

    在Arduino中,我们常用到HIGH、LOW、INPUT、OUTPUT等参数、及圆周率PI等常量都是通过宏的方式定义的。

    文件包含
    若程序中使用#include包含了一个文件,例如#include <EEPROM.h>,在预处理时系统会将该命令替换成EEPROM.h文件中的实际内容,再对替换后的代码进行编译。
    文件包含命令的一般形式为:
    两种形式的实际效果是一样的,只是使用<文件名>形式时,系统会优先在Arduino库文件中寻找目标文件,若没有找到,系统会再到当前Arduino项目的项目文件夹中查找;而使用“文件名”形式时,系统会优先在你的Arduino项目文件中查找目标文件,若没有找到,再查找Arduino库文件。

    条件编译
    回到SR04.h,在其中,你会看到以下代码:

    kittenblock中小学创客名师推荐的图形化编程软件

    
    #ifndef SR04_H
    #define SR04_H
    .
    .
    .
    #endif

    其中
    为条件编译命令。#ifndef SR04_H会查找标识符SR04_H是否在程序的其他位置被#define定义过。若没有被定义过,则定义该标识符。这个写法主要为了防止重复的包含某文件,避免程序编译出错。




    编写源文件


    接着,我们还要建立一个SR04.cpp源文件。在SR04.cpp文件中,我们需要写出了头文件中声明的成员函数的具体实现代码。


    完整代码如下:

    kittenblock中小学创客名师推荐的图形化编程软件

    
    #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类。

    [/sf]
    下一篇:Arduino教程——编写Arduino类库(3) http://www.arduino.cn/thread-31723-1-1.html



  • TA的每日心情
    擦汗
    2017-7-11 15:51
  • 签到天数: 7 天

    [LV.3]偶尔看看II

    发表于 2016-12-8 09:10 | 显示全部楼层
    奈何大神,逗人啊

    该用户从未签到

    发表于 2018-5-28 15:21 | 显示全部楼层
    本帖最后由 xiaoqiyli 于 2018-5-28 15:23 编辑

    不错、感谢~
  • TA的每日心情
    奋斗
    2018-7-31 09:23
  • 签到天数: 4 天

    [LV.2]偶尔看看I

    发表于 2018-8-2 15:40 | 显示全部楼层
    大神,哪我编写库就一定要用类的形式吗

    点评

    不一定  详情 回复 发表于 2018-8-2 20:31
  • TA的每日心情
    郁闷
    2018-12-6 22:21
  • 签到天数: 48 天

    [LV.5]常住居民I

     楼主| 发表于 2018-8-2 20:31 | 显示全部楼层
    a10520596 发表于 2018-8-2 15:40
    大神,哪我编写库就一定要用类的形式吗

    不一定

    该用户从未签到

    发表于 2018-10-19 09:18 | 显示全部楼层
    写的不错,1毛花的值
  • TA的每日心情
    开心
    2018-11-15 15:13
  • 签到天数: 1 天

    [LV.1]初来乍到

    发表于 2018-11-15 15:11 | 显示全部楼层
    为什么收费!!
  • TA的每日心情
    奋斗
    2019-7-28 10:09
  • 签到天数: 2 天

    [LV.1]初来乍到

    发表于 2019-7-28 10:20 | 显示全部楼层

    要是楼主这么多精品贴放到CSDN不知要收多少钱
  • TA的每日心情
    开心
    2019-7-29 09:27
  • 签到天数: 1 天

    [LV.1]初来乍到

    发表于 2019-7-29 09:36 | 显示全部楼层
    回复后才可以支付
    您需要登录后才可以回帖 登录 | 立即注册  

    本版积分规则

    热门推荐

    Blynk与m5stack basic以及uiflow的交互玩法
    Blynk与m5stack basic以及
    Blynk与m5stack basic以及uiflow的交互玩法 [准备工作我们假设玩家已经熟悉下面的准备
    求助oled显示屏 中间有一条不显示 折腾好久没明白是咋回事
    求助oled显示屏 中间有一
    以下是源代码,课程做东西需要,卡在了这一环节,求大神指教(跪 #include #i
    中文 字库 的8针 OLED 12864模块 arduino
    中文 字库 的8针 OLED 128
    屏幕电路SPI连线: 中文字库OLED Arduino UNO GND GND
    DIY X-Y 平面激光器
    DIY X-Y 平面激光器
    DIY X-Y 平面激光器 总成本不到50元,性能一点不比市面的差. Arduino UNO x1 舵机 x2
    【干货分享】mega2560原理图PCB图纸altium designer18
    【干货分享】mega2560原理
    分享一下mega2560的板子 AD版本 **** 本内容被作者隐藏 **** ergo
    Copyright   ©2015-2016  Arduino中文社区  Powered by©Discuz!   
    快速回复 返回顶部 返回列表