目錄
1.串口通信
2.IIC
單片機的第五大功能——串口通訊,它可以建立起你的電腦和單片機直接的連接,也可以是其他模塊的連接,比如藍牙,WIFI等,介面都是串口,另一部分的模塊,介面時IIC或者SPI,比如陀螺儀一般都是IIC,OLED顯示,介面也是IIC
在物理上,串口通信需要三根線 TX RX GND,TX是發送,RX是接受 GND是接地,看看原理圖


我們看到,RX RT經過一個USB芯片,把串口轉換成了USB口,所以插到我們的USB線就是個串口和供電的功能(注意使用的是資料線還是電源線,電源線是無法出現COM口的),我們的電腦會出現一個虛擬的COM口
串口有兩個功能,第一個功能是將資料發送出去,第二個功能是接收外面來的資料,而發送進來的資料是一串16進制的陣列,比如 55 77 03 05 9A B4 FF FF,這串陣列的意思,我們有個學名,叫做協議,也叫做通信協議 ,所謂通訊協議就是通訊雙方所約定的數值的含義,也就是說發這串資料,每個16進制數所代表的含義,一般情況下,我們制定協議的時候是這樣的,以上一個例子為例,5577代表開始,03 05 78 9A B4,這五個資料代表五個引數,當然了,具體什么引數是根據具體的需要來定的,最后兩個ff ff是表示結束,那么如果我們雙方約定好了這樣一個協議,那么我發什么你接收到之后,你也知道每一個欄位所代表的含義了,如果我不知道雙方的協議呢,我就很難介入到你們的通信當中去,比如說我要維修一個設備,這兩個設備之間呢是用串口進行通訊的,
那么我能監聽到他們通訊的內容,也能把他們通訊的16進制數都寫出來,但是我不知道他們所表示的含義,這個只有設備的生產商才知道,這種協議的我們稱之為私有協議,
有些協議是公開的,為了方便各個廠家的設備進行對接,只要大家都遵循同樣一個協議,那么我們的設備就可以互相通訊,所以大公司的產品一般都遵循一個標準協議,
那么講到串口通訊,我們還需要講一個概念,就是通訊的波特率,所謂的波特率,就是一秒鐘發送資料的位數,通訊是兩個設備之間的事情,那么他們的頻率必須保持一致,一般我們用的波特率是9600,波特率越低發送的速度越慢,波特率越高發送的資料越快,有可能會出問題
int incomedate = 0;
void setup() {
Serial.begin(9600); //設定串口波特率9600
}
void loop() {
if (Serial.available() > 0)//串口接收到資料
{
incomedate = Serial.read();//獲取串口接收到的資料
if (incomedate == 'a') // 判斷我們所接收到的字符
{
Serial.println("ko no dio da!");串口監視器里看列印出的東西
}
}
delay(1000);//回圈延時一秒列印
}
我們來介紹一下上面的這些函式
· Serial.begin(speed) 定義我們的波特率
`int Serial.available() 判斷緩沖器狀態,回傳接受到位元組數
`int Serial.read() 讀取串口并且回傳收到資料(也就是我們要我們所設定的東西,給他賦值賦這個)
`Serial.flush() 清慷訓沖器
`Serial.print(data) 串口輸出資料,data可以是任何資料型別
`Serial.println(data) 串口輸出資料并且帶回車符(空行)
我們再來梳理一下整個程序,單片機一開始什么事情也不做,就在那等待,當我的電腦發送一個資料給單片機的時候,單片機來接收并判斷這個資料,如果是我想要的資料,那么我就做選擇分支去做一件事情,我們這里做的事情是反饋一個字串出去,如果不是,我們也可以讓他去做另一個事情,利用這個特性,我們就可以進行我們的遠程點燈
比如我們在我們的判斷陳述句里加入點燈,這樣我們接受到我們想要的資料后就可以,點亮燈了
接下來是我們的IIC通信
代碼來源于 huanghaoAudio
//I2C主機
#include <Wire.h>
#define LED 13
//初始化
void setup()
{
Wire.begin(); //主機
pinMode(LED,OUTPUT);
Serial.begin(115200);
}
//主程式
void loop()
{
Wire.beginTransmission(4); //發送資料到設備號為4的從機
Wire.write("OFF"); // 發送字串
Wire.endTransmission(); // 停止發送
request(); //回復狀態
delay(1000);
Wire.beginTransmission(4);
Wire.write("ON");
Wire.endTransmission();
request();
delay(1000);
}
void request()
{
delay(10);
Wire.requestFrom(4, 2); //通知4號從機上傳2個位元組
String c;
while(Wire.available()>0) // 當主機接收到從機資料時
{
c += char(Wire.read());
}
Serial.print(c);
if(c=="OK"){digitalWrite(LED,HIGH);}
else {digitalWrite(LED,LOW);}
}
//I2C從機
#include <Wire.h>
#define LED 13
bool LED_STA;//記錄LED狀態
//初始化
void setup()
{
Wire.begin(4); // 加入 i2c 總線,設定從機地址為 #4
Wire.onReceive(receiveEvent); //注冊接收到主機字符的事件
Wire.onRequest(requestEvent); // 注冊主機通知從機上傳資料的事件
pinMode(LED,OUTPUT);//設定數字埠13為輸出
Serial.begin(115200); //設定串口波特率
}
//主程式
void loop()
{
delay(100);//延時
}
// 當從機接收到主機字符,執行該事件
void receiveEvent(int a)
{
String c;
while( Wire.available()>0) //
{
c += char(Wire.read()); // 作為字符接收位元組
}
Serial.print(c); // 把字符列印到串口監視器中
if(c=="ON"){LED_STA = 1; digitalWrite(LED,HIGH);}//記錄LED狀態
if(c=="OFF"){LED_STA = 0;digitalWrite(LED,LOW);}
}
//當主機通知從機上傳資料,執行該事件
void requestEvent()
{
if(LED_STA == 1){Wire.write("OK"); }//如果燈已經亮了 回復OK
else {Wire.write("NO");}
}

而這個就是我們的接線圖,現在我們只要在主機和從機上的D13管腳都接上我們的led燈就可以了
因為這是個回圈的操作,所以并不需要我們做些什么,電腦自己就會進行(稍微修改修改代碼,可以換成 Serial.prinln,可以讓我們看的更清楚點列印出了什么,注意我們的波特率!!!!)
主機發出字串“ON”,從機燈亮;發出“OFF”,從機燈滅,
從機記錄led狀態,如果真的亮了,則回復主機“OK”,沒亮則回復“NO”
主機收到回復為“OK”,則主機燈亮,否則燈滅
接下來介紹介紹我們的函式
·begin() 主機使用,初始化Wire.h庫
`begin(adress) 從機使用,設定本機地址
`requestFrom(adress,count) 啟動IIC總線后,向從機要count個自己資料
`beginTransmission() 對address地址的從機發起IIC通信
`write() 發送資料的形式
Wire.write(value) 發送數值
Wire.write(string) 字符組的指標
Wire.write(data,length) data:一個位元組陣列,length:傳輸數量
`byte available() 回傳接收到的位元組數
`byte read() 接收資料
`onReceive(handler) 從機使用,注冊一個處理接受資料的函式
`onRequest(handler) 從機使用,注冊一個處理請求主機的函式
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/375030.html
標籤:其他
上一篇:關于PWM調速(基礎篇)
