|
void delay_nop(unsigned int i)
{
unsigned int count;
for(count=0; count<i; count++)
#asm("nop");
}
// SCL线为高电平SDA从高到低的跳变是I2C总线的开始信号
int I2C_start()
{
SDA_DDR=1; //Set SDA port is out
SDA_PORT=1; //Make sure SDA is high
SCL_PORT=1;
#asm("nop");
#asm("nop");
#asm("nop");
if(!SCL_PIN)
return 0; //SCL locked low by device
delay_nop(5);
SDA_PORT=0;
if(SDA_PIN)
return 0;
SCL_PORT=0;
return 1;
}
//SCL线为高电平SDA从低到高的跳变是I2C总线的停止信号
void I2C_stop()
{
SDA_DDR=1; //set SDA port is out
SDA_PORT=0;
SCL_PORT=1;
delay_nop(5);
SDA_PORT=1;
delay_nop(5);
SCL_PORT=0;
}
/***********************************************************************************
*** FUNCTION:I2C 送一个字节的数据
*** INPUT:send_data
*** OUTPUT:nop
*** RETURN:nop
************************************************************************************/
void I2C_send_byte(unsigned char send_data)
{
unsigned char i;
SDA_DDR=1; //SDA port is out
for(i = 0;i < 8;i++)
{
SCL_PORT=0;
delay_nop(10);
if(send_data&0x80)
SDA_PORT=1; //最高位是否为1,为则SDA= 1
else
SDA_PORT=0; //否则 SDA=0
delay_nop(5);
SCL_PORT=1;
delay_nop(5);
send_data<<= 1; //数据左移一位,进入下一轮送数
}
//SCL_PORT=0; //
//SDA_PORT=1; //等待ack
delay_nop(5);
}
/***********************************************************************************
** FUNCTION:等待接收ACK 信号,完成一次操作
** MODIFY DATE:
** INPUT:nop
** OUTPUT:nop
** RETURN:nop
************************************************************************************/
void I2C_receive_ack()
{
SCL_PORT=0;
delay_nop(5);
SDA_DDR=0; //SDA line is input
SDA_PORT=1;
delay_nop(5);
SCL_PORT=1; //SDA line is pull up
delay_nop(50);
while(SDA_PIN);
SDA_DDR=1;
SCL_PORT=0;
delay_nop(5);
}
/************************************************************************************
** FUNCTION:接收一个字节的数据
** MODIFY DATE:
** INPUT:nop
** OUTPUT:receive_data
** RETURN:receive_data
*************************************************************************************/
unsigned char I2C_receive_byte()
{
unsigned char i;
unsigned char receive_data = 0; //返回值
unsigned char receive_bit = 0; //每一个clk 接受到的数据
SCL_PORT=0;
delay_nop(5);
SDA_PORT=1;
SDA_DDR=0; //SDA line is input
for(i = 0;i < 8; i++)
{
SCL_PORT=1;
delay_nop(5);
receive_bit = SDA_PIN;
delay_nop(5);
receive_data = ((receive_data << 1) | receive_bit);//将数据依次存入receive_data
SCL_PORT=0;
delay_nop(5);
}
return receive_data;
}
/************************************************************************************
*** FUNCTION:接受数据后发送一个ACK 信号
*** MODIFY DATE:
*** INPUT:nop
*** OUTPUT:nop
*** RETURN:nop
************************************************************************************/
void I2C_send_ack()
{
SCL_PORT=0;
SDA_DDR=1; //SDA line is out
SDA_PORT=0;
delay_nop(5);
SCL_PORT=1;
delay_nop(5);
SCL_PORT=0;
}
/************************************************************************************
*** FUNCTION: 向I2C写一个小于256的数据
*** MODIFY DATE:
*** INPUT:address and data
*** OUTPUT:nop
*** RETURN:nop
************************************************************************************/
void I2C_write_byte(unsigned char address, unsigned char data)
{
if(I2C_start());
{
I2C_send_byte(0xa0); //slave address
I2C_receive_ack();
I2C_send_byte(address);
I2C_receive_ack();
I2C_send_byte(data);
I2C_receive_ack();
I2C_stop();
// delay_nop(8000);
//delay_ms(10);
}
}
/************************************************************************************
*** FUNCTION: 向I2C读一个字节的数据
*** MODIFY DATE:
*** INPUT:address and data
*** OUTPUT:nop
*** RETURN:nop
************************************************************************************/
unsigned char I2C_read_byte(unsigned char read_address)
{
unsigned char read_data;
//启动 送地址
if(I2C_start());
{
I2C_send_byte(0xa0); //DEVICE DATA :1010_000_0_WRITE
I2C_receive_ack();
I2C_send_byte(read_address);
I2C_receive_ack();
//启动 改为读操作
I2C_start();
I2C_send_byte(0xa1); //DEVICE DATA:1010_000_0_READ
I2C_receive_ack();
//开始读取数据,先低后高,存入int 型
read_data = I2C_receive_byte();
//结束时没有ACK
I2C_stop();
return read_data;
// delay_nop(8000);
// delay_ms(10);
}
} |
|