91欧美超碰AV自拍|国产成年人性爱视频免费看|亚洲 日韩 欧美一厂二区入|人人看人人爽人人操aV|丝袜美腿视频一区二区在线看|人人操人人爽人人爱|婷婷五月天超碰|97色色欧美亚州A√|另类A√无码精品一级av|欧美特级日韩特级

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

Arduino中進行I2C通信發(fā)送數(shù)據(jù)案例分析

電子設(shè)計 ? 來源:一板網(wǎng) ? 作者:風箏 ? 2021-01-01 10:27 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

在之前的文章中,我們介紹了Arduino之間的SPI通信。今天我們將學習另一種串行通信協(xié)議:I2C(內(nèi)部集成電路)。比較I2C和SPI,I2C只有兩條線,而SPI使用四條,I2C可以有多個主機和從機,而SPI只能有一個主機和多個從機。因此,如果項目中有多個微控制器需要作為主機,那么就采用I2C。 I2C通信通常用于與陀螺儀、加速度計、氣壓傳感器、LED顯示器等進行通信。

在本篇文章中,我們將使用I2C總線在兩個arduino開發(fā)板之間進行通信,并且使用電位計將值(0到127)相互發(fā)送。這些值將顯示在連接到每個Arduino的1602液晶顯示屏上。文章中,一個Arduino開發(fā)板作為主機,另一個開發(fā)板作為從機?,F(xiàn)在讓我們從關(guān)于I2C通信的介紹開始吧。

什么是I2C通信協(xié)議?

術(shù)語IIC代表“Inter Integrated Circuits”。它通常表示為I2C或IIC,甚至在某些地方表示為2線接口協(xié)議(TWI),但它們代表的含義是一樣的。 I2C是同步通信協(xié)議,也就是說共享信息的設(shè)備必須共享公共時鐘信號。它只有兩根線來共享信息,其中一根用于時鐘信號,另一根用于發(fā)送和接收數(shù)據(jù)。

I2C通信如何工作?

I2C通信最初由Phillips引入。如前所述,它有兩根導線,這兩根導線將連接在兩個設(shè)備上。這里一個設(shè)備稱為主機,另一個設(shè)備稱為從機。通信應該并且將始終發(fā)生在一個主機和一個從機之間。 I2C通信的優(yōu)點是可以將多個從機連接到一個主機。

o4YBAF_bFX-ANZ1IAACK-JXPhYc302.png

完整的通信通過這兩條導線進行,即串行時鐘(SCL)和串行數(shù)據(jù)(SDA)。

● 串行時鐘(SCL):與主設(shè)備共享主設(shè)備生成的時鐘信號

● 串行數(shù)據(jù)(SDA):在主機和從機之間發(fā)送數(shù)據(jù)。

在任何給定時間,只有主機才能啟動通信。由于總線中有多個從站,因此主站必須使用不同的地址來引用每個從站。當被尋址時,只有具有該特定地址的從機將應答該信息,而其他地址繼續(xù)退出。這樣我們就可以使用相同的總線與多個設(shè)備進行通信。

I2C的電壓電平未預定義。 I2C通信靈活,意味著由5v電源供電的器件,可以使用5v用于I2C,3.3v器件可以使用3v進行I2C通信。但是,如果兩個運行在不同電壓下的設(shè)備需要使用I2C進行通信呢? 5V I2C總線不能與3.3V器件連接。在這種情況下,電壓移位器用于匹配兩個I2C總線之間的電壓電平。

有一些條件可以構(gòu)成傳輸。傳輸?shù)某跏蓟瘡腟DA的下降沿開始,在下圖中定義為“START”條件,其中主機將SCL設(shè)為高電平,同時將SDA設(shè)置為低電平。如下圖所示,

pIYBAF_bFYyAJb6zAAAWiXiEpZY108.png

SDA的下降沿是START條件的硬件觸發(fā)。在此之后,同一總線上的所有設(shè)備都進入監(jiān)聽模式。

同樣的,SDA的上升沿停止傳輸,在上圖中顯示為“STOP”條件,其中主機將SCL置為高電平并且還釋放SDA以變?yōu)楦唠娖健R虼?,SDA的上升沿會阻止傳輸。

pIYBAF_bFZaAOoSVAAALYSRDWog203.png

R / W位表示后續(xù)字節(jié)的傳輸方向,如果為高電平表示從機將發(fā)送,如果為低則表示主機將發(fā)送。

每個位在每個時鐘周期發(fā)送,因此傳輸一個字節(jié)需要8個時鐘周期。在發(fā)送或接收每個字節(jié)之后,保持第九個時鐘周期用于ACK / NACK(確認/未確認)。該ACK位由從機或主機根據(jù)情況生成。對于ACK位,SDA在第9個時鐘周期由主機或從機設(shè)置為低電平。所以它被認為是低,否則NACK。

pIYBAF_bFbGAGwdnAABpfusEOfM752.png

在哪里使用I2C通信?

I2C通信僅用于短距離通信。它在某種程度上肯定是可靠的,因為它具有同步的時鐘脈沖以使其智能化。該協(xié)議主要用于與必須向主設(shè)備發(fā)送信息的傳感器或其他設(shè)備進行通信。當微控制器必須使用最少的導線與許多其他從模塊通信時非常方便。如果您正在尋找遠程通信,您應該嘗試RS232,如果您正在尋找更可靠的通信,您應該嘗試SPI協(xié)議。

Arduino中的I2C

下圖顯示了Arduino UNO中的I2C引腳。

I2C總線Arduino中的引腳

SDAA4

SCLA5

在開始使用兩個Arduino編程I2C之前,我們需要了解Arduino IDE中使用的Wire庫。

庫《Wire.h》包含在程序中,用于使用以下I2C通信函數(shù)。

1. Wire.begin(address):

用途:該庫用于與I2C設(shè)備進行通信。初始化Wire庫,并作為從機或主機加入I2C總線。

address:7位從機地址是可選的,如果未指定地址,類似[Wire.begin()],將作為主機加入總線。

2. Wire.read():

用途:該函數(shù)用于讀取從主機或從機接收的字節(jié),該字節(jié)是在調(diào)用requestFrom()后從一個從機發(fā)送到主設(shè)備的字節(jié),或從主設(shè)備發(fā)送到從機的字節(jié)。

3. Wire.write():

用途:該函數(shù)用于將數(shù)據(jù)寫入從機或主機。

從機到主機:當主站中使用Wire.RequestFrom()時,從機將數(shù)據(jù)寫入主機。

主機到從機:從主機到從機的傳輸,Wire.write()用在調(diào)用Wire.beginTransmission()和Wire.endTransmission()之間。

Wire.write()可以寫成:

? Wire.write(value)

value:要作為單個字節(jié)發(fā)送的值。

? Wire.write(string):

string:要作為一系列字節(jié)發(fā)送的字符串。

? Wire.write(data,length):

data:要作為字節(jié)發(fā)送的數(shù)據(jù)數(shù)組

length:要傳輸?shù)淖止?jié)數(shù)。

4. Wire.beginTransmission(address):

用途:該函數(shù)用于開始使用給定的從地址傳輸?shù)絀2C設(shè)備。隨后,使用write()函數(shù)構(gòu)建用于傳輸?shù)淖止?jié)隊列,然后通過調(diào)用endTransmission()函數(shù)傳輸它們。

address:發(fā)送設(shè)備的7位地址。

5. Wire.endTransmission();

用途:此函數(shù)用于結(jié)束由beginTransmission()發(fā)起的從機的傳輸,并傳輸由Wire.write()排隊的字節(jié)。

6. Wire.onRequest();

用途:當主設(shè)備使用Wire.requestFrom()請求來自從設(shè)備的數(shù)據(jù)時,將調(diào)用此函數(shù)。這里我們可以包含Wire.write()函數(shù)來向主機發(fā)送數(shù)據(jù)。

7. Wire.onReceive();

用途:當從設(shè)備從主設(shè)備接收數(shù)據(jù)時,將調(diào)用此函數(shù)。這里我們可以包含Wire.read();用于讀取從主站發(fā)送的數(shù)據(jù)的函數(shù)。

8. Wire.requestFrom(addres,quantity);

用途:該函數(shù)在主設(shè)備中用于從從設(shè)備請求字節(jié)。函數(shù)Wire.read()用于讀取從設(shè)備發(fā)送的數(shù)據(jù)。

address:要從中請求字節(jié)的設(shè)備的7位地址

quantity:要請求的字節(jié)數(shù)

需要的組件

● Arduino Uno開發(fā)板

● 1602 LCD顯示模塊

● 10K電位器

● 面包板

● 連接導線

電路原理

pIYBAF_bFdCADV7NAAI_4gKk-ps581.png

工作過程

這里為了演示Arduino中的I2C通信,我們使用兩個Arduino UNO和兩個1602 LCD顯示器相互連接,并在兩個arduino開發(fā)板上使用兩個電位器來確定從主設(shè)備到從設(shè)備和從設(shè)備到主設(shè)備的發(fā)送值(0到127)通過改變電位器。

我們使用電位器將arduino引腳A0的輸入模擬值從(0到5V)轉(zhuǎn)換為模擬到數(shù)字值(0到1023)。然后,這些ADC值進一步轉(zhuǎn)換為(0到127),因為我們只能通過I2C通信發(fā)送7位數(shù)據(jù)。 I2C通信通過arduino的A4和A5引腳上的兩條線進行。

通過改變主機的電位器,從機Arduino開發(fā)板的LCD的值將發(fā)生變化,反之亦然。

Arduino中的I2C編程

本篇文章有兩個程序,一個用于主機Arduino,另一個用于從機Arduino。

主機Arduino編程介紹

1.首先,我們需要包含用于使用I2C通信功能的Wire庫和用于使用LCD功能的LCD庫。還需要為1602 LCD定義LCD引腳。

#include《Wire.h》

#include《LiquidCrystal.h》

LiquidCrystal lcd(2, 7, 8, 9, 10, 11);

2.在void setup()函數(shù)中,

我們以波特率9600啟動串行通信。

Serial.begin(9600);

接下來在引腳(A4,A5)上啟動I2C通信

Wire.begin(); //Begins I2C communication at pin (A4,A5)

接下來我們在1602模式下初始化LCD顯示模塊并顯示歡迎信息,然后在五秒后清除。

lcd.begin(16,2); //Initilize LCD display

lcd.setCursor(0,0); //Sets Cursor at first line of Display

lcd.print(“Circuit Digest”); //Prints CIRCUIT DIGEST in LCD

lcd.setCursor(0,1); //Sets Cursor at second line of Display

lcd.print(“I2C 2 ARDUINO”); //Prints I2C ARDUINO in LCD

delay(5000); //Delay for 5 seconds

lcd.clear(); //Clears LCD display

3.在void loop()函數(shù)中

首先,我們需要從Slave獲取數(shù)據(jù),因此我們使用requestFrom()和從地址8,我們請求一個字節(jié)

Wire.requestFrom(8,1);

使用Wire.read()讀取接收的值

byte MasterReceive = Wire.read();

接下來,我們需要讀取連接到引腳A0的主機arduino電位器的模擬值

int potvalue = analogRead(A0);

我們將該值轉(zhuǎn)換為0到127的字節(jié)。

byte MasterSend = map(potvalue,0,1023,0,127);

接下來我們需要發(fā)送轉(zhuǎn)換后的值,使用8地址開始從機sarduino的傳輸

Wire.beginTransmission(8);

Wire.write(MasterSend);

Wire.endTransmission();

接下來,我們顯示來自從機arduino的接收值,延遲為500微秒,我們不斷接收并顯示這些值。

lcd.setCursor(0,0); //Sets Currsor at line one of LCD

lcd.print(“》》 Master 《《”); //Prints 》》 Master 《《 at LCD

lcd.setCursor(0,1); //Sets Cursor at line two of LCD

lcd.print(“SlaveVal:”); //Prints SlaveVal: in LCD

lcd.print(MasterReceive); //Prints MasterReceive in LCD received from Slave

Serial.println(“Master Received From Slave”); //Prints in Serial Monitor

Serial.println(MasterReceive);

delay(500);

lcd.clear();

從機Arduino編程介紹

1.與主機設(shè)備相同,首先我們需要包含用于使用I2C通信功能的Wire庫和用于使用LCD功能的LCD庫。還為1602 LCD定義LCD引腳。

#include《Wire.h》

#include《LiquidCrystal.h》

LiquidCrystal lcd(2, 7, 8, 9, 10, 11);

2. 在void setup()函數(shù)中,

我們以波特率9600啟動串行通信。

Serial.begin(9600);

接下來在引腳(A4,A5)上啟動I2C通信,從地址設(shè)定為8。這里指定從地址非常重要。

Wire.begin(8);

接下來,當從機從主機接收值并且主機請求從機的值時,我們需要調(diào)用該函數(shù)

Wire.onReceive(receiveEvent);

Wire.onRequest(requestEvent);

接下來我們在16X2模式下初始化LCD顯示模塊并顯示歡迎信息,然后在五秒后清除。

lcd.begin(16,2); //Initilize LCD display

lcd.setCursor(0,0); //Sets Cursor at first line of Display

lcd.print(“Circuit Digest”); //Prints CIRCUIT DIGEST in LCD

lcd.setCursor(0,1); //Sets Cursor at second line of Display

lcd.print(“I2C 2 ARDUINO”); //Prints I2C ARDUINO in LCD

delay(5000); //Delay for 5 seconds

lcd.clear(); //Clears LCD display

3.接下來,我們有兩個函數(shù),一個用于請求事件,另一個用于接收事件

對于請求事件

當主機從從機請求值時,將執(zhí)行該函數(shù)。此函數(shù)從從機電位器獲取輸入值并以7位轉(zhuǎn)換,然后將該值發(fā)送給主機。

void requestEvent()

{

int potvalue = analogRead(A0);

byte SlaveSend = map(potvalue,0,1023,0,127);

Wire.write(SlaveSend);

}

對于接收事件

當主機通過從機地址(8)向從機發(fā)送數(shù)據(jù)時,將執(zhí)行該函數(shù)。此函數(shù)從主機讀取接收的值并存儲在byte類型的變量中。

void receiveEvent (int howMany)

{

SlaveReceived = Wire.read();

}

4. 在void loop()函數(shù)中:

我們在LCD顯示模塊中連續(xù)顯示主設(shè)備的接收值。

void loop(void)

{

lcd.setCursor(0,0); //Sets Currsor at line one of LCD

lcd.print(“》》 Slave 《《”); //Prints 》》 Slave 《《 at LCD

lcd.setCursor(0,1); //Sets Cursor at line two of LCD

lcd.print(“MasterVal:”); //Prints MasterVal: in LCD

lcd.print(SlaveReceived); //Prints SlaveReceived value in LCD received from Master

Serial.println(“Slave Received From Master:”); //Prints in Serial Monitor

Serial.println(SlaveReceived);

delay(500);

lcd.clear();

}

通過旋轉(zhuǎn)一側(cè)的電位器,您可以在另一側(cè)看到LCD上的變化值:

以上就是在Arduino中進行I2C通信的方式,這里我們不僅使用兩個Arduino開發(fā)板來演示通過I2C通信發(fā)送數(shù)據(jù),而且還演示了接收數(shù)據(jù)。所以現(xiàn)在你可以將任何I2C傳感器連接到Arduino。
編輯:hfy

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • lcd
    lcd
    +關(guān)注

    關(guān)注

    36

    文章

    4619

    瀏覽量

    177326
  • 電位器
    +關(guān)注

    關(guān)注

    14

    文章

    1028

    瀏覽量

    69273
  • I2C
    I2C
    +關(guān)注

    關(guān)注

    28

    文章

    1556

    瀏覽量

    131274
  • Arduino
    +關(guān)注

    關(guān)注

    190

    文章

    6526

    瀏覽量

    196991
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關(guān)推薦
    熱點推薦

    I2C 為什么只要兩根線就能搞定通信?

    到目前為止,我們已經(jīng)討論了SPI通信和UART通信的基礎(chǔ)知識,現(xiàn)在讓我們討論本系列的最后一個協(xié)議,即集成電路間協(xié)議(I2C)。如果您曾經(jīng)構(gòu)建過使用OLED顯示器、氣壓傳感器或陀螺儀/加速度計模塊
    的頭像 發(fā)表于 01-04 09:14 ?1707次閱讀
    <b class='flag-5'>I2C</b> 為什么只要兩根線就能搞定<b class='flag-5'>通信</b>?

    基于FPGA的I2C控制模塊設(shè)計

    I2C_WRITE_WDATA.v模塊實現(xiàn)I2C寫時序,I2C_Controller (I2C控制器)例化了I2C_WRITE_WDATA.
    的頭像 發(fā)表于 12-26 09:48 ?5076次閱讀
    基于FPGA的<b class='flag-5'>I2C</b>控制模塊設(shè)計

    CW32 I2C接口的主要特性

    CW32F030 內(nèi)部集成 2I2C 控制器,能按照設(shè)定的傳輸速率(標準,快速,高速)將需要發(fā)送數(shù)據(jù)按照 I2C規(guī)范串行
    發(fā)表于 12-16 07:51

    I2C的總線協(xié)議

    用狀態(tài)。 I2C 通信采用主從結(jié)構(gòu),并由主機發(fā)起和結(jié)束通信。主機通過發(fā)送 START 起始信號來發(fā)起通信,之后
    發(fā)表于 12-15 08:07

    I2C的狀態(tài)碼

    I2C 總線狀態(tài)通過 I2C 狀態(tài)寄存器 I2Cx_STAT 來標識,共 26 個正常接收或發(fā)送狀態(tài),和 2 個特殊狀態(tài)(0xF8:
    發(fā)表于 12-08 08:04

    如何在CW32 MCU上優(yōu)化I2C通信

    CW32 MCU中的實現(xiàn),包括數(shù)據(jù)傳輸模式、時序要求以及如何通過CW32的I2C接口進行配置和管理。 頻率調(diào)節(jié)對I2C通信的影響:
    發(fā)表于 11-27 06:25

    基于芯源CW32F030 MCU的I2C通信及應用

    。 停止通信發(fā)送停止信號,結(jié)束數(shù)據(jù)傳輸。 5. 實例代碼:I2C讀寫EEPROM下面的代碼展示了如何使用CW32F030 MCU通過I2C
    發(fā)表于 11-18 08:29

    深入剖析I2C協(xié)議

    I2C是由Philips開發(fā)的簡單的雙向兩線總線,在深入淺出理解SPI協(xié)議中,我們區(qū)分了單工,半雙工,全雙工協(xié)議數(shù)據(jù)流向的區(qū)別,根據(jù)特征,I2C協(xié)議屬于半雙工協(xié)議(即同一時刻,數(shù)據(jù)單向
    的頭像 發(fā)表于 08-21 15:10 ?3693次閱讀
    深入剖析<b class='flag-5'>I2C</b>協(xié)議

    I2C通信異常問題怎么解決?

    我們在進行I2C通信,發(fā)現(xiàn)當寫數(shù)據(jù)時SCL和SDA會有下降沿重合的情況,導致通信失敗,請幫忙分析
    發(fā)表于 08-12 07:45

    I2C總線通信,為什么要進行電氣隔離?

    I2C總線采用雙向二線制,支持多主機多從機通信,具備高可靠性、抗干擾能力強,廣泛應用于嵌入式系統(tǒng)中。
    的頭像 發(fā)表于 08-11 11:04 ?2525次閱讀
    <b class='flag-5'>I2C</b>總線<b class='flag-5'>通信</b>,為什么要<b class='flag-5'>進行</b>電氣隔離?

    第十八章 I2C通信測試

    本章介紹了I2C協(xié)議,其物理層用SDA和SCL雙線,支持多設(shè)備:協(xié)議層含起始/停止信號、應答機制等。還講解W55MH32的I2C外設(shè)及初始化,并進行通信測試代碼的
    的頭像 發(fā)表于 06-19 17:07 ?1325次閱讀
    第十八章 <b class='flag-5'>I2C</b><b class='flag-5'>通信</b>測試

    CYPD3177 I2C通信無應答怎么解決?

    SOC端通過I2C與CYPD3177進行通信,在讀芯片ID時(0x0002寄存器),主機發(fā)送數(shù)據(jù)后無應答。目前SOC端和CYPD3177只連
    發(fā)表于 05-12 07:10

    嵌入式學習-飛凌嵌入式ElfBoard ELF 1板卡-I2C設(shè)備驅(qū)動之Linux下的I2C驅(qū)動簡介

    在Linux下,I2C(Inter-Integrated Circuit)驅(qū)動是用于支持I2C總線協(xié)議的驅(qū)動程序。I2C是一種串行通信協(xié)議,用于在集成電路之間
    發(fā)表于 04-15 10:39

    飛凌嵌入式ElfBoard ELF 1板卡-I2C設(shè)備驅(qū)動之Linux下的I2C驅(qū)動簡介

    在Linux下,I2C(Inter-Integrated Circuit)驅(qū)動是用于支持I2C總線協(xié)議的驅(qū)動程序。I2C是一種串行通信協(xié)議,用于在集成電路之間
    發(fā)表于 04-15 10:19

    是德DSOX4034A示波器I2C總線信號分析

    在現(xiàn)代電子設(shè)計與調(diào)試中,I2C(Inter-Integrated Circuit)總線作為一種廣泛應用的串行通信協(xié)議,因其簡單性、靈活性和低功耗特性,成為許多嵌入式系統(tǒng)和電子設(shè)備中不可或缺的通信方式
    的頭像 發(fā)表于 03-19 13:47 ?1257次閱讀
    是德DSOX4034A示波器<b class='flag-5'>I2C</b>總線信號<b class='flag-5'>分析</b>