1024手机基地看电影,午夜福利视频导航,国产精品福利在线一区,亚洲欧美日韩另类成人,在线观看午夜日本理论片,成年超爽免费网站,国产精品成人免费,精品动作一级毛片,成人免费观看网站,97精品伊人久久大香蕉
標題:
單片機IIC通信時序的詳細解釋
[打印本頁]
作者:
xzf586
時間:
2018-8-16 17:09
標題:
單片機IIC通信時序的詳細解釋
/*---------------------------------------------------------------------
IIC.C文件
作者:xzf586 創建日期:2018.8.16
----------------------------------------------------------------------*/
#include <reg52.h>
#include <intrins.h>
#include"IIC.H"
#define NOP4 {_nop_();_nop_();_nop_();_nop_();_nop_();}
/***********************************************************************
IIC起始信號
時 序: 1 SDA SCL高電平期間,持續時間>4.7us(實際上是總線空閑)
2 SDA下降沿后,持續時間>4us(線與,總線占用)
************************************************************************/
void I2CStart()
{
I2C_SDA = 1; //首先確保SDA、SCL都是高電平,總線空閑
I2C_SCL = 1;
NOP4
I2C_SDA = 0; //先拉低SDA
NOP4 //起始信號結束
I2C_SCL = 0; //再拉低SCL,為后續SDA數據變化做準備
}
/***********************************************************************
IIC結束通信信號
時 序: 1 SCL高電平期間,持續時間>4.7us
2 SDA上升沿后,持續時間>4.7us(總線釋放)
************************************************************************/
void I2CStop()
{
I2C_SDA = 0;
I2C_SCL = 1; //先拉高SCL
NOP4
I2C_SDA = 1; //再拉高SDA,釋放總線
NOP4
}
/***********************************************************************
IIC主機向從機寫一個字節
時 序: 1 SCL=0;上面起始信號已準備好
2 SDA=待傳輸位的值0或1
3 等待一段時間,數據穩定
4 SCL=1,此時SDA上數據不可以變化,因為從機要讀取這個SDA值
5 等待一段時間,從機讀取這個SDA值
6 SCL=0,進行下一次SDA數據變化,再傳輸出去
返回值 從機應答位的值
************************************************************************/
bit I2CWrite(unsigned char dat)
{
bit ack; //用于暫存應答位的值
unsigned char temp; //用于探測字節內某一位值的掩碼變量
for (temp=0x80; temp!=0; temp>>=1) //從高位到低位依次進行
{
if ((temp&dat) == 0) //該位的值輸出到SDA上
I2C_SDA = 0;
else
I2C_SDA = 1;
NOP4
I2C_SCL = 1; //拉高SCL
NOP4
I2C_SCL = 0; //再拉低SCL,完成一個位周期
} //8位數據發送完畢,
I2C_SDA = 1; //8位數據發送完后,主機釋放SDA,以檢測從機應答
NOP4
I2C_SCL = 1; //拉高SCL,目的讓主機讀取應答值
ack = I2C_SDA; //讀取此時的SDA值,即為從機的應答值
NOP4
I2C_SCL = 0; //再拉低SCL完成應答位,并保持住總線
return (~ack); //應答值取反以符合通常的邏輯:
//0=不存在或忙或寫入失敗,1=存在且空閑或寫入成功,注意ack取反
}
/***********************************************************************
主機從從機讀取最后一個字節,發送非應答信號
時 序: 1 SDA=1;余下SDA信號由從機控制
2 SCL=1;拉高SCL,此時SDA上已由從機寫上一位0或1,主機開始讀取
3 等待一段時間,讀取完畢
4 SCL=0,拉低SCL,以使從機發送出下一位到SDA上
************************************************************************/
unsigned char I2CReadNAK()
{
unsigned char temp;
unsigned char dat;
I2C_SDA = 1; //首先確保主機釋放SDA,即將SDA控制權交由從機
for (temp=0x80; temp!=0; temp>>=1) //從高位到低位依次進行
{
NOP4
I2C_SCL = 1; //拉高SCL
if(I2C_SDA == 0) //讀取SDA的值,此時SDA已由從機寫上一位0或1,
dat &= ~temp; //為0時,dat中對應位清零
else
dat |= temp; //為1時,dat中對應位置1
NOP4
I2C_SCL = 0; //再拉低SCL,以使從機發送出下一位
}
I2C_SDA = 1; //從機8位數據發送完后,主機拉高SDA,發送非應答信號,這樣從機將SDA控制權轉交主機
NOP4
I2C_SCL = 1; //拉高SCL,讓從機讀到這個1,知道停止向主機發送數據
NOP4
I2C_SCL = 0; //再拉低SCL完成非應答位,并保持住總線,因為停止信號還沒有發出,所以要保持總線
return dat;
}
/***********************************************************************
主機從從機讀取一個字節(非最后一個字節),發送應答信號
時 序: 1 SDA=1;余下SDA信號由從機控制
2 SCL=1;拉高SCL,此時SDA上已由從機寫上一位0或1,主機開始讀取
3 等待一段時間,讀取完畢
4 SCL=0,拉低SCL,以使從機發送出下一位到SDA上
************************************************************************/
unsigned char I2CReadACK()
{
unsigned char temp;
unsigned char dat;
I2C_SDA = 1; //首先確保主機釋放SDA
for (temp=0x80; temp!=0; temp>>=1) //從高位到低位依次進行
{
NOP4
I2C_SCL = 1; //拉高SCL
if(I2C_SDA == 0) //讀取SDA的值
dat &= ~temp; //為0時,dat中對應位清零
else
dat |= temp; //為1時,dat中對應位置1
NOP4
I2C_SCL = 0; //再拉低SCL,以使從機發送出下一位
}
I2C_SDA = 0; //從機8位數據發送完后,主機拉低SDA,發送應答信號,SDA控制權仍然在從機手里
NOP4
I2C_SCL = 1; //拉高SCL,讓從機讀到這個0,繼續向主機發送數據
NOP4
I2C_SCL = 0; //再拉低SCL完成應答位,并保持住總線,SDA由從機確定
return dat;
}
作者:
lyMarvin
時間:
2018-8-17 06:21
謝謝分享!
后面若是有應用示例就更好了
作者:
renzaijiangnan
時間:
2020-11-3 07:33
從編程上看,是宋師傅的忠實粉絲,一起學了。有應用實例嗎
歡迎光臨 (http://www.raoushi.com/bbs/)
Powered by Discuz! X3.1