當前位置:編程學習大全網 - 編程語言 - 51單片機如何模擬I2C總線中從機接收ID,發送數據的程序

51單片機如何模擬I2C總線中從機接收ID,發送數據的程序

#include /*頭文件的包含*/

#include

#define uchar unsigned char /*宏定義*/

#define uint unsigned int

/*端口位定義*/

sbit BELL_OUT=P3^5;

sbit SCL="P1"^3;/*模擬I2C數據傳送位*/

sbit SDA="P1"^4;/*模擬I2C時鐘控制位*/

bit ack; /*應答標誌位*/

/*********************************************************************

起動總線函數

函數原型: void Start_I2c();

功能:啟動I2C總線,即發送I2C起始條件

********************************************************************/

void Start_I2c()

{

SDA="1"; /*發送起始條件的數據信號*/

_nop_();

SCL="1"; /*起始條件建立時間大於4.7us,延時*/

_nop_();

SDA="0"; /*發送起始信號*/

_nop_(); /* 起始條件鎖定時間大於4μs*/

SCL="0"; /*鉗住I2C總線,準備發送或接收數據 */

_nop_();

}

/***********************************************

結束總線函數

函數原型: void Stop_I2c();

功能:結束I2C總線,即發送I2C結束條件

***********************************************/

void Stop_I2c()

{

SDA="0"; /*發送結束條件的數據信號*/

_nop_(); /*發送結束條件的時鐘信號*/

SCL="1"; /*結束條件建立時間大於4μs*/

_nop_();

SDA="1"; /*發送I2C總線結束信號*/

_nop_();

}

/*******************************************************************

字節數據傳送函數

函數原型: void SendByte(uchar c);

功能:將數據c發送出去,可以是地址,也可以是數據,發完後等待應答,並對此狀

態位進行操作(不應答或非應答都使ack=0 假) 。發送數據正常,ack=1;

ack=0表示被控器無應答或損壞。

********************************************************************/

void SendByte(uchar c)

{

uchar BitCnt;

for(BitCnt=0;BitCnt<8;BitCnt++) /*要傳送的數據長度為8位*/

{

SCL="0";

if((c<

else SDA="0";

SCL="1"; /*置時鐘線為高,通知被控器開始接收數據位*/

_nop_(); /*保證時鐘高電平周期大於4μs*/

}

//從機應答,可以用應答和非應答信號代替

_nop_();

SCL="0";

_nop_();

SDA="1"; //

_nop_();

SCL="1";

_nop_();

if(SDA==1){ack=0;} /*判斷是否接收到應答信號*/

else ack="1";

SCL="0";

_nop_();

}

/*******************************************************************

字節數據傳送函數

函數原型: uchar RcvByte();

功能:用來接收從器件傳來的數據,並判斷總線錯誤(不發應答信號),

發完後請用應答函數。

********************************************************************/

uchar RcvByte()

{

uchar retc;

uchar BitCnt;

retc="0";

for(BitCnt=0;BitCnt<8;BitCnt++)

{

SCL="1"; /*置時鐘線為高使數據線上數據有效*/

_nop_();

retc="retc"<<1;

if(SDA==1) retc="retc"+1; /*讀數據位,接收的數據位放入retc中 */

SCL="0";

}

return(retc);

}

/********************************************************************

應答子函數

原型: void Ack_I2c();

功能:主控器進行應答信號

********************************************************************/

void Ack_I2c()

{

SDA="0"; /*在此發出應答信號 */

_nop_();

SCL="0";

_nop_();

SCL="1";

_nop_();

SCL="0"; /*清時鐘線,鉗住I2C總線以便繼續接收*/

_nop_();

SDA="1";

_nop_();

}

/********************************************************************

非應答子函數

原型: void NoAck_I2c();

功能:主控器進行非應答信號

********************************************************************/

void NoAck_I2c()

{

SDA="1"; /*在此發出非應答信號 */

_nop_();

SCL="1";

_nop_();

SCL="0"; /*清時鐘線,鉗住I2C總線以便繼續接收*/

}

/*******************************************************************

向無子地址器件發送字節數據函數

函數原型: bit ISendByte(uchar sla,ucahr c);

功能:從啟動總線到發送地址,數據,結束總線的全過程,從器件地址sla。如果

返回1表示操作成功,否則操作有誤。

********************************************************************/

bit ISendByte(uchar sla,uchar c)

{

Start_I2c(); /*啟動總線*/

SendByte(sla); /*發送器件地址*/

if(ack==0)return(0);

SendByte(c); /*發送數據*/

if(ack==0)return(0);

Stop_I2c(); /*結束總線*/

return(1);

}

/*******************************************************************

向有子地址器件發送多字節數據函數

函數原型: bit ISendStr(uchar sla,uchar suba,ucahr *s,uchar no);

功能:從啟動總線到發送地址,子地址,數據,結束總線的全過程,從器件地址sla,

子地址suba,發送內容是s指向的內容,發送no個字節。如果返回1表示

操作成功,否則操作有誤。

********************************************************************/

bit ISendStr(uchar sla,uchar suba,uchar *s,uchar no)

{

uchar i;

Start_I2c(); /*啟動總線*/

SendByte(sla); /*發送器件地址*/

if(ack==0)return(0);

SendByte(suba); /*發送器件子地址*/

if(ack==0)return(0);

for(i=0;i

{

SendByte(*s); /*發送數據*/

if(ack==0)return(0);

s++;

}

Stop_I2c(); /*結束總線*/

//delayMs(1); //

return(1);

}

/*******************************************************************

向無子地址器件讀字節數據函數

函數原型: bit IRcvByte(uchar sla,ucahr *c);

功能:從啟動總線到發送地址,讀數據,結束總線的全過程,從器件地址sla,返

回值在c。如果返回1表示操作成功,否則操作有誤。

********************************************************************/

bit IRcvByte(uchar sla,uchar *c)

{

Start_I2c(); /*啟動總線*/

SendByte(sla+1); /*發送器件地址*/

if(ack==0)return(0);

*c=RcvByte(); /*讀取數據*/

NoAck_I2c(); /*發送非就答位*/

Stop_I2c(); /*結束總線*/

return(1);

}

/**********************************************************************

向有子地址器件讀取多字節數據函數

函數原型: bit ISendStr(uchar sla,uchar suba,ucahr *s,uchar no);

功能:從啟動總線到發送地址,子地址,讀數據,結束總線的全過程,從器件地址sla,

子地址suba,讀出的內容放入s指向的存儲區,讀no個字節。如果返回1

表示操作成功,否則操作有誤。

**********************************************************************/

bit IRcvStr(uchar sla,uchar suba,uchar *s,uchar no)

{

Start_I2c(); /*啟動總線*/

SendByte(sla); /*發送器件地址*/

if(ack==0)return(0);

SendByte(suba); /*發送器件子地址*/

if(ack==0)return(0);

Start_I2c();

SendByte(sla+1);

if(ack==0)return(0);

while(no!=1)

{

*s=RcvByte();/*發送數據*/

Ack_I2c(); /*發送就答位*/

s++;

no--;

}

*s=RcvByte();

NoAck_I2c(); /*發送非應位*/

Stop_I2c(); /*結束總線*/

return(1);

}

  • 上一篇:濰坊福田汽車廠怎麽樣
  • 下一篇:高分求用8051單片機設計8按鍵電子琴
  • copyright 2024編程學習大全網