一区二区三区三上|欧美在线视频五区|国产午夜无码在线观看视频|亚洲国产裸体网站|无码成年人影视|亚洲AV亚洲AV|成人开心激情五月|欧美性爱内射视频|超碰人人干人人上|一区二区无码三区亚洲人区久久精品

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

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

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

一文深入理解IIC通信基礎(chǔ)知識(shí)

碼農(nóng)愛(ài)學(xué)習(xí) ? 來(lái)源:碼農(nóng)愛(ài)學(xué)習(xí) ? 作者:碼農(nóng)愛(ài)學(xué)習(xí) ? 2022-06-08 09:06 ? 次閱讀

單片機(jī)的朋友都知道IIC通信這個(gè)工具,但好多人只是會(huì)用,內(nèi)部的原理不求甚解,或是想要了解其原理,但卻對(duì)抽象的時(shí)序描述一頭霧水。本文將從實(shí)測(cè)的IIC波形入手,帶你看到真實(shí)的IIC樣子,進(jìn)而去理解IIC的通信原理。

IIC基礎(chǔ)知識(shí)

首先復(fù)習(xí)一下IIC基礎(chǔ)知識(shí),這部分看不懂的請(qǐng)先帶著疑問(wèn),然后我們通過(guò)分析IIC的真實(shí)波形,這些疑問(wèn)可能就豁然開(kāi)朗了~

IIC是什么

IIC(Inter Integrated Circuit,集成電路總線)是一種由 PHILIPS 公司開(kāi)發(fā)的兩線式串行總線,用于連接微控制器及其外圍設(shè)備。它是由數(shù)據(jù)線 SDA時(shí)鐘 SCL 構(gòu)成的串行總線,可發(fā)送和接收數(shù)據(jù)。在 CPU (單片機(jī))與IIC模塊之間、IIC模塊與IIC模塊之間進(jìn)行雙向傳送。

IIC的一些特點(diǎn):

IIC是半雙工,而不是全雙工

IIC是真正的多主機(jī)總線,(對(duì)比SPI在每次通信前都需要把主機(jī)定死,而IIC可以在通訊過(guò)程中,改變主機(jī)),如果兩個(gè)或更多的主機(jī)同時(shí)請(qǐng)求總線,可以通過(guò)沖突檢測(cè)和仲裁防止總線數(shù)據(jù)被破壞

起始和終止信號(hào)都是由主機(jī)發(fā)出的,連接到I2C總線上的器件,若具有I2C總線的硬件接口,則很容易檢測(cè)到起始和終止信號(hào)

起始信號(hào)后必須發(fā)送一個(gè)7位從機(jī)地址+1位方向位,用“0”表示主機(jī)發(fā)送數(shù)據(jù),“1”表示主機(jī)接收數(shù)據(jù)。

每當(dāng)主機(jī)向從機(jī)發(fā)送完一個(gè)字節(jié)的數(shù)據(jù),主機(jī)總是需要等待從機(jī)給出一個(gè)應(yīng)答信號(hào),以確認(rèn)從機(jī)是否成功接收到了數(shù)據(jù)

起始信號(hào)是必需的,結(jié)束信號(hào)和應(yīng)答信號(hào),都可以不要

:實(shí)際使用中,一般是單片機(jī)作為主機(jī),其它器件作為從機(jī),單片機(jī)先向器件發(fā)送信息表示要讀取數(shù)據(jù),之后轉(zhuǎn)變傳輸方向,器件發(fā)送數(shù)據(jù)到單片機(jī)。

IIC物理連接

使用IIC通信的IIC器件有很多,比如陀螺儀加速度計(jì)MPU6050,EEPROM存儲(chǔ)芯片AT24C02等,通過(guò)IIC總線,可以與單片機(jī)之間進(jìn)行數(shù)據(jù)傳輸。

IIC通信線只有只有兩根,數(shù)據(jù)線SDA的高低電平傳輸2進(jìn)制的數(shù)據(jù),時(shí)鐘線SCL通過(guò)方波信號(hào)提供時(shí)鐘節(jié)拍

多個(gè)IIC器件可以并聯(lián)在IIC總線上,每個(gè)器件有特定的地址,分時(shí)共享IIC總線

實(shí)際使用IIC當(dāng)然還要連接電源以及共地哦

pYYBAGKfaFSAHCH-AAAlpEErPGw798.png

IIC時(shí)序

網(wǎng)上查找IIC的基礎(chǔ)知識(shí),可能會(huì)搜到這樣的時(shí)序圖:

poYBAGKfaGOADGDoAABmSQIz0NU683.png

看起來(lái)好復(fù)雜的樣子,這時(shí)可能一部分人就放棄思考了。

IIC起始結(jié)束信號(hào)

好吧,換個(gè)簡(jiǎn)單點(diǎn)的圖,你也可能會(huì)搜到這樣的圖:

pYYBAGKfaH-ABmpgAABlS3bo2aI315.png

這張圖看起來(lái)更簡(jiǎn)單一些,描述了IIC的起始和停止條件:

起始:時(shí)鐘線SCL為高時(shí),數(shù)據(jù)線SDA由高到低

停止:時(shí)鐘線SCL為高時(shí),數(shù)據(jù)線SDA由低到高

注:SDA和SCL同時(shí)為高時(shí),為IIC總線的空閑狀態(tài)

IIC應(yīng)答

再來(lái)看下面這張圖:

pYYBAGKfaIqAK4NTAABgKyp6IUQ665.png

這表示IIC的應(yīng)答機(jī)制

下面的波形:SCL,主機(jī)產(chǎn)生的時(shí)鐘脈沖

上面的波形:SDA,主機(jī)發(fā)送的8位數(shù)據(jù)

中間的波形:SDA,從機(jī)在第9個(gè)時(shí)鐘信號(hào)進(jìn)行拉低回應(yīng),表示收到了主機(jī)發(fā)來(lái)的數(shù)據(jù),拉高則表示不應(yīng)答

注:實(shí)際上,上面和中間是同樣的SDA線,這里只是分開(kāi)示意。因?yàn)镮IC應(yīng)答是一種相互關(guān)系,單片機(jī)發(fā)數(shù)據(jù)給IIC器件,IIC器件要進(jìn)行應(yīng)答,表示收到了數(shù)據(jù),同樣,單片機(jī)接收IIC器件的數(shù)據(jù)后,也要給IIC器件一個(gè)應(yīng)答。

既然發(fā)送完都需要對(duì)方回應(yīng),那什么時(shí)候使用不應(yīng)答呢?就是在讀取到本次數(shù)據(jù)后,如果不需要繼續(xù)讀取,則發(fā)送非應(yīng)答,對(duì)方以為你沒(méi)收到這次數(shù)據(jù),則就不會(huì)繼續(xù)發(fā)送了。

IIC完整傳輸時(shí)序

poYBAGKfaJaAH-IVAACa3k2t5KE949.png

開(kāi)始標(biāo)志(S)發(fā)出后,主設(shè)備會(huì)傳送一個(gè)7 位的Slave 地址,并且后面跟著一個(gè)第8位,稱為Read/Write 位。

R/W 位表示主設(shè)備是在接受從設(shè)備的數(shù)據(jù)還是在向其寫(xiě)數(shù)據(jù)。

然后,主設(shè)備釋放SDA 線,等待從設(shè)備的應(yīng)答信號(hào)(ACK)。每個(gè)字節(jié)的傳輸都要跟隨有一個(gè)應(yīng)答位。

應(yīng)答產(chǎn)生時(shí),從設(shè)備將SDA 線拉低并且在SCL 為高電平時(shí)保持低。

數(shù)據(jù)傳輸以停止標(biāo)志(P)結(jié)束,然后釋放總線。但主設(shè)備也可以產(chǎn)生重復(fù)的開(kāi)始信號(hào)去操作另一臺(tái)從設(shè)備,而不發(fā)出結(jié)束標(biāo)志。

所有的SDA 信號(hào)變化都要在SCL 時(shí)鐘為低電平時(shí)進(jìn)行,除了開(kāi)始和結(jié)束標(biāo)志

常用的數(shù)據(jù)收發(fā)方式(時(shí)序)

上面1.3小節(jié)是IIC的基礎(chǔ)時(shí)序,在實(shí)際使用中,一般是對(duì)某個(gè)IIC器件的某個(gè)寄存器進(jìn)行讀寫(xiě)操作,因此,對(duì)于寄存器的讀寫(xiě)操作,還要遵循下面的組合時(shí)序邏輯。

寫(xiě)一個(gè)字節(jié)

用于對(duì)IIC器件某個(gè)寄存器的配置,如對(duì)MPU6050的某些參數(shù)進(jìn)行設(shè)置。

pYYBAGKfaKSAdV79AAAaEqp1V38144.png

寫(xiě)寄存器時(shí),主設(shè)備除了發(fā)出開(kāi)始標(biāo)志和地址位,還要加一個(gè)R/W 位,0 為寫(xiě),1 為讀

在第9 個(gè)時(shí)鐘周期(高電平時(shí)),MPU6050 產(chǎn)生應(yīng)答信號(hào)

主設(shè)備開(kāi)始傳送寄存器地址,并接到應(yīng)答

然后開(kāi)始傳送寄存器數(shù)據(jù),仍然要有應(yīng)答信號(hào)

最后主設(shè)備發(fā)送停止信號(hào)。

連續(xù)寫(xiě)多個(gè)字節(jié)

對(duì)連續(xù)地址的寫(xiě)入,這個(gè)用的較少。

pYYBAGKfaLeAIbleAAAb767OGAs536.png

通信時(shí)序與上面的“寫(xiě)一個(gè)字節(jié)”類似,上面是寫(xiě)一個(gè)字節(jié)后就停止了,若要連續(xù)寫(xiě),則繼續(xù)寫(xiě)即可,只要可以收到從機(jī)Ack。

讀一個(gè)字節(jié)

用于讀取IIC器件某個(gè)寄存器的數(shù)值。

poYBAGKfaMOAHYdKAAAeiCBiwpg399.png

首先由主設(shè)備產(chǎn)生開(kāi)始信號(hào),然后發(fā)送從設(shè)備地址位和一個(gè)寫(xiě)數(shù)據(jù)位,等待應(yīng)答

然后發(fā)送寄存器地址,才能開(kāi)始讀寄存器

收到應(yīng)答信號(hào)后,主設(shè)備再發(fā)一個(gè)開(kāi)始信號(hào),然后發(fā)送從設(shè)備地址位和一個(gè)讀數(shù)據(jù)位

然后,作為從設(shè)備的MPU6050 產(chǎn)生應(yīng)答信號(hào)并開(kāi)始發(fā)送寄存器中的數(shù)據(jù)

通信以主設(shè)備產(chǎn)生的拒絕應(yīng)答信號(hào)(nACK)和結(jié)束標(biāo)志(Stop)結(jié)束

拒絕應(yīng)答信號(hào)(nACK)產(chǎn)生定義為SDA 數(shù)據(jù)在第9 個(gè)時(shí)鐘周期一直為高

連續(xù)讀多個(gè)字節(jié)

也是用于讀取IIC器件某個(gè)寄存器的數(shù)值,當(dāng)某些數(shù)據(jù)一位字節(jié)不夠表示,或有一組連續(xù)的數(shù)據(jù)需要讀時(shí),可以使用該模式。

poYBAGKfaNGASny3AAAhIbef6SE086.png

通信時(shí)序與上面的“讀一個(gè)字節(jié)”類似,上面是讀一個(gè)字節(jié)后就nAck叫停,若要連續(xù)寫(xiě),則發(fā)送Ack,直到不需要繼續(xù)讀時(shí)再回復(fù)nAck。

復(fù)習(xí)了這么多,之前對(duì)IIC懵懵懂懂的是否依然犯迷糊,好了,現(xiàn)在從理論進(jìn)入實(shí)踐,看看真實(shí)的IIC是什么樣子。

初識(shí)IIC真實(shí)波形

下面這張圖是通過(guò)示波器抓取的IIC波形,可以看到:

時(shí)鐘線SCL是一種間歇性的方波(需要通信時(shí)才產(chǎn)生方波)

數(shù)據(jù)線SDA根據(jù)SCL提供的節(jié)拍,高電平代表數(shù)據(jù)1,低電平代表數(shù)據(jù)0

沒(méi)有數(shù)據(jù)傳輸時(shí),SDA和SCL均為高電平狀態(tài)

起始信號(hào)后,數(shù)據(jù)是9個(gè)一組,包括8位的數(shù)據(jù)和另一方的1位回應(yīng)

圖中紅色數(shù)字表示單片機(jī)發(fā)送的8位數(shù)據(jù),黃色數(shù)字表示IIC器件回應(yīng)的信號(hào),低電平0表示器件收到了單片機(jī)發(fā)來(lái)的數(shù)據(jù)。

pYYBAGKfaOKAT4mhAAIF79_FEk8005.png

現(xiàn)在對(duì)IIC波形有沒(méi)有多了一些直觀的認(rèn)識(shí)?下面再進(jìn)入編程階段,看看程序是怎么控制這兩根線的。

編寫(xiě)IIC通信函數(shù)

IIC通信可以使用單片機(jī)自帶的硬件IIC,它提供了固定的引腳接口和函數(shù)庫(kù)。也可以自己通過(guò)軟件編寫(xiě)來(lái)實(shí)現(xiàn)IIC時(shí)序,這時(shí)就可以任選引腳,也方便其它硬件平臺(tái)的移植。

下面通過(guò)軟件IIC的編寫(xiě),從軟件角度理解IIC通信邏輯。

以下函數(shù)都是單片機(jī)在執(zhí)行,即主機(jī)發(fā)出的動(dòng)作,所以一定要從單片機(jī)的角度思考哦~

另外,不要看到程序就匆匆掠過(guò),為幫助理解,我對(duì)代碼進(jìn)行了一定的注解,仔細(xì)分析每條代碼,想想與IIC的邏輯如何對(duì)應(yīng)起來(lái),IIC邏輯還沒(méi)懂的,讀完本篇,分析過(guò)真實(shí)的IIC波形后,再來(lái)看看代碼,會(huì)有不一樣的體會(huì)。

起始IIC_Start()

//==================================
//產(chǎn)生IIC起始信號(hào)
//==================================
void IIC_Start(void)
{
	SDA_OUT();   //sda線輸出
	IIC_SDA=1;	  
	delay_us(2);	
	IIC_SCL=1;   //時(shí)鐘線為高時(shí)
	delay_us(2);
 	IIC_SDA=0;   //數(shù)據(jù)線由高到低
	delay_us(4);
	IIC_SCL=0;   //時(shí)鐘線拉低,鉗住IIC總線,準(zhǔn)備發(fā)送數(shù)據(jù) 
}

最后一句SCL拉低,然后就準(zhǔn)備產(chǎn)生時(shí)鐘信號(hào),發(fā)送數(shù)據(jù)了。

停止IIC_Stop()

//==================================
//產(chǎn)生IIC停止信號(hào)
//==================================
void IIC_Stop(void)
{
	SDA_OUT();  //sda線輸出
	IIC_SCL=0;  //確保時(shí)鐘線為低時(shí),數(shù)據(jù)線才能變化為0,否則這就可能成起始信號(hào)了!
	delay_us(2);
	IIC_SDA=0;
 	delay_us(2);
	IIC_SCL=1;  //時(shí)鐘線為高時(shí)
	IIC_SDA=1;  //數(shù)據(jù)線由低到高
	delay_us(4);							   	
}

停止前也要確保SCL是拉低的狀態(tài)。

最后SDA和SCL都為高,即釋放IIC總線,IIC總線進(jìn)入空閑狀態(tài)。

等待應(yīng)答IIC_wait_Ack()

//==================================
//等待應(yīng)答信號(hào)到來(lái)
//用于發(fā)送模式下,發(fā)送8位后,等待器件應(yīng)答第9位
//返回值:1,接收應(yīng)答失敗
//        0,接收應(yīng)答成功
//==================================
u8 IIC_Wait_Ack(void)
{
	u8 ucErrTime=0;
	SDA_IN();                 //SDA設(shè)置為輸入  
	IIC_SDA=1;delay_us(1);	  //SDA先拉高,若被從機(jī)拉低則說(shuō)明收到應(yīng)答信號(hào)
	IIC_SCL=1;delay_us(1);	  //SCL拉高,產(chǎn)生第9位的脈沖
	while(READ_SDA)
	{
		ucErrTime++;
		if(ucErrTime>250)
		{
			IIC_Stop();
			return 1;
		}
	}
	IIC_SCL=0;//時(shí)鐘輸出0 	  //SCL拉低,結(jié)束第9位的脈沖 
	return 0;  
} 

在一定是時(shí)間內(nèi)檢測(cè)SDA是否被從機(jī)拉低,被拉低則說(shuō)明從機(jī)收到了數(shù)據(jù)。

產(chǎn)生應(yīng)答IIC_Ack()

//==================================
//產(chǎn)生ACK應(yīng)答
//用于讀取模式(SDA為in)讀了8位器件數(shù)據(jù)后,在第9位給出一個(gè)應(yīng)答,我還要繼續(xù)讀
//==================================
void IIC_Ack(void)
{
	IIC_SCL=0;    //確保時(shí)鐘線為低時(shí),數(shù)據(jù)線才能變化為0,否則這就可能成起始信號(hào)了!
	SDA_OUT();    //SDA由讀取改為發(fā)送
	delay_us(2);
	IIC_SDA=0;    //拉低SDA,表示應(yīng)答
	delay_us(2);
	IIC_SCL=1;    //SCL先上升
	delay_us(2);
	IIC_SCL=0;    //SCL再下降,形成一個(gè)脈沖,應(yīng)答才生效
}

單片機(jī)在接收器件數(shù)據(jù)后,進(jìn)行回應(yīng),表示接收到了器件的數(shù)據(jù)。

該函數(shù)用在連續(xù)讀取多個(gè)字節(jié)時(shí),每讀完一個(gè)字節(jié)(8位),產(chǎn)生回應(yīng),表示還要進(jìn)行讀,這時(shí)器件就可以繼續(xù)發(fā)數(shù)據(jù)了。

當(dāng)單片機(jī)不需要繼續(xù)讀,如連續(xù)讀的最后一個(gè)字節(jié),或只讀一個(gè)字節(jié),單片機(jī)發(fā)送非應(yīng)答信號(hào),這時(shí)器件以為單片機(jī)沒(méi)有收到數(shù)據(jù),接下來(lái)就不會(huì)再發(fā)數(shù)據(jù)了。

非應(yīng)答函數(shù)如下,就是拉高SDA:

不產(chǎn)生應(yīng)答IIC_nAck()

//==================================
//不產(chǎn)生ACK應(yīng)答	
//用于讀取模式(SDA為in)讀了8位器件數(shù)據(jù)后,在第9位給出一個(gè)應(yīng)答,我不想讀了
//==================================
void IIC_NAck(void)
{
	IIC_SCL=0;    //確保時(shí)鐘線為低時(shí),數(shù)據(jù)線才能變化為0,否則這就可能成起始信號(hào)了!
	SDA_OUT();    //SDA由讀取改為發(fā)送
	IIC_SDA=1;    //拉高SDA,表示不應(yīng)答
	delay_us(2);
	IIC_SCL=1;    //SCL先上升
	delay_us(2);
	IIC_SCL=0;    //SCL再下降,形成一個(gè)脈沖,不應(yīng)答才生效
}

IIC發(fā)送一個(gè)字節(jié)

//==================================
//IIC發(fā)送一個(gè)字節(jié)
//返回從機(jī)有無(wú)應(yīng)答
//1,有應(yīng)答
//0,無(wú)應(yīng)答	
//==================================
void IIC_Send_Byte(u8 txd)
{                        
    u8 t;   
	SDA_OUT(); 	               //SDA發(fā)送模式
    IIC_SCL=0;                 //拉低時(shí)鐘開(kāi)始數(shù)據(jù)傳輸
    for(t=0;t<8;t++)
    {              
        IIC_SDA=(txd&0x80)>>7; //SDA高低電平表示數(shù)據(jù)1和0
        txd<<=1; 	  
        delay_us(2);           //對(duì)TEA5767這三個(gè)延時(shí)都是必須的
        IIC_SCL=1;             //SCL先上升
        delay_us(2); 
        IIC_SCL=0;	           //SCL再下降,形成一個(gè)脈沖,發(fā)送一位數(shù)據(jù)生效
        delay_us(2);
    }	 
} 

發(fā)送一個(gè)字節(jié),就是分8次循環(huán),產(chǎn)生8個(gè)時(shí)鐘信號(hào),并將SDA賦值為0或1。

IIC讀取一個(gè)字節(jié)

//==================================
//讀1個(gè)字節(jié)
//ack=1時(shí),發(fā)送ACK,ack=0,發(fā)送nACK  
//==================================
u8 IIC_Read_Byte(unsigned char ack)
{
	unsigned char i,receive=0;
	SDA_IN();                  //SDA輸入模式
    for(i=0;i<8;i++ )
	{
        IIC_SCL=0;             //SCL先下降,通過(guò)循環(huán),形成時(shí)鐘脈沖
        delay_us(2);
		IIC_SCL=1;             //SCL上升
        receive<<=1;
        if(READ_SDA)
			receive++;         //讀取并組合記錄數(shù)據(jù),++表示讀到1了,最低位置1
		delay_us(1); 
    }	
    //讀取8位后,主機(jī)需要變?yōu)榘l(fā)送模式,在第9位進(jìn)行應(yīng)答或不應(yīng)答
    //此時(shí)CLK還是高電平狀態(tài),不過(guò)下面的應(yīng)答會(huì)先將CLK拉低的	
    if (!ack)
	{
		//讀1個(gè)字節(jié),或讀多個(gè)字節(jié)讀到最后一個(gè)字節(jié)時(shí),使用nACK
		//然后配合使用IIC停止信號(hào)
        IIC_NAck();//發(fā)送nACK
	}
    else
	{
		//讀多個(gè)字節(jié)還沒(méi)讀完時(shí),使用ACK,表示現(xiàn)在讀的ok,還要繼續(xù)讀
        IIC_Ack(); //發(fā)送ACK 
	}		
    return receive;
}

讀取一個(gè)字節(jié),也是分8次循環(huán),產(chǎn)生8個(gè)時(shí)鐘信號(hào),并讀取SDA的高低電平信號(hào),最后,根據(jù)要不要繼續(xù)讀下一個(gè)字節(jié),發(fā)送第9位的Ack或nACK。

真實(shí)IIC波形詳細(xì)分析

讀取從機(jī)數(shù)據(jù)(單字節(jié)讀)

這張圖展示IIC讀某個(gè)器件的寄存器的一個(gè)字節(jié)的真實(shí)波形(注:實(shí)際是讀了2個(gè)不同寄存器的值,每個(gè)寄存器讀了1個(gè)字節(jié),所以,可以先只看前半部分哦~),我已對(duì)波形進(jìn)行了詳細(xì)的注解。

對(duì)照著圖,再來(lái)溫習(xí)一下各個(gè)信號(hào)的特點(diǎn):

起始信號(hào):時(shí)鐘線SCL為高時(shí),數(shù)據(jù)線SDA由高到低

停止信號(hào):時(shí)鐘線SCL為高時(shí),數(shù)據(jù)線SDA由低到高

數(shù)據(jù)信號(hào):連續(xù)的8位,每一個(gè)SCL脈沖時(shí)鐘對(duì)應(yīng)的SDA,高電平為數(shù)據(jù)1,低電平為數(shù)據(jù)0

應(yīng)答信號(hào):第9位(數(shù)據(jù)信號(hào)后),由對(duì)方產(chǎn)生的回應(yīng),0為產(chǎn)生回應(yīng),1為不產(chǎn)生回應(yīng)

這幅圖中,單片機(jī)先產(chǎn)生起始信號(hào),然后發(fā)送7位器件地址+1位寫(xiě)標(biāo)志(綠色的0),并等待從機(jī)回應(yīng)(從機(jī)拉低SDA表示收到數(shù)據(jù)),接著發(fā)送8位寄存器地址,并等待從機(jī)回應(yīng)。然后,單片機(jī)先再次產(chǎn)生起始信號(hào),發(fā)送7位器件地址+1位讀標(biāo)志(綠色的1),并等待從機(jī)回應(yīng)。從機(jī)收到讀的信號(hào)后,從機(jī)開(kāi)始發(fā)送8位數(shù)據(jù),主機(jī)接收到數(shù)據(jù)后,主機(jī)發(fā)送nAck不應(yīng)答信號(hào)(圖中的Ack(1),主機(jī)將SDA拉高,從機(jī)則認(rèn)為主機(jī)剛才沒(méi)有收到它發(fā)送的數(shù)據(jù),從機(jī)將不再繼續(xù)發(fā)送),接著主機(jī)發(fā)送結(jié)束信號(hào),讀取完成。

此圖后半部分是以相同方式讀了另一個(gè)寄存器的值。

poYBAGKfaPSAf47XAAYkHNGhzUQ673.png

上圖中,SCL信號(hào)都是由單片機(jī)產(chǎn)生,SDA信號(hào)由單片機(jī)和IIC器件(從機(jī))共同產(chǎn)生,當(dāng)需要對(duì)IIC器件的寄存器寫(xiě)時(shí),單片機(jī)產(chǎn)生SDA數(shù)據(jù),當(dāng)需要讀取IIC器件的寄存器數(shù)據(jù)時(shí),改變傳輸方向,IIC器件產(chǎn)生SDA數(shù)據(jù)。

對(duì)于主機(jī)和從機(jī)什么時(shí)候控制SDA,還可以參考這個(gè)圖幫助理解:

pYYBAGKfaP6AbiLqAADbhuF0ltk485.png

讀取從機(jī)數(shù)據(jù)(多字節(jié)讀)

上面是單字節(jié)讀的波形,再來(lái)看看多字節(jié)的波形,前面的寫(xiě)器件地址、寫(xiě)寄存器地址1與單字節(jié)讀一樣,這張圖只顯示了后面不一樣的部分,主要區(qū)別在于單片機(jī)接收到數(shù)據(jù)1后,產(chǎn)生低電平的應(yīng)答,從而可以繼續(xù)讀取數(shù)據(jù)2。

(注意,因?yàn)?a target="_blank">傳感器這次測(cè)得的數(shù)據(jù)不一樣,所以讀出的數(shù)據(jù)也不一樣哦~)

pYYBAGKfaQaASh97AAFnIed3FTo211.png

注:以上的IIC真實(shí)波形,是使用是硬件IIC,自己編寫(xiě)的軟件IIC測(cè)得的波形,可能在兩個(gè)信號(hào)的前后延時(shí)時(shí)間上稍有差別,但整體的時(shí)序邏輯肯定是一樣的。

配置從機(jī)寄存器(單字節(jié)寫(xiě)與多字節(jié)寫(xiě))

對(duì)于寄存器的配置,也就是IIC的寫(xiě)寄存器操作,我就不放圖了,參考上面的“常用的數(shù)據(jù)收發(fā)方式(時(shí)序)”以及上面的IIC讀寄存器的真實(shí)波形,IIC的寫(xiě)寄存器的真實(shí)波形,應(yīng)該可以腦補(bǔ)出哦,哈哈~

最后

通過(guò)真實(shí)的IIC波形分析,對(duì)IIC通信邏輯有沒(méi)有更加直觀的認(rèn)識(shí)呢?

審核編輯:湯梓紅

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

    關(guān)注

    10

    文章

    2936

    瀏覽量

    89149
  • 波形
    +關(guān)注

    關(guān)注

    3

    文章

    386

    瀏覽量

    32004
  • IIC通信
    +關(guān)注

    關(guān)注

    0

    文章

    19

    瀏覽量

    3125
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    深入理解Android

    深入理解Android
    發(fā)表于 08-20 15:30

    深入理解和實(shí)現(xiàn)RTOS_連載

    和trcohili的帖子。深入理解和實(shí)現(xiàn)RTOS_連載1_RTOS的前生今世今天發(fā)布的是第篇,"RTOS的前生今世"。通過(guò)軟件系統(tǒng)結(jié)構(gòu)的比對(duì)簡(jiǎn)要的介紹rtos為何而生。如果讀者對(duì)RTOS
    發(fā)表于 05-29 11:20

    深入理解和實(shí)現(xiàn)RTOS_連載

    ,其中的每個(gè)任務(wù)都專注自己處理的問(wèn)題,而這些任務(wù)間則需要處理下彼此的溝通問(wèn)題......深入理解和實(shí)現(xiàn)RTOS_連載3_多任務(wù)機(jī)制設(shè)計(jì)前面我們已經(jīng)介紹過(guò)了在單核處理器上的多任務(wù)機(jī)制的基本知識(shí)。如果讀者
    發(fā)表于 05-30 01:02

    深入理解C語(yǔ)言比較有用的幾個(gè)資料

    這里有三個(gè)對(duì)深入理解C語(yǔ)言的資料,覺(jué)得不錯(cuò),分享
    發(fā)表于 08-07 21:37

    深入理解lte-a

    深入理解LTE-A
    發(fā)表于 02-26 10:21

    深入理解STM32

    時(shí)鐘系統(tǒng)是處理器的核心,所以在學(xué)習(xí)STM32所有外設(shè)之前,認(rèn)真學(xué)習(xí)時(shí)鐘系統(tǒng)是必要的,有助于深入理解STM32。下面是從網(wǎng)上找的個(gè)STM32時(shí)鐘框圖,比《STM32中參考手冊(cè)》里面的是中途看起來(lái)清晰
    發(fā)表于 08-12 07:46

    對(duì)棧的深入理解

    為什么要深入理解棧?做C語(yǔ)言開(kāi)發(fā)如果棧設(shè)置不合理或者使用不對(duì),棧就會(huì)溢出,溢出就會(huì)遇到無(wú)法預(yù)測(cè)亂飛現(xiàn)象。所以對(duì)棧的深入理解是非常重要的。注:動(dòng)畫(huà)如果看不清楚可以電腦看更清晰啥是棧先來(lái)看段動(dòng)畫(huà):沒(méi)有
    發(fā)表于 02-15 07:01

    為什么要深入理解

    [導(dǎo)讀] 從這篇文章開(kāi)始,將會(huì)不定期更新關(guān)于嵌入式C語(yǔ)言編程相關(guān)的個(gè)人認(rèn)為比較重要的知識(shí)點(diǎn),或者踩過(guò)的坑。為什么要深入理解棧?做C語(yǔ)言開(kāi)發(fā)如果棧設(shè)置不合理或者使用不對(duì),棧就會(huì)溢出,溢出就會(huì)遇到無(wú)法
    發(fā)表于 02-15 06:09

    深入理解Android之資源文件

    深入理解Android之資源文件
    發(fā)表于 01-22 21:11 ?22次下載

    深入理解Android》

    深入理解Android》
    發(fā)表于 03-19 11:23 ?0次下載

    深入理解Android:卷I》

    深入理解Android:卷I》
    發(fā)表于 03-19 11:23 ?0次下載

    深入理解Android網(wǎng)絡(luò)編程

    深入理解Android網(wǎng)絡(luò)編程
    發(fā)表于 03-19 11:26 ?1次下載

    開(kāi)關(guān)電源技術(shù)saber深入理解和鞏固驗(yàn)證基本理論知識(shí)指導(dǎo)書(shū)

    開(kāi)關(guān)電源技術(shù)saber深入理解和鞏固驗(yàn)證基本理論知識(shí)指導(dǎo)書(shū)
    發(fā)表于 09-15 16:19 ?14次下載
    開(kāi)關(guān)電源技術(shù)saber<b class='flag-5'>深入理解</b>和鞏固驗(yàn)證基本理論<b class='flag-5'>知識(shí)</b>指導(dǎo)書(shū)

    深入理解MOS管電子版資源下載

    深入理解MOS管電子版資源下載
    發(fā)表于 07-09 09:43 ?0次下載

    深入理解操作系統(tǒng)的進(jìn)程調(diào)度

    深入理解操作系統(tǒng)的進(jìn)程調(diào)度,需要先獲得些準(zhǔn)備知識(shí),這樣后面就不懵圈啦:
    的頭像 發(fā)表于 03-16 10:58 ?2630次閱讀