文件名i2c.h
/***************************************************
名稱:I2C通信模塊修改版
編寫:YuMin_Dong
時間:2012.11.17
***************************************************/
#ifndef _I2C_H_
#define _I2C_H_
sbit SDA=P1^0;
sbit SCL=P1^1;
uint8 ACK;
//開啟I2C總線
void I2C_Start()
{
SDA=1;
//_nop_();
//_nop_();
//_nop_();
_nop_();
_nop_();
SCL=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SDA=0;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SCL=0;//鉗主總線
_nop_();
_nop_();
}
//停止I2C總線
void I2C_Stop()
{
SDA=0;
//_nop_();
//_nop_();
//_nop_();
_nop_();
_nop_();
SCL=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SDA=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SCL=0;
}
//I2C通信主機發送字節
void I2C_SendByte(uint8 byte)
{
uint8 i;
for(i=0;i<8;i++)
{
if(byte&0x80)
SDA=1;
else SDA=0;
_nop_();
SCL=1;//使SDA數據有效
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SCL=0;
byte<<=1;
_nop_();
_nop_();
}
SDA=1;//數據線浮高
_nop_();
_nop_();
SCL=1;//使讀取的數據有效,判斷是否應答或非應答
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
if(SDA==1)
ACK=0;//收到非應答信號
else ACK=1;//收到應答信號
SCL=0;//鉗總線
_nop_();
_nop_();
}
//I2C通信主機接收字節
uint8 I2C_ReceiveByte()
{
uint8 i;
uint8 byte;
for(i=0;i<8;i++)
{
SDA=1;//拉高準備接收
_nop_();
SCL=1;
byte<<=1;
if(SDA==1)
byte|=0x01;
else byte&=0xfe;
SCL=0;
_nop_();
_nop_();
}
return byte;
}
//(主機接收函數將要調用)從設備發生的應答信號
void I2C_Ack()
{
SDA=0;
_nop_();
_nop_();
SCL=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SCL=0;
_nop_();
_nop_();
_nop_();
}
//非應答信號產生函數
void I2C_NoAck()
{
SDA=1;
_nop_();
_nop_();
SCL=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SCL=0;
_nop_();
_nop_();
_nop_();
}
//主機發送多字節函數
bit SendString(uint8 address,uint8 *s,uint8 num)
{
uint8 i;
I2C_Start();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
I2C_SendByte(address);
if(ACK==0)
return 0;
for(i=0;i<num;i++)
{
I2C_SendByte(*s);
if(ACK==0)
return 0;
DelayMs(10);//以等待設備寫入數據處理完成
s++;
}
I2C_Stop();
DelayUs(10);
return 1;
}
//主機接收多字節函數
bit ReceiveString(uint8 address,uint8 *s,uint8 num)
{
uint8 i;
I2C_Start();
I2C_SendByte(address);
if(ACK==0)
return 0;
I2C_Start();
I2C_SendByte(address+1);
if(!ACK)
return 0;
for(i=0;i<num-1;i++)
{
*s=I2C_ReceiveByte();
I2C_Ack();
DelayMs(10);
s++;
}
*s=I2C_ReceiveByte();
I2C_NoAck(); //給的非應答信號
I2C_Stop(); //停止總線
return 1;
}
#endif
庫文件的調用例子:http://www.zg4o1577.cn/bbs/dpj-20623-1.html