编写Arduino支持的C++类库

以下为摘抄的例子,已经亲自验证过,例子是正确的

我们在上一讲中实现了一个TN901红外温度传感器51程序到Arduino程序的转换,如果代码越来越多这样程序的可维护性会随之降低,也不适合团度开发。我们应该把常用的文件封装成C++库,这样在复用的时候就会方便很多。
首先让我们来看下官方的C++类库是怎样的结构,以官方的LCD类库为例,如下图所示:

image

上面的文件大体是这样的结构:

文件名文件类型文件说明
keywords.txtkeywords.txtArduino库色标文件
LiquidCrystal.h.hC++头文件
LiquidCrystal.cpp.cppC++程序文件

以下几种文件的作用如下:

.h 头文件:头文件作为一种包含功能函数、数据接口声明的载体文件,用于保存程序的声明(declaration),而定义文件用于保存程序的实现 (implementation)。

.cpp 文件:C++程序源文件主要的逻辑写在这里。

keywords.txt 文件:用来定义库在程序中显示关键字的颜色。

首先我们来尝试下头文件的编写

#ifndef TH901_H  //根据条件进行编译
#define TH901_H//我们在这中间添加程序主体的代码部分,首先来添加程序的头文件,需要引用什么都可以加进来
#include <inttypes.h> //引用相关的头文件//之后我们可以预定义一些需要的常量,这样维护起来比较方便,如果常量值改变只要统一修改这里就好
#define TN901_OTADDRESS 0x4c
#define TN901_ETADDRESS 0x66
#define TN901_ENDADDRESS 0x0d//接下来我们来定义变量和声明程序的方法,需要外部调用和访问的就声明成public,不需要外部访问的就声明为privateclass TN901     //定义类主体及类名
{
public:  //以下定义为公共方法
short ET;   //环境温度输出
short OT;   //目标温度输出
void Init(int TN_Data,int TN_Clk,int TN_ACK); //程序初始化
void Read();  //读取方法
void ReadData(char flag); //读取指定地址的数据
int  GetData(); //获取数据
private:  //以下定义为私有方法
int _dataPin;  //数据引脚
int _clkPin;   //时钟引脚
int _ackPin;   //反馈引脚
unsigned char  Data[5];  //数据数组
};
#endif//程序结束

这样我们一个头文件就写好了.

接下来我们来书写程序的主体,就是CPP文件。

//首先我们引用已经写好的程序头文件
#include "TN901.h"
//之后我们引用一些需要的库文件
#include "TN901.h"
#include <stdio.h>
#include <string.h>
#include <inttypes.h>
#include "Arduino.h"
然后我们逐一实现在头文件中定义的方法,注意类型要与定义类型相对应。所有的方法都要属于你定义的类名,格式如下

类名::方法名

另外i啊我们要为程序的封装考虑程序应有的结构,总之是怎样使你的库使用起来最方便,在一般的逻辑中尽量减少调用的次数。我们可以把程序的逻辑分割为几个部分来书写。如:

1.初 始 化
2.实现功能
3.显示数据

当然这个逻辑以具体的程序为准。

我们来尝试写第一个初始化的方法,这样我们可以自己定义程序的端口。

//初始化TN901传感器
void TN901::Init(int TN_Data,int TN_Clk,int TN_ACK)
{
//定义私有端口
_dataPin=TN_Data;
_clkPin=TN_Clk;
_ackPin=TN_ACK;pinMode(_clkPin, INPUT);
pinMode(_ackPin, OUTPUT);
digitalWrite(_ackPin,HIGH);
}

然后我们书写程序的主要逻辑部分
//读取数据
void TN901::Read()
{
digitalWrite(_ackPin,LOW);
ReadData(TN901_OTADDRESS);//目标温度的第一个字节为0x4c
if((Data[0]==TN901_OTADDRESS)&&
(Data[4]==TN901_ENDADDRESS))//每帧的最后一个字节为0x0d
{
GetData_OT();
}delay(1); //等待1毫秒digitalWrite(_ackPin,LOW);
ReadData(TN901_ETADDRESS);//环境温度的第一个字节为0x66if((Data[0]==TN901_ETADDRESS)&&
(Data[4]==TN901_ENDADDRESS))//每帧的最后一个字节为0x0d
{
GetData_ET();
}
}


最后我们逐一实现程序的运算过程
//读取数据
void TN901::ReadData(char flag)
{
char i,j,k;
byte BitState = 0;          //每次发七帧
for(k=0;k<7;k++)
{
for(j=0;j<5;j++)        //每帧5个字节
{
for(i=0;i<8;i++)
{
int temp= digitalRead(_clkPin);
while(temp)
{
temp = digitalRead(_clkPin);
}
temp= digitalRead(_clkPin);
BitState= digitalRead(_dataPin);
Data[j]= Data[j]<<1;
Data[j]= Data[j]|BitState;while(!temp)
{
temp = digitalRead(_clkPin);
}
}
}
if(Data[0]==flag)  k=8;
}digitalWrite(_ackPin,HIGH);
}//计算环境温度
void TN901::GetData_ET()
{
ET=(Data[1]<<8)|Data[2];
ET = int(((float)ET/16 - 273.15)*100);
}//计算目标温度
void TN901::GetData_OT()
{
OT=(Data[1]<<8)|Data[2];
OT = int(((float)OT/16 - 273.15)*100);
}


之后我们来尝试为我们的库编写一个范例程序来测试我们的程序是否运行正常。
#include <TN901.h>  //引用库文件
TN901 tn;           //实 例 化
void setup()
{
Serial.begin(9600);
tn.Init(7,9,8);  //初 始 化
}void loop()
{
tn.Read();        //数据读取
SerialValue();
delay(200);
}void SerialValue()
{
Serial.print("OT: ");
Serial.print(tn.OT, DEC);  //输出目标温度
Serial.println(" C");
Serial.print("ET: ");
Serial.print(tn.ET, DEC);  //输出环境温度
Serial.println(" C");
}

好了,我们看到虽然我们花了一点时间编写了库文件,但是在我们使用程序的时候可以非常方便的调用,而且这样逻辑会比较清晰。呵呵。

最后送给大家一个小礼物,就是如何为我们的库编写色标文件,色标文件就是定义你的库中的方法在编译器中显示的颜色
没有色标文件的库显示起来是这样的:

image

我们可以看到库文件的类名和方法名都是黑色的这样看起来不是很清楚。加上色标文件之后是这样的

image

我们可以看到TN901这样的类名都被加亮了这样看起来要清楚许多。

实现这个需要定义一个色标文件放在库文件的目录中,格式如下

#######################################
# Syntax Coloring Map For 你的类名
##############################################################################
# Datatypes (KEYWORD1) 数据类型关键字
#######################################TN901        KEYWORD1#######################################
# Methods and Functions (KEYWORD2) 方法类型关键字
#######################################Init        KEYWORD2
Read        KEYWORD2
ReadData        KEYWORD2
GetData        KEYWORD2#######################################
# Constants (LITERAL1)  常量类型关键字
#######################################ET        LITERAL1
OT        LITERAL1

这样我们的色标文件就写好了,我们把它保存成文件名为keywords.txt的文件放在库文件目录下就可以了。

当我们些库文件全部做好了之后我们就可以把这些文件放在,这样的目录下

energia:energia-0101E0008\hardware\msp430\libraries\
arduino:arduino-1.0.1-windows\arduino-1.0.1\libraries\

这样当你重新打开官方编译器的时候可以看到如下的内容

image

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/255293.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【机器学习实战】——常见函数积累

目录 第二章 k近邻算法 1、array.sum(axies 1) : 2、array.argsort(axies0/1) 3、array.tile(mat,(m,n)) 4、dict.get(key,value) 5、sorted函数 6、string.strip()函数 7、string.split() 8、scatter&#xff08;&#xff09;函数 9、min()&max() 10、enumera…

安装oracle 11g 客户端,检查过程中报物理内存不足的解决

今早接到同事电话&#xff0c;说安装oracle 11g客户端的时候&#xff0c;在检查先决条件的时候&#xff0c;报错&#xff0c;说内存不足&#xff0c;但是本机的内存是2G&#xff0c;肯定够用&#xff1a;如图&#xff1a; 找了一圈&#xff0c;原来Oracle执行先决条件检查是依赖…

Codeforces Round #401 (Div. 2) D. Cloud of Hashtags

题目链接&#xff1a;D. Cloud of Hashtags 题意&#xff1a; 给你n个字符串&#xff0c;让你删后缀&#xff0c;使得这些字符串按字典序排列&#xff0c;要求是删除的后缀最少 题解&#xff1a; 由于n比较大&#xff0c;我们可以将全部的字符串存在一个数组里面&#xff0c;然…

史陶比尔机器人的 LLI (Low Level Interface)

史陶比尔机器人的 LLI &#xff08;Low Level Interface&#xff09; 史陶比尔机器人拥有 Low Level Interface (LLI)接口选项. 在CS8C控制器的时代&#xff0c;LLI 接口仍然可用。这是一个选项接口。.这是除了VAL3编程语言之外的替代操作系统。通过C程序替代你的程序。 这里的…

HALCON示例程序check_bottle_crate.hdev啤酒箱内酒瓶数检测

HALCON示例程序check_bottle_crate.hdev啤酒箱内酒瓶数检测 示例程序源码&#xff08;加注释&#xff09; 获取系统关于“空白区域储存的设置” get_system (‘store_empty_region’, StoreEmptyRegion)系统“空白区域储存”设置为 ‘false’ set_system (‘store_empty_regi…

单片机平台的最小偏差圆弧插补算法

在CNC机床的G代码中&#xff0c;最常见的有G0、G1、G2、G3代码&#xff0c;分别表示直线和圆弧插补&#xff0c;直线插补对于单片机来说&#xff0c;比较容易实现&#xff0c;只需要将位移增量转换为脉冲增量然后输出给步进电机就可以了&#xff0c;但对于圆弧插补&#xff0c;…

【转】JS跨域(ajax跨域、iframe跨域)解决方法及原理详解(jsonp)

这里说的js跨域是指通过js在不同的域之间进行数据传输或通信&#xff0c;比如用ajax向一个不同的域请求数据&#xff0c;或者通过js获取页面中不同域的框架中(iframe)的数据。只要协议、域名、端口有任何一个不同&#xff0c;都被当作是不同的域。 下表给出了相对http://store.…

Lua基本语法-lua与C#的交互(相当简单详细的例子)

lua脚本 与 C#的交互 本文提供全流程&#xff0c;中文翻译。Chinar坚持将简单的生活方式&#xff0c;带给世人&#xff01;&#xff08;拥有更好的阅读体验 —— 高分辨率用户请根据需求调整网页缩放比例&#xff09; 1Lua And C# —— Lua 和 C#的交互准备工作 2C# Create Lu…

漫谈程序员系列:千奇百怪的程序员

干开发时间长了&#xff0c;遇见好多好玩儿的程序员。 看看你躺枪了没。 博客之星评选&#xff0c;点击投我一票&#xff0c;谢谢。投过了也可以点哦&#xff0c;每天都可以投投一票。 留一手 有个哥们儿&#xff0c;在一合资公司做程序员&#xff0c;能力挺强&#xff0c;写…

SCARA机器人与 DELTA机器人

1、SCARA机器人SCARA&#xff08;Selective Compliance Assembly Robot Arm&#xff0c;中文译名&#xff1a;选择顺应性装配机器手臂&#xff09;是一种圆柱坐标型的特殊类型的工业机器人。1978年&#xff0c;日本山梨大学牧野洋发明SCARA&#xff0c;该机器人具有四个轴和四个…

一直以来都没直视的轮播-_-

一直以来做项目碰到轮播图我都是去网站上找现成插件拿来用&#xff0c;现成的插件1是省时间&#xff0c;拿来改改尺寸改改参数就能直接用&#xff0c;2是现在的插件确实很强大&#xff0c;对于我一个刚刚学习前端的人来说&#xff0c;牛人写的轮播我看懂也要花些功夫&#xff0…

HALCON示例程序circles.hdev边界轮廓的圆形拟合

HALCON示例程序circles.hdev边界轮廓的圆形拟合 小哥哥小姐姐觉得有用点个赞呗&#xff01; 示例程序源码&#xff08;加注释&#xff09; 读入图片 read_image (Image, ‘double_circle’)窗口初始化 dev_close_window () get_image_size (Image, Width, Height) dev_open…

asp.net 微信企业号办公系统-流程设计--保存与发布

如果流程未设计完时可以先保存&#xff0c;以后再打开接着设计。点击工具栏上的保存按钮即可保存当前流程设计: 如果下次要接着设计&#xff0c;则可以打开该流程继续设计&#xff1a; 如果流程设计完成&#xff0c;可以点击安装按钮来发布流程&#xff0c;流程安装成功后即加入…

Canny边缘检测算法原理及其VC实现详解(二)

3、 Canny算法的实现流程 由于本文主要目的在于学习和实现算法&#xff0c;而对于图像读取、视频获取等内容不进行阐述。因此选用OpenCV算法库作为其他功能的实现途径&#xff08;关于OpenCV的使用&#xff0c;作者将另文表述&#xff09;。首先展现本文将要处理的彩色图片。 …

IDEA注册jar包使用和常用插件

IDEA注册jar包使用 点击获取下载地址或生成注册码 一、安装完成后&#xff0c;先不启动&#xff0c;首先如下图修改相关的地方。 二、启动IDEA&#xff0c;并且激活IDEA IDEA插件仓库 IntelliJ IDEA Plugins 一、Maven Helper 我一般用这款插件来查看maven的依赖树。在不使用此…

Android Monkey压力测试

一. JAVA环境的搭建 安装jdk-8u151-windows-x64,可以到官网或者应用中心下载.JAVA环境变量的搭建: 在"我的电脑"-"属性"-"高级"-"环境变量"中,点击新建,填写变量名为JAVA_HOME,变量值为JAVA安装的路径.在系统变量中找到Path,点击编辑,…

bzoj 4517: [Sdoi2016]排列计数

4517: [Sdoi2016]排列计数 Time Limit: 60 Sec Memory Limit: 128 MBSubmit: 637 Solved: 396[Submit][Status][Discuss]Description 求有多少种长度为 n 的序列 A&#xff0c;满足以下条件&#xff1a;1 ~ n 这 n 个数在序列中各出现了一次若第 i 个数 A[i] 的值为 i&#x…

自制反汇编逆向分析工具 迭代第六版本 (五)

本工具从最初版的跳转分布图只为了更直观地分析反汇编代码的分支结构&#xff0c;第三版开始对直观图进行逆向分支代码的输出&#xff0c;第四版对分支输出策略的一些探索&#xff0c;第五版结合之前的探索进行改进。第六版在现在功能的基础上进行增强&#xff0c;利用第六版&a…

centos7搭建FTP服务器

1.   使用 yum 安装 vsftpd&#xff1a;yum install -y vsftpd 2.  启动 VSFTPD&#xff1a;systemctl start vsftpd.service 3.  启动后可监听到21端口&#xff1a;netstat -nltp | grep 21 4.  配置FTP权限&#xff1a;&#xff08;vsftpd.conf&#xff0c;修改前先备…

教你如何剖析源码

一、源码阅读需求 在学习中&#xff0c;我们会需要了解&#xff0c;学习&#xff0c;使用一个框架&#xff0c;一个新的函数库。在工作中&#xff0c;因为业务需求&#xff0c;因为性能问题&#xff0c;可能通过一个更高性能的工具&#xff0c;架构去优化我们的程序。 那么&…