I2C是由Philips公司发明的一种串行数据通信协议,仅使用两根信号线:SerialClock(简称SCL)和SerialData(简称SDA)。I2C是总线结构,1个Master,1个或多个Slave,各Slave设备以7位地址区分,地址后面再跟1位读写位,表示读(=1)或者写(=0),所以我们有时也可看到8位形式的设备地址,此时每个设备有读、写两个地址,高7位地址其实是相同的。 7,I2C规程运用主/从双向通讯。器件发送数据到总线上,则定义为发送器,器件接收据 定义为接收器。主器件和从器件都可以工作于接收和发送状态。 总线必须由主器件(通常 为微控制器)控制,主器件产生串行时钟(SCL)控制总线的传输方向,并产生起始和停止 条件。SDA线上的数据状态仅在SCL为低电平的期间才能改变,SCL为高电平的期间,SDA 状态的改变被用来表示起始和停止条件。
源码: void i2c_init(void) uint8 i2c_write(uint8 slave_address, uint8 *buffer, int byte_count, int freq) delay(2*D); /********************************************************************/ uint8 i2c_read(uint8 slave_address, uint8 *buffer, int byte_count, int freq) delay(2*D); for(i = 0; i < byte_count; i++) /********************************************************************/ void i2c_start(void) /********************************************************************/ uint8 i2c_stop(void) PADAT_init; /********************************************************************/ void delay(int value) /********************************************************************/
第二个例子 函数定义: gpio_iic.h: #ifndef __IIC_GPIO__ /* /* /*
/* /* /* /* /* /* /* /* /* /* /* #endif
#include "gpio_iic.h" #ifdef __80C52__
#ifdef __MINI2440__ #ifdef __80C52__
#ifdef __80C52__
/*
/*
/*
/* /* set_sda( 1 ); /* /* /* /* /* /*
下面是可以用来读写at24c02的测试代码,在mini2440板测试通过, static void m24c02_send( int addr, char *buf, int buf_size) static void m24c02_recv( int addr , char *buf, int buf_size )
(1)基础宏定义
#define GPIO_SCL S3C2410_GPF3
#define GPIO_SDA S3C2410_GPF0
#define GPIO_SDA_OUTP S3C2410_GPF0_OUTP //设定SDA输出
#define GPIO_SDA_INP S3C2410_GPF0_INP //设定SDA输入
#define GPIO_SCL_OUTP S3C2410_GPF3_OUTP //设定SCL输出
void I2C_SCL_OUTP( void )
{
s3c2410_gpio_cfgpin(GPIO_SCL,GPIO_SCL_OUTP);
}
void I2C_SCL_Output(u8 value)
{
if(value)
{
s3c2410_gpio_setpin(GPIO_SCL,value);
}
else
{
s3c2410_gpio_setpin(GPIO_SCL,value );
}
}
void I2C_SDA_Mode(u8 v_mode) //SDA输出方向
{
if(v_mode)
{
s3c2410_gpio_cfgpin(GPIO_SDA, GPIO_SDA_OUTP);
}
else
{
s3c2410_gpio_cfgpin(GPIO_SDA, GPIO_SDA_INP);
}
}
void I2C_SDA_Output(u8 value)
{
if(value)
{
s3c2410_gpio_setpin(GPIO_SDA,value);
}
else
{
s3c2410_gpio_setpin(GPIO_SDA,value );
}
}
u8 I2C_SDA_Read(void) //SDA读数据
{
return s3c2410_gpio_getpin(GPIO_SDA);
}
(2)基础段
void I2C_Init(void)
{
I2C_SDA_Output(1);
I2C_SCL_Output(1); //默认拉高
}
void I2C_Wait(void)
{
u16 i;
for(i=0;i<200;i++);
}
void I2C_Start(void)
{
I2C_SDA_Output(1);
I2C_SCL_Output(1);
I2C_Wait();
I2C_SDA_Output(0);
I2C_Wait();
I2C_SCL_Output(0);
}
void I2C_Stop(void)
{
I2C_SDA_Output(0);
I2C_Wait();
I2C_SCL_Output(1);
I2C_Wait();
I2C_SDA_Output(1);
}
(3)读写单个字节的段
u8 I2C_Send_Byte(u8 bytedata)
{
u8 i,ack;
I2C_SDA_Mode(1); //SDA输出
I2C_SCL_OUTP();
for (i = 0; i < 8; i++)
{
if (bytedata & 0x80)
{
I2C_SDA_Output(1);
}
else
{
I2C_SDA_Output(0);
}
bytedata <<= 1;
I2C_SCL_Output(1);
udelay(3);
I2C_SCL_Output(0);
udelay(1);
}
I2C_SDA_Output(1); //release
udelay(3);
I2C_SDA_Mode(0); //设定SDA输入
I2C_SCL_Output(1);
udelay(3);
ack = I2C_SDA_Read(); //读应答
I2C_SDA_Mode(1);
I2C_SCL_Output(0);
udelay(3);
return ack;
}
u8 I2C_Receive_Byte(void)
{
u8 i;
u8 bytedata = 0x00;
u8 temp;
I2C_SDA_Mode(0);
for ( i = 0; i < 8; i++)
{
I2C_SCL_Output(1);
udelay(3);
bytedata <<= 1;
temp = I2C_SDA_Read();
printk("reda SDA'value is:%d\n",temp);
if (temp)
bytedata |= 0x01;
printk(" bytedata is:%x\n",bytedata);
I2C_SCL_Output(0);
udelay(1);
}
I2C_SDA_Mode(1);
return bytedata;
}
(4)读写单个字节的I2C应用函数
u8 I2C_Byte_Write(u8 device_ID,u8 address,u8 bytedata)
{
u8 ack;
printk("device_ID is:%x\n",device_ID);
printk("address is:%x\n",address);
printk("date is:%x\n",bytedata);
I2C_Start();
ack=I2C_Send_Byte(device_ID);
printk("ack is:%d\n",ack);
if(ack)
I2C_Stop();
I2C_Send_Byte(address);
I2C_Send_Byte(bytedata);
I2C_Stop();
I2C_Wait();
return 0;
}
u8 I2C_Byte_Read(u8 device_ID,u8 address)
{
u8 bytedata;
I2C_Start();
I2C_Send_Byte(device_ID);
I2C_Send_Byte(address);
I2C_Start();
I2C_Send_Byte(device_ID+1);
bytedata = I2C_Receive_Byte(); //读单个字节,不需要再发应答
I2C_Stop();
return bytedata;
}
|