?? i2c.c
字號:
#include<at89x51.h>
#include<intrins.h>
#define uint unsigned int
#define uchar unsigned char
code uchar SenData[]={0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10};
sbit SCL=P1^4;
sbit SDA=P1^5;
/***********************************************
**函數名稱:DelayNms()
**函數功能:延時N毫秒
**入口參數:n
**出口參數:無
**說明 :無
***********************************************/
void DelayNms(uint n)
{
uint i,j;
for(i=0;i<n;i++)
for(j=0;j<120;j++);
}
/***********************************************
**函數名稱:I2C_Start()
**函數功能:發送起始條件
**入口參數:無
**出口參數:無
**說明 :時序按照標準模式建立
***********************************************/
void I2C_Start()
{
SDA=1;
_nop_();//數據建立時間大于250ns
_nop_();
_nop_();
SCL=1;
_nop_();
_nop_();
_nop_();
SDA=0;
_nop_();
_nop_();
SCL=0; //SCL高電平時間大于4us,嵌住時鐘總線
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
}
/***********************************************
**函數名稱:I2C_Stop()
**函數功能:發送停止條件
**入口參數:無
**出口參數:無
**說明 :時序按照標準模式建立
***********************************************/
void I2C_Stop()
{
SDA=0;
_nop_();//數據建立時間大于250ns
_nop_();
_nop_();
SCL=1;
_nop_();
_nop_();
_nop_();
SDA=1;
_nop_();
_nop_();
SCL=0; //SCL高電平時間大于4us,嵌住時鐘總線
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
}
/***********************************************
**函數名稱:I2C_SendByte()
**函數功能:發送一個字節
**入口參數:待發送字節n
**出口參數:無
**說明 :時序按照標準模式建立
***********************************************/
void I2C_SendByte(uchar n)
{
char i;
for(i=7;i>=0;i--)
{
SDA=(n>>i)&0x01;
_nop_();
_nop_();
_nop_();
SCL=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SCL=0;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
}
}
/***********************************************
**函數名稱:I2C_RecByte()
**函數功能:接收一個字節
**入口參數:無
**出口參數:已接收字節
**說明 :時序按照標準模式建立
***********************************************/
I2C_RecByte(void)
{
char i,j=0;
for(i=7;i>=0;i--)
{
j<<=1;
SDA=1;
_nop_();
_nop_();
_nop_();
SCL=1;
_nop_();
_nop_();
_nop_();
j|=SDA&0x01;
_nop_();
_nop_();
SCL=0;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
}
return (j);
}
/***********************************************
**函數名稱:Check_Ack()
**函數功能:檢測從機響應
**入口參數:無
**出口參數:從機響應則為'0',否則為'1'
**說明 :時序按照標準模式建立
***********************************************/
Check_Ack()
{
uchar i=1;
SDA=1;
_nop_();
_nop_();
_nop_();
SCL=1;
_nop_();
_nop_();
_nop_();
i=SDA;
_nop_();
_nop_();
_nop_();
SCL=0;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
return (i);
}
/***********************************************
**函數名稱:Gen_Ack()
**函數功能:產生應答
**入口參數:i
**出口參數:無
**說明 :i=0產生應答,i=1產生非應答
***********************************************/
Gen_Ack(char i)
{
SDA=i;
_nop_();
_nop_();
SCL=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SCL=0;
_nop_();
_nop_();
SDA=1;
_nop_();
_nop_();
_nop_();
}
/***********************************************
**函數名稱:I2C_SendNByte()
**函數功能:發送N個字節
**入口參數:字節個數n,待發送數據隊列首地址
**出口參數:無
**說明 :時序按照標準模式建立
***********************************************/
void I2C_SendNByte(uchar n,uchar *p)
{
while(n--)
{
send:I2C_SendByte(*p);
if(Check_Ack()) goto send;
p++;
}
I2C_Stop();
}
/***********************************************
**函數名稱:I2C_RecNByte()
**函數功能:接收N個字節
**入口參數:字節個數n,存放數據隊列首地址
**出口參數:無
**說明 :時序按照標準模式建立
***********************************************/
void I2C_RecNByte(char n,uchar *p)
{
while(n--)
{
*p=I2C_RecByte();
if(n>0)
{Gen_Ack(0x00);//產生應答
p++;
}
else
{Gen_Ack(0x01);//產生非應答
I2C_Stop();
}
}
}
void main(void)
{
uchar RecData[18]={0x00};
/***********************************************/
start:I2C_Start();
I2C_SendByte(0xae);//發送從地址選擇24c01
if(Check_Ack())
{
I2C_Stop();
goto start;
}
I2C_SendByte(0x30);//發送子地址
if(Check_Ack())
{
I2C_Stop();
goto start;
}
I2C_SendNByte(17,SenData);//在頁寫入模式下一次最多寫一頁,寫的數據超過16個將覆蓋前面所寫的
DelayNms(1000);//這個延時很有用,去掉試試看
/***********************************************/
/***********************************************/
start2:I2C_Start();
I2C_SendByte(0xac);//發送從地址選擇24c02
if(Check_Ack())
{
I2C_Stop();
goto start2;
}
I2C_SendByte(0x80);//發送子地址
if(Check_Ack())
{
I2C_Stop();
goto start2;
}
I2C_SendNByte(17,SenData);//在頁寫入模式下一次最多寫一頁,寫的數據超過16個將覆蓋前面所寫的
DelayNms(1000);//這個延時很有用,去掉試試看
/***********************************************/
/***********************************************/
start3:I2C_Start();
I2C_SendByte(0xa0);//發送從地址,選擇24c04,第0頁
if(Check_Ack())
{
I2C_Stop();
goto start3;
}
I2C_SendByte(0x80);//發送子地址
if(Check_Ack())
{
I2C_Stop();
goto start3;
}
I2C_SendNByte(17,SenData);//在頁寫入模式下一次最多寫一頁,寫的數據超過16個將覆蓋前面所寫的
DelayNms(1000);//這個延時很有用,去掉試試看
start4:I2C_Start();
I2C_SendByte(0xa2);//發送從地址,選擇24c04,第1頁
if(Check_Ack())
{
I2C_Stop();
goto start4;
}
I2C_SendByte(0x70);//發送子地址
if(Check_Ack())
{
I2C_Stop();
goto start4;
}
I2C_SendNByte(17,SenData);//在頁寫入模式下一次最多寫一頁,寫的數據超過16個將覆蓋前面所寫的
DelayNms(1000);//這個延時很有用,去掉試試看
/***********************************************/
/***********************************************/
start1: I2C_Start();
I2C_SendByte(0xa0);//發送從地址
if(Check_Ack())
{
I2C_Stop();
goto start1;
}
I2C_SendByte(0x08);//發送子地址
if(Check_Ack())
{
I2C_Stop();
goto start1;
}
I2C_Start();
I2C_SendByte(0xa1);//這一步不要忘記檢測應答
if(Check_Ack())
{
I2C_Stop();
goto start1;
}
I2C_RecNByte(18,RecData);
/***********************************************/
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -