編寫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.pswp.cn/news/255293.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/255293.shtml
英文地址,請注明出處:http://en.pswp.cn/news/255293.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

函數,游標與存儲過程的綜合應用

--在TOY數據庫中完成以下操作use toygo--1、編寫一個存儲過程&#xff0c;接收任意一個訂單號&#xff0c;打印訂單的表頭數據。格式如下&#xff1a;--(其中訂單編號由訂單日期訂單號的字符串組成)--訂單編號:20010520000001 訂貨日期:2001-05-20 訂貨人:拉爾森create pro…

HALCON示例程序check_blister.hdev藥品膠囊檢測

HALCON check_blister.hdev藥品膠囊檢測 示例程序源碼&#xff08;加注釋&#xff09; 顯示、讀入圖片、設置顯示字體等&#xff0c;之前的帖子已經介紹過了 dev_close_window () dev_update_off () read_image (ImageOrig, ‘blister/blister_reference’) dev_open_window_f…

【機器學習實戰】——常見函數積累

目錄 第二章 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執行先決條件檢查是依賴…

智能時代 軟件賦能——2017中國軟件技術大會

由中國科學院軟件研究所、中科軟科技股份有限公司聯合主辦&#xff0c;北京中科凱亞科技有限公司協辦的第15屆中國軟件技術大會將于2017年12月在北京 國家會議中心隆重舉行。 毋庸置疑&#xff0c;我們正在邁入智能時代&#xff0c;伴隨著物聯網、云計算、大數據、人工智能等智…

Arduino 代碼機制

新建一個Arduino程序。可是建完就郁悶了&#xff0c;因為只看到了setup和loop函數&#xff0c;卻沒有基本的c函數。 void setup() {// put your setup code here, to run once: }void loop() {// put your main code here, to run repeatedly: }于是好奇心就來了&#xff0c;當…

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

題目鏈接&#xff1a;D. Cloud of Hashtags 題意&#xff1a; 給你n個字符串&#xff0c;讓你刪后綴&#xff0c;使得這些字符串按字典序排列&#xff0c;要求是刪除的后綴最少 題解&#xff1a; 由于n比較大&#xff0c;我們可以將全部的字符串存在一個數組里面&#xff0c;然…

HALCON示例程序check_blister_mixed.hedv藥品膠囊缺陷檢測

HALCON示例程序check_blister_mixed.hedv藥品膠囊缺陷檢測 示例程序源碼&#xff08;加注釋&#xff09; 讀入圖片與顯示相關設置 dev_close_window () read_image (Image, ‘blister/blister_mixed_reference’) dev_open_window_fit_image (Image, 0, 0, -1, -1, WindowHan…

php類與對象

1.類與對象 對象&#xff1a;實際存在該類事物中每個實物的個體。$a new User(); 實例化后的$a 引用&#xff1a;php的別名&#xff0c;兩個不同的變量名字指向相同的內容 封裝: 把對象的屬性和方法組織在一個類&#xff08;邏輯單元&#xff09;里 繼承&#xff1a;以原有的類…

【深度學習系列】基礎知識、模型學習

基礎知識 原創 【深度學習】——訓練過程 原創 【深度學習】——BN層&#xff08;batch normalization&#xff09; 原創 【深度學習】——激活函數&#xff08;sigmoid、tanh、relu、softmax&#xff09; 原創 【深度學習】——損失函數 原創 【深度學習】——梯度下…

史陶比爾機器人的 LLI (Low Level Interface)

史陶比爾機器人的 LLI &#xff08;Low Level Interface&#xff09; 史陶比爾機器人擁有 Low Level Interface (LLI)接口選項. 在CS8C控制器的時代&#xff0c;LLI 接口仍然可用。這是一個選項接口。.這是除了VAL3編程語言之外的替代操作系統。通過C程序替代你的程序。 這里的…

陽獅集團與阿里巴巴全域營銷伙伴關系再升級:數據和業務合作將更緊密

3月6日&#xff0c;阿里巴巴集團與全球領先的廣告傳播集團陽獅集團在上海開啟了主題為“新局面新高度”新階段的合作溝通&#xff0c;未來雙方將進行更緊密的數據和業務層面的合作。阿里巴巴集團CMO、阿里媽媽總裁董本洪及陽獅媒體大中華區首席執行官張敬鸞就開放共贏達成共識&…

HALCON示例程序check_bottle_crate.hdev啤酒箱內酒瓶數檢測

HALCON示例程序check_bottle_crate.hdev啤酒箱內酒瓶數檢測 示例程序源碼&#xff08;加注釋&#xff09; 獲取系統關于“空白區域儲存的設置” get_system (‘store_empty_region’, StoreEmptyRegion)系統“空白區域儲存”設置為 ‘false’ set_system (‘store_empty_regi…

#undef 標識符

#undef 是在后面取消以前定義的宏定義 該指令的形式為 #undef 標識符 其中&#xff0c;標識符是一個宏名稱。如果標識符當前沒有被定義成一個宏名稱&#xff0c;那么就會忽略該指令。一旦定義預處理器標識符&#xff0c;它將保持已定義狀態且在作用域內&#xff0c;直到程序結束…

[轉]OpenGL庫介紹

原帖地址&#xff1a;http://blog.csdn.net/yyyuhan/archive/2008/01/15/2045009.aspx 開發基于OpenGL的應用程序&#xff0c;必須先了解OpenGL的庫函數。它采用C語言風格&#xff0c;提供大量的函數來進行圖形的處理和顯示。OpenGL庫函數的命名方式非常有規律。所有OpenGL函數…

SQL Server優化50法

查詢速度慢的原因很多&#xff0c;常見如下幾種&#xff1a; 1、沒有索引或者沒有用到索引(這是查詢慢最常見的問題&#xff0c;是程序設計的缺陷) 2、I/O吞吐量小&#xff0c;形成了瓶頸效應。 3、沒有創建計算列導致查詢不優化。 4、內存不足 5、網絡速度慢 …

HALCON示例程序check_fish_stick_dimension.hdev生魚棒尺寸測量;基于形態學的像素級精度尺寸測量

HALCON示例程序check_fish_stick_dimension.hdev基于形態學的像素級精度尺寸測量 示例程序源碼&#xff08;加注釋&#xff09; 關閉實時顯示更新 dev_update_off () 關閉窗口 dev_close_window () 讀入圖片 read_image (Image, ‘food/fish_sticks_raw_01’) 根據給定長寬…

單片機平臺的最小偏差圓弧插補算法

在CNC機床的G代碼中&#xff0c;最常見的有G0、G1、G2、G3代碼&#xff0c;分別表示直線和圓弧插補&#xff0c;直線插補對于單片機來說&#xff0c;比較容易實現&#xff0c;只需要將位移增量轉換為脈沖增量然后輸出給步進電機就可以了&#xff0c;但對于圓弧插補&#xff0c;…

javascript基礎--數組排序

字符串的排序 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><title>數組排序</title><script>var arr [fliar, asdf, dfe, loii, yhhl];arr.sort();alert(arr);</script> </head>&…

【轉】JS跨域(ajax跨域、iframe跨域)解決方法及原理詳解(jsonp)

這里說的js跨域是指通過js在不同的域之間進行數據傳輸或通信&#xff0c;比如用ajax向一個不同的域請求數據&#xff0c;或者通過js獲取頁面中不同域的框架中(iframe)的數據。只要協議、域名、端口有任何一個不同&#xff0c;都被當作是不同的域。 下表給出了相對http://store.…