📄 i2c.c
字号:
#include <reg52.h>
#include <stdio.h>
#include "I2C.h"
#include "Uart.h"
#include "Reg.h"
#include "debug.h"
#define DELAY_TIME 2
#define TryTimes 5
/************* Wait ************/
void Wait(uchar t)
{
while(t!=0)
{
t--;
}
}
/**************启动I2C总线的函数,当SCL为高电平时使SDA产生一个负跳变
********************************************************************/
void IIC_Start(void)
{
SCL = 1; //SDA=1;SCL=1;
SDA = 1;
Wait(DELAY_TIME);
SDA=0;
Wait(DELAY_TIME);
SCL=0;
Wait(DELAY_TIME);
}
/**************终止I2C总线,当SCL为高电平时使SDA产生一个正跳变
*************************************************************/
void IIC_Stop(void)
{
SDA=0;
Wait(DELAY_TIME);
SCL = 1;
Wait(8);
SDA=1;
}
/************发送0,在SCL为高电平时使SDA信号为低*************/
void SEND_0(void)
{
SDA=0;
Wait(DELAY_TIME);
SCL=1;
Wait(DELAY_TIME);
SCL=0;
Wait(DELAY_TIME);
}
/************发送1,在SCL为高电平时使SDA信号为高*************/
void SEND_1(void)
{
SDA=1;
Wait(DELAY_TIME);
SCL=1;
Wait(DELAY_TIME);
SCL = 0;
Wait(DELAY_TIME);
}
/**************发送完一个字节后检验设备的应答信号************/
bit Check_Ack(void)
{
bit F0;
SCL = 1;
Wait(DELAY_TIME);
F0 = SDA; //读入SDA的值
Wait(DELAY_TIME);
SCL = 0;
Wait(DELAY_TIME);
if( F0==1 )
{
SCL=1;
IIC_Stop();
return FALSE;
}
return TRUE;
}
/**************向IIC总线写一个字节************/
void Write_Byte(uchar b)
{
uchar i;
for(i=0;i<8;i++)
{
if((b<<i)&0x80)
SEND_1();
else SEND_0();
Wait(4);
}
}
/**************向I2C总线写n个字节 page write 模式************/
bit Write_N_Bytes(uchar slave,uchar dataAddr,uchar *buffer,uchar n)
{
uchar i;
uchar ucCount;
for(ucCount=0; ucCount<TryTimes; ucCount++)
{
IIC_Start();
Write_Byte(slave);
if(!Check_Ack())
{
IIC_Stop();
#ifdef _DEBUG_ON_
printf("I2C write slave NoAck!");
#endif
continue;
}
Write_Byte(dataAddr);
if(!Check_Ack())
{
IIC_Stop();
#ifdef _DEBUG_ON_
printf("I2C write addr NoAck!");
#endif
continue;
}
for(i=0;i<n;i++)
{
Write_Byte(buffer[i]);
Wait(4);
if(!Check_Ack())
{
IIC_Stop();
continue;
}
}
IIC_Stop();
Wait(100);
return TRUE;
}
#ifdef _DEBUG_ON_
printf("I2C write N Bytes is wrong!");
#endif
return FALSE;
}
/**************从I2C总线读一个字节************/
uchar Read_Byte(void)
{
uchar b=0;
uchar i;
bit F0;
for(i=0;i<8;i++)
{
SDA=1;
SCL=1;
Wait(4);
F0 = SDA;
Wait(4);
SCL=0;
if(F0==1)
{
b=b<<1; //左移一位
b=b|0x01; //SDA为1,则低位为1
}
else b=b<<1;
}
return b;
}
/**************从I2C总线读n个字节 随机读取方式************/
bit Read_N_Bytes(uchar slave,uchar dataAddr,uchar *buffer,uchar n)
{
uchar i,ucCount;
for(ucCount=0; ucCount<TryTimes; ucCount++)
{
IIC_Start();
Write_Byte(slave);
if(!Check_Ack())
{
IIC_Stop();
#ifdef _DEBUG_ON_
printf("I2C read slave NoAck!");
#endif
continue;
}
Write_Byte(dataAddr); //向eeprom发数据addr
if(!Check_Ack()) //等待接收器应答信号
{
IIC_Stop();
#ifdef _DEBUG_ON_
printf("I2C read addr NoAck!");
#endif
continue;
}
IIC_Start();
slave = slave|0x01;
Write_Byte(slave); //向总线发送接收器地址
if(!Check_Ack()) //等待接收器应答信号
{
IIC_Stop();
#ifdef _DEBUG_ON_
printf("I2C read slave NoAck!");
#endif
continue;//printf("IIC read SlaveAdr2 is wrong!");
}
for(i=0;i<n;i++)
{
buffer[i]=Read_Byte();
if(i!=n-1) //最后一个数据是n-1,而不是n
{
SEND_0(); //发送应答
}
else
{
SEND_1(); //发送非应答
}
Wait(4);
}
IIC_Stop();
return TRUE;
}
#ifdef _DEBUG_ON_
printf("I2C read is wrong!");
#endif
return FALSE;
}
/**************从I2C总线读n个字节 随机读取方式************/
bit Read_Char(uchar SlaveAdr,uchar dataAddr,uchar *Data)
{
uchar ucCount;
for(ucCount=0; ucCount<TryTimes; ucCount++)
{
IIC_Start();
Write_Byte(SlaveAdr);
if(!Check_Ack()) //等待接收器应答信号
{
IIC_Stop();
#ifdef _DEBUG_ON_
printf("I2C read slave NoAck!");
#endif
continue;
}
Write_Byte(dataAddr); //向eeprom发数据addr
if(!Check_Ack()) //等待接收器应答信号
{
IIC_Stop();
#ifdef _DEBUG_ON_
printf("I2C read addr NoAck!");
#endif
continue;
}
IIC_Start();
SlaveAdr = SlaveAdr|0x01;
Write_Byte(SlaveAdr); //向总线发送接收器地址
if(!Check_Ack()) //等待接收器应答信号
{
IIC_Stop();
continue;
}
Data[0] = Read_Byte();
SEND_1(); //发送应答
Wait(4);
IIC_Stop();
return TRUE;
}
#ifdef _DEBUG_ON_
printf("I2C read is wrong!");
#endif
return FALSE;
}
/*****************************/
bit Write_int(uchar slave,uchar dataAddr,uint Data)
{
uchar ucCount;
for(ucCount=0; ucCount<TryTimes; ucCount++)
{
IIC_Start();
Write_Byte(slave);
if(!Check_Ack())
{
IIC_Stop();
continue;
}
Write_Byte(dataAddr);
if(!Check_Ack())
{
IIC_Stop();
continue;
}
Write_Byte(Data/256);
Wait(4);
if(!Check_Ack())
{
IIC_Stop();
continue;
}
Write_Byte(Data%256);
Wait(4);
if(!Check_Ack())
{
IIC_Stop();
continue;
}
IIC_Stop();
Wait(4); //启动内部写电路
return TRUE;
}
#ifdef _DEBUG_ON_
printf("I2C Int write is wrong!");
#endif
return FALSE;
}
/*****************************/
bit Write_char(uchar slave,uchar dataAddr,uchar Data)
{
uchar ucCount;
for(ucCount=0; ucCount<TryTimes; ucCount++)
{
IIC_Start();
Write_Byte(slave);
if(!Check_Ack())
{
IIC_Stop();
continue;
}
Write_Byte(dataAddr);
if(!Check_Ack())
{
IIC_Stop();
continue;
}
Write_Byte(Data);
Wait(4);
if(!Check_Ack())
{
IIC_Stop();
continue;
}
Wait(4);
IIC_Stop();
Wait(4); //启动内部写电路
return TRUE;
}
#ifdef _DEBUG_ON_
printf("I2C Char write is wrong!");
#endif
return FALSE;
}
/******************************
* 0对应的EEPROM slave地址 0--7*
******************************/
unsigned char E2PROM_Bank(unsigned char n)
{
return( 0xa8+n*2 );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -