久久ER99热精品一区二区-久久精品99国产精品日本-久久精品免费一区二区三区-久久综合九色综合欧美狠狠

新聞中心

EEPW首頁 > 嵌入式系統 > 設計應用 > C51單片機模擬I2C總線驅動程序設計(1)

C51單片機模擬I2C總線驅動程序設計(1)

作者: 時間:2016-11-26 來源:網絡 收藏
/********************************** I2C 總線驅動 ******************************
模塊名:I2C 總線驅動 型號:I2C
功能描述:
此模塊包括發送數據及接收數據,應答位發送,并提供了幾個直接面對器件的操作函數,能
很方便的與用戶程序進行連接并擴展。需要注意的是,函數是采用延時方法產生 SCL 脈沖,
對高晶振頻率要做一定的修改!!在寫 E2PROM 的時候一定要延時!!!
說明:
1us機器周期,晶振頻率要小于12MHz
返回1:則操作成功,返回0:則操作失敗。
sla為器件從地址,suba為器件子地址。
*******************************************************************************
#i nclude "AT89X52.h"
#i nclude
#define SomeNOP(); {_nop_();_nop_();_nop_();_nop_();_nop_();} //定義空指令
sbit SDA = P1^3; //模擬 I2C 數據傳輸位
sbit SCL = P1^2; //模擬 I2C 時鐘控制位
bit bdata I2C_Ack; //應答標志位
/************************************ I2C_Start *******************************
函數名:void I2C_Start()
入口:
出口:
功能描述:啟動 I2C 總線,即發送 I2C 初始條件
解釋: 在 I2C 總線協議中規定的起始位格式是:在 SCL 高電平期間,SDA 發生從高到低的電平
跳變.它與其它數據格式的區別在于,協議中規定有效的數據必須在 SCL 的高電平期間保持
不變,只有在 SCL 的低電平期間才能發生跳變.所以這一有別與其它格式的數據才能做為起
始位.
調用函數:
全局變量
*******************************************************************************
void I2C_Start()
{
SDA = 1; //發送起始條件的數據信號
_Nop();
SCL = 1;
SomeNOP(); //起始條件建立時間大于 4.7us,延時
SDA = 0; //發送起始信號
SomeNOP(); //起始條件建立時間大于 4us,延時
SCL = 0; //鉗住 I2C 總線準備發送或接收數據
//解釋:I2C 總線在空閑狀態下都是被上拉為高電平的,所以當它們處于低電平時就表示忙的狀態.
_nop_();
_nop_();
}
/************************************ I2C_Stop ********************************
函數名:void I2C_Stop()
入口:
出口:
功能描述:結束 I2C 總線,即發送 I2C 結束條件
解釋:同起始條件的格式類似,結束條件的格式是在 SCL 高電平期間,SDA 由低電平向高電平
跳變.
調用函數:
全局變量:
*******************************************************************************
void I2C_Stop()
{
SDA = 0; //發送結束條件的數據信號
_Nop();
SCL = 1; //發送結束條件的時鐘信號
SomeNOP();//結束條件建立時間大于 4us,延時
SDA = 1; //發送 I2C 總線結束信號
SomeNOP();
}
/************************************ I2C_CheckAck ****************************
函數名:bit I2C_CheckAck(void)
入口:
出口:0(無應答),1(有應答)
功能描述:
檢驗 I2C 總線應答信號,有應答則返回 1,否則返回 0,超時值取 255.
解釋:I2C 總線協議中規定傳輸的每個字節之后必須跟一個應答位,所以從器件在接收到每
個字節之后必須反饋一個應答信號給主控制器,而主控制器就需要檢測從器件回傳的應答信
號,根據其信息做出相應的處理.另外,主從之別是相對的,接收數據的即為從,發送數據的及
為主.
再看看應答信號的格式:在由發送器產生的時鐘響應周期里,發送器先釋放 SDA(置高),然后
由接受器將 SDA 拉低,并在這個時鐘脈沖周期的高電平期間保持穩定的低電平.即表示從器
件做出了應答.
調用函數:void I2C_Stop()
全局變量:
*******************************************************************************
bit I2C_CheckAck(void)
{
uchar errtime = 255; // 因故障接收方無 Ack,超時值為 255
SDA = 1; //發送器先釋放 SDA
SomeNOP();
SCL = 1;
SomeNOP(); //時鐘電平周期大于 4 us
while(SDA) //判斷 SDA 是否被拉低
{
errtime--;
if(errtime==0)
{
I2C_Stop();
return(0);
}
}
SCL = 0;
_nop_();
return(1);
}
/************************************ I2C_SendB *******************************
函數名:void I2C_SendB(uchar c)
入口:uchar 型數據
出口:
功能描述:
字節數據傳送函數,將數據 c 發送出去,可以是地址,也可以是數據,發完后等待應答,
并對
此狀態位進行操作
注意:在傳送數據時,數據(SDA)的改變只能發生在SCL的低電平期間,在SCL的高電平期間保
持不變
調用函數:bit I2C_CheckAck()
全局變量:I2C_Ack
*******************************************************************************
void I2C_SendB(uchar c)
{
uchar BitCnt;
for (BitCnt=0; BitCnt<8; BitCnt++) //要傳送的數據長度為 8 位
{
if((c<
{
SDA = 1;
}
else
{
SDA = 0;
}
_nop_();
_nop_();
SCL = 1; //置時鐘線為高通知被控器開始接收數據位
SomeNOP(); //保證時鐘高電平周期大于 4us
SCL = 0;
}
_nop_();
_nop_();
I2C_Ack = I2C_CheckAck();//檢驗應答信號,作為發送方,所以要檢測接收器反饋的應答信號.
_nop_();
_nop_();
}




評論


技術專區

關閉