一天入門Arduino語言 教程
爲什麼要寫這個文章
爲了讓有一定編程基礎和開發經驗的同學能夠快速的上手 Arduino 同時Arduino 新手也可以藉此鞏固下知識
如果你有過類似 51 STM32 NXP 等開發經驗,根據本篇文章,可以快速的瞭解並上手Arduino
,同時對於Arduino新手而言,可以有一個系統的學習。
可結合IDE介紹博客一起學習,更好的掌握Arduino
Arduino IDE使用教程-超詳細
文章目錄
Arduino語言
Arduino使用C/C++編寫程序,雖然C++兼容C語言,但這是兩種語言,C語言是一種面向過程的編程語言,C++是一種面向對象的編程語言。早期的Arduino核心庫使用C語言編寫,後來引進了面向對象的思想,目前最新的Arduino核心庫採用C與C++混合編寫而成。
通常我們說的Arduino語言,是指Arduino核心庫文件提供的各種應用程序編程接口(Application Programming Interface,簡稱API)的集合。這些API是對更底層的單片機支持庫進行二次封裝所形成的。例如,使用AVR單片機的Arduino的核心庫是對AVR-Libc(基於GCC的AVR支持庫)的二次封裝。
傳統開發方式中,你需要釐清每個寄存器的意義及之間的關係,然後通過配置多個寄存器來達到目的。
而在Arduino中,使用了清楚明瞭的API替代繁雜的寄存器配置過程,這點在下方的代碼中你將深有體會,這也是Arduino能成爲簡單入門單片機的核心。
C語言基礎部分
判斷語句:
if
if語句是最常用的選擇結構實現方式,當給定表達式爲真時,就會運行if內的語句
if(表達式)
{
語句;
}
if…else
若這個表示式爲真,語句1部分的代碼就會被執行。若這個表示式爲假,則執行緊接着else之後的語句2部分代碼。
if(表達式)
{
語句1;
}
else
{
語句2;
}
if…else if
若這個表示式1爲真,語句1部分的代碼就會被執行。若這個表示式1爲假,則緊接着判斷else if之後的表達式2,如果表達式2爲真,則執行語句2 ,否則依次往下循環。
一旦 else if 成功,將不會測試剩餘的else if或else語句。
if(表達式1)
{
語句1;
}
else if(表達式2)
{
語句2;
}
else if(表達式3)
{
語句3;
}
else if(表達式4)
{
語句4;
}
……
switch…case
類似於if語句, switch … case 通過允許程序員指定應在各種條件下執行的不同代碼來控制程序的流程。 switch 語句將變量的值與 case 語句中指定的值進行比較。當發現一個case語句的值與變量的值匹配時,運行case語句中的代碼。如果所有的case都不符合switch的表達式 則執行default語句中的代碼。
比起一串冗長的if敘述,使用swith case可使程序代碼看起來比較簡潔。
switch(表達式)
{
case 常量表達式1:
語句1
break;
case 常量表達式2:
語句2
break;
default : // 以上條件都不符合時,預設執行的動作
語句n
break;
}
-
Switch後的表達式結果只能是整形或字符型
-
switch語句使用 break 關鍵字退出,通常在每個case語句的結尾使用。如果沒有break語句,switch語句將繼續執行後續的表達式(“fall-through”),直到到達break語句或達到switch語句的結尾。
循環語句:
while循環
當while之後的條件成立時,執行括號內的程序代碼。
while循環將會連續、無限循環,直到括號()內的表達式變爲false。或者使用break語句跳出循環,否則while就是死循環。
while(表達式)
{
語句;
}
do…while循環
和while 相似,不同的是while前的那段程序代碼會先被執行一次,纔會判斷特定的條件式爲真或爲假。如果爲真則繼續執行,如果爲假則跳出循環。因此若有一段程序代碼至少需要被執行一次,就可以使用do…while架構。
do
{
語句;
}
while(表達式);
for循環
假如您需要運行代碼多次,且每次使用不同的值,那麼for循環則非常適用
for (循環變量類型 循環變量名稱;循環條件;更新語句)
for(循環變量名稱;循環條件;更新語句)
{
語句;
}
每次循環完一次都會執行更新語句 只要還滿足循環條件就會一直進行循環
for (i=0; i<5; i++) {
}
就是初始化i=0 當i小於5時運行循環體中的語句,每循環完一次,i自加1,總共循環5次
break語句
當 break 關鍵字用於 while、for循環時,會終止循環而執行整個循環語句後面的代碼。break 關鍵字通常和 if 語句一起使用,即滿足條件時便跳出循環。
while(1){ //循環條件爲死循環
sum+=i;
i++;
if(i>100) break;
}
while 循環條件爲 1,是一個死循環。當執行到第100次循環的時候,計算完i++;
後 i 的值爲 101,此時 if 語句的條件 i> 100 成立,執行break;
語句,結束循環。
一個 break 語句只向外跳一層
continue語句
continue 語句的作用是跳過循環體中剩餘的語句而強制進入下一次循環。continue語句只用在 while、for 循環中,常與 if 條件語句一起使用,判斷條件是否成立。
i=0;
b=0;
if(i<10)
{
i++;
if(i<5)
b++;
else
continue;
}
上方代碼就會在i小於5的時候執行b++ 在i大於5的時候執行continue語句 繼續循環 最後i=10,b=5
語法符號
- ; 語句分隔符
- {} 代碼塊
- // 單行註釋
- /* 在這個範圍內你可以寫一整首詩 */ 多行註釋
*/*與/**之間的內容,及 // 之後的內容均爲程序註釋,使用它可以更好的管理代碼。註釋不會被編譯到程序中,不影響程序的運行。
// 這是一個單行註釋
/*
這是一個多行註釋
註釋內容1
註釋內容2
……
*/
運算符:
常見C\C++運算符
Arduuino複合運算符
*+= , -= , = , /=
對一個變量和另一個參數或變量完成一個數學運算。+=(以及其他)可以縮短語法長度。
Syntax語法
x += y; // 等價於 x = x + y;
x -= y; // 等價於 x = x - y;
x *= y; // 等價於 x = x * y;
x /= y; // 等價於 x = x / y;
Parameters參數
x:任何變量類型
y:任何變量類型或常數
Examples範例
x = 2;
x += 4; // x現在爲6
x -= 3; // x現在爲3
x *= 10; // x現在爲30
x /= 2; // x現在爲15
Syntax語法
x++; // increment x by one and returns the old value of x
// 將x的值加1並返回原來的x的值。 ++x; // increment x by one and returns the new value of x // 將x的值加1並返回現在的x的值。
x-- ; // decrement x by one and returns the old value of x // 將x的值減1並返回原來的x的值。
–x ; // decrement x by one and returns the new value of x // 將x的值減1並返回現在的x的值。
Parameters參數
x: an integer or long (possibly unsigned)
x:一個整數或長整數(可以無符號)
Returns返回
The original or newly incremented / decremented value of the variable.
返回變量原始值或增加/消耗後的新值。
Examples範例:
x = 2;
y = ++x; // x now contains 3, y contains 3 // x現在爲3,y爲3
y = x–; // x contains 2 again, y still contains 3 // x現在仍然爲2,y將爲3
數據類型:
整型:
類型 | 取值範圍 | 說明 |
---|---|---|
int | –2,147,483,648 ~ 2,147,483,647 | 整型 |
unsigned int | 0 ~ 4,294,967,295 | 無符號整型 |
long | –2,147,483,648 ~ 2,147,483,647 | 長整型 |
unsigned long | 0 ~ 4,294,967,295 | 無符號長整型 |
short | –32,768 ~ 32,767 | 短整型 |
boolean 布爾類型
布爾類型的值只能爲真(true)或是假(false)
boolean會佔用1個字節的內存空間。
byte 字節類型
儲存的數值範圍爲0到255。如同字符一樣字節型態的變量只需要用一個字節(8位)的內存空間儲存。
浮點型
浮點數也就是常說的小數。在Arduino中有float和double兩種浮點類型,
float類型佔用4個字節(32位)內存空間,
double類型佔用8個字節(64位)內存空間。可表達最大值爲 1.7976931348623157 x 10308
float最多有8位小數
double最多有16位小數
float 和double 都不能爲0
字符型
char
用於存儲字符數據 單一字符例如 A 佔用一個字節內存空間,存儲字符時,字符需要用單引號引用
Arduino使用ASCII 碼來存儲字符數據 用數字表示一個字符時,它的值有效範圍爲 -128 到127。
char Str='A';
String
char只能表示一個字符,如果需要多個字符的話,就需要用到String
它是由多個ASCII字符組成 可以用來保存多個字符
如:
String Str = "Helloo,World";
相較於數組形式的定義方法,使用String類型定義字符串會佔用更多的存儲空間。
數組:
數組是由一組相同數據類型的數據構成的集合。數組概念的引入,使得在處理多個相同類型的數據時,程序更加清晰和簡潔。
其定義方式如下:
類型說明符 數組名[常量表達式];
例如:
int a[5];
它表示定義了一個整型數組,數組名爲 a,定義的數組稱爲數組 a
此時數組 a 中有 5 個元素,每個元素都是 int 型變量,而且它們在內存中的地址是連續分配的。也就是說,int 型變量佔 4 字節的內存空間,那麼 5 個int型變量就佔 20 字節的內存空間,而且它們的地址是連續分配的。
數組中的下標是從 0 開始的,例如“int a[5];”表示定義了有 5 個元素的數組 a,這 5 個元素分別爲 a[0]、a[1]、a[2]、a[3]、a[4]。
初始化:
在定義時初始化
int a[5] = {1, 2, 3, 4, 5};
int a[5];
a[0]=1; a[1]=2; a[2]=3; a[3]=4; a[4]=5;
要將A[4]的值除以2並將結果賦值給變量x,我們將寫:
x = A[ 4 ] / 2;
數據類型轉換:
-
char()
-
byte()
-
int()
-
long()
-
float()
也就是類型強制轉換 比方說將一個char字符類型強制轉化爲int整數類型
char str = 'a';
int sch = int(str); //將字符a 轉換爲整數 按照ASCII碼 a的ASCII碼數值是97
注意,由高精度想低精度轉換,會出現bug 比如把int類型轉換爲byte類型,就會出現數據缺失的情況 (int最大2,147,483,647 byte最大255)
常量和變量:
常量:在Arduino語言中事先定義了一些具特殊用途的保留字。 其值不能改變
可以用const關鍵字來定義常量
const 類型 常量名 = 常量值
還可以用宏定義來定義常量
#define 宏名 值
例如:
const int a =0;
#define b = 1;
那麼在該程序種,a就只能是0 b就只能是1
變量:變量可以用來儲存各種類型數據,並且可以更改數據
其定義方法如下
類型 變量名;
例如,定義一個整型變量i:
int i=95;
Arduino使用的C語言中的變量具有名爲scope(範圍)的屬性。scope是程序的一個區域,有三個地方可以聲明變量。它們是:
- 在函數或代碼塊內部,稱爲局部變量。
- 在函數參數的定義中,稱爲形式參數。
- 在所有函數之外,稱爲全局變量。
局部變量
在函數或代碼塊中聲明的變量是局部變量。局部變量只能在其函數內使用
Void loop () {
int x , y ;
x = 0;
y = 0;
}
y = 2; //這樣就是錯的
形式參數
作爲函數的參數來使用,用來傳遞其他變量的值
void Led(int a){
a = 0;
}
int b=2;
Led(b); //把b的值傳遞給形參a
全局變量
全局變量在所有函數之外定義,通常位於程序的頂部。全局變量將在程序的整個生命週期中保持其價值。
全局變量可以被任何函數訪問。也就是說,一個全局變量可以在整個程序中聲明後使用。
int y = 0; //全局變量
Void loop () {
int x;
x = 0;
y = 1; //這樣是對的
}
y = 2; //這樣是對的
在Arduino中定義了許多常量,是不可修改的,也是我們常用的
常量PI
Arduino核心庫中已定義的常數PI,
#define PI 3.1415926535897932384626433832795
HIGH | LOW
表示數字IO口的電平,HIGH 表示高電平(1),LOW 表示低電平(0)。 HIGH 和LOW 也用來表示你開啓或是關閉了一個Arduino的腳位(pin)
INPUT | OUTPUT
表示數字IO口的方向,INPUT 表示輸入(高阻態),OUTPUT 表示輸出(AVR能提供5V電壓 40mA電流)
true | false
true 表示真(1),false表示假(0)。
Arduino 語言部分
此部分我們來探討Arduino的語言特性,讓你來真正的掌握Arduino
Arduino結構
Arduino程序中沒有main函數。
main函數的定義隱藏在了Arduino的核心庫文件中,所以Arduino開發一般不直接操作main函數,而是使用Setup和loop這個兩個函數。
**Arduino軟件結構包括兩個主要函數:
-
Setup()函數 初始化變量,管腳模式,調用庫函數等
-
Loop()函數 連續循環執行loop函數內的程序
void setup()
{
// 在這裏加入你的setup代碼,它只會運行一次:
}
void loop()
{
// 在這裏加入你的loop代碼,它會不斷重複運行:
}
Void setup ( ) {
}
在程序開始時使用,Arduino控制器通電或復位後,,程序啓動時會調用 **setup()**函數。使用它來初始化變量,引腳模式,啓用庫等。setup函數只能在Arduino板的每次上電或復位後運行一次。
Void loop ( ) {
}
在setup()函數之後,即初始化之後,loop() 讓你的程序循環地被執行。使用它來運轉Arduino。連續執行函數內的語句,這部份的程式會一直重複的被執行,直到Arduino 板子被關閉。
Arduino I/O函數
數字 I/O
pinMode()函數
pinMode(13,OUTPUT); //定義引腳的模式
數字IO口輸入輸出模式定義函數,將接口定義爲輸入或輸出接口
pinMode()函數用於將特定引腳配置爲輸入或輸出。可以使用INPUT_PULLUP模式啓用內部上拉電阻。此外,INPUT模式顯式禁止內部上拉。
- pin - 你希望設置模式的引腳的編號 0~13
- *mode* - INPUT(輸入模式),OUTPUT(輸出模式)或INPUT_PULLUP(內部上拉輸入)。
範例:
pinMode(7,INPUT); // 將腳位 7 設定爲輸入模式
pinMode(1,INPUT);//將腳位1設定爲輸入模式
pinMode(2,INPUT);//將腳位2設定爲輸入模式
pinMode(3,INPUT);//將腳位3設定爲輸入模式
引腳配置爲INPUT
Arduino引腳默認配置爲輸入 ,輸入模式下,由外部器件向Arduino對於引腳輸入電平,和數據,Arduino識別電平及數據,進行相應的處理。
引腳配置爲OUTPUT
引腳配置爲輸出模式,Arduino引腳向其他電路提供大量的電流。Arduino引腳可以向其他器件/電路提供(提供正電流)或吸收(提供負電流)高達40mA(毫安)的電流。這是足以點亮LED或者運行許多傳感器的電流(不要忘記串聯電阻),但不足以運行繼電器,螺線管或電機。
上拉電阻
上拉就是將不確定的信號通過一個電阻鉗位在高電平,電阻同時起限流作用,增強輸出引腳的驅動能力,提高芯片輸入信號的噪聲容限,增強抗干擾能力。
也就是默認狀態下io爲高電平 ,下拉電阻與此同理。
digitalWrite()函數
digitalWrite(pin,value); //定義引腳的電平
- pin:你希望設置模式的引腳的編號 0~13
- value :表示爲HIGH(高電平)或LOW(低電平)
HIGH爲5V(或3.3V在3.3V板上),LOW爲0V(接地)
數字IO口輸出電平定義函數,將數字接口值至高或低、開或關,即digitalWrite(接口名稱, HIGH或LOW)。但腳位必須先透過pinMode明示爲輸入或輸出模式digitalWrite才能生效。比如定義HIGH可以驅動LED。
範例:
digitalWrite(8,HIGH); //將腳位 8設定輸出高電位
digitalRead函數
引腳電平讀取函數
int digitalRead(pin)
數字IO口讀輸入電平函數,讀出數字接口的值 比如可以讀數字傳感器。當感測到腳位處於高電位時時回傳HIGH,否則回傳LOW。
範例:
val = digitalRead(7); // 讀出腳位 7 的值並指定給 val
模擬 I/O
analogRead()函數
int analogRead(pin)
- pin 要讀取的模擬輸入引腳的編號(Arduino Diecimila爲0~5,Arduino nano爲0~7 Mega上爲0至15)
模擬IO口讀函數,從指定的模擬接口讀取值,Arduino對該模擬值進行10-bit的數字轉換。 此函數返回0到1023之間的數字,表示0到5伏特之間的電壓。例如,如果施加到編號0的引腳的電壓爲2.5V,則analogRead(0)返回512。
通過使用**analogRead()**函數,我們可以讀取施加到其中一個引腳的電壓。比如可以讀模擬傳感器(10位AD,0~5V表示爲0~1023)。
範例:
val = analogRead(2); //讀出類比腳位 2 的值並賦值給 val
analogWrite函數
analogWrite(pin, value);
數字IO口PWM輸出函數,給一個接口寫入模擬值(PWM波)改變PWM腳位的輸出電壓值可用於電機PWM調速或音樂播放。
-
pin:對於 ATmega168芯片的Arduino(包括Mini或BT),該函數可以工作於 3, 5, 6, 9, 10和 11號接口
-
value表示爲0~255
例如:輸出電壓2.5伏特(V),該值大約是128。
範例 :
analogWrite(9,128); // 輸出電壓約2.5伏特(V)
擴展 I/O
shiftOut函數
shiftOut(dataPin, clockPin, bitOrder, value)
SPI外部IO擴展函數,通常使用帶SPI接口的74HC595做8個IO擴展,把資料傳給用來延伸數位輸出的暫存器,此函式通常使用在延伸數位的輸出。函式使用一個腳位表示資料、一個腳位表示時脈。dataPin爲數據口,clockPin爲時鐘口,bitOrder用來表示位元間移動的方式,爲數據傳輸方向(MSBFIRST高位在前,LSBFIRST低位在前),value會以byte形式輸出,表示所要傳送的數據(0~255),另外還需要一個IO口做74HC595的使能控制。
範例 :
shiftOut(dataPin, clockPin, LSBFIRST, 255);
pulseIn()函數
unsigned long pulseIn(pin, value)
脈衝長度記錄函數,設定讀取腳位狀態的持續時間,返回時間參數(us),例如使用紅外線、加速度感測器測得某一項數值時,在時間單位內不會改變狀態。pin表示爲0~13,value爲HIGH或LOW。比如value爲HIGH,那麼當pin輸入爲高電平時,開始計時,當pin輸入爲低電平時,停止計時,然後返回該時間。
範例:
time = pulsein(7,HIGH); // 設定腳位7的狀態在時間單位內保持爲HIGH
Arduino 時間函數
Arduino提供四種不同的時間操作函數
delay(ms) 延時函數
delay (ms) ;
delay(ms) 延時函數(單位ms),延時一段時間,暫停晶片執行多少毫秒,
delay(1000)爲一秒。
範例:
//LED閃爍實驗
void loop() {
digitalWrite(ledPin, HIGH); // 打開LED燈
delay(1000); // 延時1秒鐘
digitalWrite(ledPin, LOW); // 關閉LED燈
delay(1000); // 延時1秒鐘
}
delayMicroseconds()函數
delayMicroseconds (us) ;
- us 是要暫停的微秒數(無符號整型)。
延時函數(單位us)暫停晶片執行多少微秒
delayMicroseconds()函數接受單個整數(或數字)參數。此數字表示時間,以微秒爲單位。一毫秒內有一千微秒,一秒內有一百萬微秒
目前,可以產生精確延遲的最大值是16383
範例:
delayMicroseconds(1000); //暫停1豪秒
millis()函數
unsigned long millis()
返回時間函數(單位ms), 回傳晶片開始執行到目前的毫秒,此函數用於返回Arduino板開始運行當前程序時的毫秒數,該參數溢出大概需要50天時間。
範例:
void loop() {
Serial.print("Time:"); //延時1S計算運行時間
time = millis();
delay(1000);
}
micros()函數
micros () ;
micros()函數返回Arduino板開始運行當前程序時的微秒數。該數字在大約70分鐘後溢出,即回到零。在16 MHz Arduino板(例如Duemilanove和Nano)上,此函數的分辨率爲4微秒(即返回值總是4的倍數)。在8 MHz Arduino板(例如LilyPad)上,此函數的分辨率爲8微秒。
範例:
void loop() {
Serial.print("Time:"); //延時1S計算運行時間
time = micros();
delay(1000);
}
Arduino數學函數
Arduino數學庫(math.h)包含了許多用於操作浮點數的有用的數學函數。
min(x, y)
求最小值 ,回傳兩數之間較小者
範例:
val = min(10,20); // val=10
max(x, y)
求最大值 ,回傳兩數之間較大者
範例:
val = max(10,20); // val=20
abs(x)
計算絕對值 ,回傳該數的絕對值,
範例:
val = abs(-5); // val=5
constrain(x, a, b)
約束函數,下限a,上限b,判斷x變數位於a與b之間的狀態。
x若小於a回傳a;
介於a與b之間回傳x本身;
大於b回傳b
範例:
val = constrain(i, 0, 255); // 將i的值賦值給val 並且i的取值爲0~255
map(value, fromLow, fromHigh, toLow, toHigh)
約束函數,value必須在fromLow與toLow之間和fromHigh與toHigh之間。將value變數依照fromLow與fromHigh範圍,對等轉換至toLow與toHigh範圍。時常使用於讀取類比訊號,轉換至程式所需要的範圍值。
範例:
val = map(analogRead(0),0,1023,100, 200); // 將analog0 所讀取到的訊號0~1023對等轉換至100,200之間的數值。
pow(base, exponent)
開方函數,base的exponent次方。回傳一個數(base)的指數(exponent)值。
範例:
double x = pow(y, 32); // 設定x爲y的32次方
sq(x) 平方
平方函數,返回x的平方值
範例:
val=sq(2); //val等於2的平方
sqrt(x) 開根號
回傳double型態的取平方根值。
範例:
double val = sqrt(1138); // 回傳1138平方根的近似值 33.73425674438
double log (double __x)
log()函數返回參數x的自然對數。
範例:
double val = log(2);
double round (double __x)
round()函數將x四捨五入到最近的整數,但中間情況不捨入到0(不是到最近的偶數整數)。不可能會溢出。
範例:
double val = round(5.6); //val=6
Arduino三角函數
Arduino提供了傳統的三角函數(sin,cos,tan,asin,acos,atan)
double sin(double x); //返回x弧度的正弦
double cos(double y); //返回y弧度的餘弦
double tan(double x); //返回x弧度的正切
double acos(double x); //返回A,對應於cos(A)=x的角度
double asin(double x); //返回A,與sin(A)=x相對應的角度
double atan(double x); //返回A,與tan(A)=x相對應的角度
範例:
double sine = sin(2); // 近似值 0.90929737091
double cosine = cos(2); //近似值-0.41614685058
double tangent = tan(2); //近似值-2.18503975868
Arduino 隨機數函數
randomSeed()函數
randomSeed(seed)
隨機數端口定義函數,seed表示讀模擬口analogRead(pin)函數
randomSeed(seed)函數重置Arduino的僞隨機數生成器
雖然random()返回的數字的分佈本質上是隨機的,但是順序是可預測的。所以如果需要一個真正的亂數,可以呼叫此函式重新設定產生亂數種子。你可以使用亂數當作亂數的種子,以確保數字以隨機的方式出現,通常會使用類比輸入當作亂數種子,藉此可以產生與環境有關的亂數(例如:無線電波、宇宙雷射線、電話和螢光燈發出的電磁波等)。
範例:
randomSeed(analogRead(5)); //使用來自模擬管腳5的噪聲隨機化
random()函數
long random(min, max)
隨機數函數,返回數據大於等於min,小於max。
long random(max)
返回數據大於等於0,小於max。
範例:
long randnum = random(11); // 回傳 0 -10之間的數字
long randnum = random(0, 100); // 回傳0 – 99 之間的數字
Arduino外部中斷函數
中斷:**
中斷(interrupt)停止Arduino的當前工作,以便可以完成一些其他工作。
什麼是中斷:
CPU在處理某一事件A時,發生了另一事件B請求CPU迅速去處理(中斷髮生);
CPU暫時中斷當前的工作,轉去處理事件B(中斷響應和中斷服務);
待CPU將事件B處理完畢後,再回到原來事件A被中斷的地方繼續處理事件A(中斷返回),這一過程稱爲中斷。
通俗點說:你正在家裏做家務,突然有人來找你,打斷了你的進程,在你們交談完之後,你就又回去繼續進行你的家務活,這其中被打斷的過程,就叫做中斷,而在中斷結束之後,你則會繼續進行本來應該做的事情
- 中斷是一種使CPU中止正在執行的程序而轉去處理特殊事件的操作,這些引起中斷的事件稱爲中斷源,它們可能是來自外設的輸入輸出請求,也可能是計算機的一些異常事故或其它內部原因。
- 中斷可以來自各種來源。在這種情況下,我們使用的是由數字引腳上的狀態改變觸發的硬件中斷
- 大多數Arduino設計有兩個硬件中斷(稱爲“interrupt0”和“interrupt1”)分別硬連接到數字I/O引腳2和3。
- Arduino Mega有六個硬件中斷,包括引腳21,20,19和18上的附加中斷(“interrupt2”到“interrupt5”)。
- 你可以定義該程序並指定上升沿,下降沿或兩者的條件。在這些特定條件下,將處理中斷。
中斷類型:
- 硬件中斷 - 它們響應外部事件而發生,例如外部中斷引腳變爲高電平或低電平。
- 軟件中斷 - 它們響應於在軟件中發送的指令而發生。“Arduino語言”支持的唯一類型的中斷是attachInterrupt()函數。
具體請參考:
attachInterrupt()函數
attachInterrupt(interrupt,function,mode)
interrupt:中斷源(在Arduino中,中斷源可選值爲0或1,一般分別對應2號和3號引腳)
function:需要中斷的函數名
mode:
-
LOW(低電平觸發)、
-
CHANGE(在引腳電平變化時觸發)、
-
RISING(低電平變爲高電平觸發)、
-
FALLING(高電平變爲低電平觸發)
外部中斷只能用到數字IO口2和3,interrupt表示中斷口初始0或1,表示一個功能函數,mode:LOW低電平中斷,CHANGE有變化就中斷,RISING上升沿中斷,FALLING 下降沿中斷。
detachInterrupt()函數
detachInterrupt(interrupt)
中斷開關函數,interrupt=1 開,interrupt=0 關。
範例:
detachInterrupt(1)//打開中斷
中斷使能函數
interrupts()// 使能中斷
noInterrupts() //禁止中斷
Arduino串口收發函數
Arduino Uno R3開發板上,硬件串口位於Rx(0)和Tx(1)引腳上,Arduino的USB口通過轉換芯片與這兩個引腳連接。該轉換芯片會通過USB接口在PC機上虛擬出一個用於Arduino通訊的串口,我們下載程序也是通過串口進行的。
Serial.begin(speed)
-
串口定義波特率函數,設置串行每秒傳輸數據的速率(波特率),可以指定Arduino從電腦交換訊息的速率,通常置於setup()函數中。
-
原型:
-
Serial.begin(speed)
-
- Serial.begin(speed, config)
參數:
-
speed:波特率,一般取值9600,115200等。在同計算機通訊時,使用下面這些值:300, 1200, 2400, 4800, 9600, 14400, 19200, 28800, 38400, 57600或 115200 bps(每秒位元組)
-
config:設置數據位、校驗位和停止位。默認SERIAL_8N1表示8個數據位,無校驗位,1個停止位。
-
返回值:無。
範例:
Serial.begin(9600)
Serial.end()
- 描述:禁止串口傳輸。此時串口Rx和Tx可以作爲數字IO引腳使用。
- 原型:Serial.end()
- 參數:無。
- 返回值:無。
Serial.print()
- 描述:串口輸出數據,寫入字符數據到串口。
- 原型:
- Serial.print(val)
- Serial.print(val, format)
- 參數:
- val:打印的值,任意數據類型。
- config:輸出的數據格式。BIN(二進制)、OCT(八進制)、DEC(十進制)、HEX(十六進制)。對於浮點數,此參數指定要使用的小數位數。
- 示例:
- Serial.print(75); // 列印出 “75”
- Serial.print(75, DEC); //列印出 “75”
- Serial.print(75, HEX); // “4B” (75 的十六進位)
- Serial.print(75, OCT); // “113” (75 in的八進位)
- Serial.print(75, BIN); // “1001011” (75的二進位)
- Serial.print(75, BYTE); // “K” (以byte進行傳送,顯示以ASCII編碼方式)
- Serial.print(1.23456, 0) 得到 “1”
- Serial.print(1.23456, 2) 得到 “1.23”
- Serial.print(1.23456, 4) 得到 “1.2346”
- Serial.print(‘N’) 得到 “N”
- Serial.print(“Hello world.”) 得到 “Hello world.”
- 返回值:返回寫入的字節數。
Serial.println()
- 描述:串口輸出數據並換行。
- 原型:
- Serial.println(val)
- Serial.println(val, format)
- 參數:
- val:打印的值,任意數據類型。
- config:輸出的數據格式。
- 返回值:返回寫入的字節數。
Serial.available()
- 描述:判斷串口緩衝區的狀態,返回從串口緩衝區讀取的字節數。
- 原型:Serial.available()
- 參數:無。
- 返回值:可讀取的字節數, 如果回傳值是0代表所有序列埠上資料都已經被read()函式讀取。
範例:
int count = Serial.available();
Serial.read()
- 描述:讀取串口數據,一次讀一個字符,讀完後刪除已讀數據。
- 原型:Serial.read()
- 參數:無。
- 返回值:返回串口緩存中第一個可讀字節,當沒有可讀數據時返回-1,整數類型。
範例:
int data = Serial.read();
Serial.readBytes()
- 描述:從串口讀取指定長度的字符到緩存數組。
- 原型:Serial.readBytes(buffer, length)
- 參數:
- buffer:緩存變量。
- length:設定的讀取長度。
- 返回值:返回存入緩存的字符數。
Serial.flush()
- 描述:清空緩衝器。 有時候因爲資料速度太快,超過程式處理資料的速度,你可以使用此函式清除緩衝區內的資料。經過此函式可以確保緩衝區(buffer)內的資料都是最新的。
- 原型: Serial.flush();
- 參數: 無
- 返回值: 無
範例:
Serial.flush();
Arduino語言庫文件
官方庫文件
· EEPROM - EEPROM讀寫程序庫
· Ethernet - 以太網控制器程序庫
· LiquidCrystal - LCD控制程序庫
· Servo - 舵機控制程序庫
· SoftwareSerial - 任何數字IO口模擬串口程序庫
· Stepper - 步進電機控制程序庫
· Wire - TWI/I2C總線程序庫
· Matrix - LED矩陣控制程序庫
· Sprite - LED矩陣圖象處理控制程序庫
Arduino 內部集成電路I2C
內部集成電路(I2C)是用於微控制器和新一代專用集成電路之間的串行數據交換系統。當它們之間的距離很短(接收器和發射器通常在同一個印刷電路板上)時使用。通過兩根導線建立連接。一個用於數據傳輸,另一個用於同步(時鐘信號)。
Arduino板的I2C引腳
I2C總線由兩個信號組成 - SCL和SDA。SCL是時鐘信號,SDA是數據信號。當前總線主機總是產生時鐘信號。一些從設備可能迫使時鐘低電平以延遲主設備發送更多數據(或者在主設備嘗試將數據寫出之前請求更多的時間來準備數據)。這被稱爲“時鐘伸展”。
以下是不同Arduino板的引腳:
- Uno, Pro Mini A4 (SDA), A5 (SCL)
- Mega, Due 20 (SDA), 21 (SCL)
- Leonardo, Yun 2 (SDA), 3 (SCL)
Arduino I2C
我們有兩種模式 - 主代碼和從代碼 - 使用I2C連接兩個Arduino板。它們是:
- Master Transmitter / Slave Receiver 主發射器/從接收器
- Master Receiver / Slave Transmitter 主接收器/從發射器
主發射器/從接收器
讓我們現在看看什麼是主發送器和從接收器。
主發射器
以下函數用於初始化Wire庫,並將I2C總線作爲主器件或從器件加入。這通常只被調用一次。
- Wire.begin(地址) - 在我們的例子中,地址是7位從地址,因爲未指定主機,它將作爲主機加入總線。
- Wire.beginTransmission(地址) - 開始向給定地址的I2C從設備發送數據。
- Wire.write(值) - 用於從主設備傳輸到從設備的隊列字節(在beginTransmission()和endTransmission()之間的調用)。
- Wire.endTransmission() - 結束由beginTransmission()開始的對從設備的傳輸,並傳輸由wire.write()排隊的字節。
從接收器
使用以下函數:
- Wire.begin(地址) - 地址是7位從地址。
- Wire.onReceive(收到的數據處理程序) - 當從設備從主設備接收數據時調用的函數。
- Wire.available() - 返回Wire.read()可用於檢索的字節數,應在Wire.onReceive()處理程序中調用。