以前写过,拿出来参考下
void I2C_init(void)
{
SET(PT(I2C_SCL_PORT,DIR,I2C_SCL_BIT));
CLR(PT(I2C_SCL_PORT,OUT,I2C_SCL_BIT));
}
void I2C_wait(void)
{
asm("NOP");
asm("NOP");
asm("NOP");
asm("NOP");
asm("NOP");
asm("NOP");
asm("NOP");
asm("NOP");
}
void I2C_ack(void)
{
SET(PT(I2C_SDA_PORT,DIR,I2C_SDA_BIT));
PT(I2C_SDA_PORT,OUT,I2C_SDA_BIT) = 0;
I2C_wait();
PT(I2C_SCL_PORT,OUT,I2C_SCL_BIT) = 1;
I2C_wait();
PT(I2C_SCL_PORT,OUT,I2C_SCL_BIT) = 0;
I2C_wait();
PT(I2C_SDA_PORT,OUT,I2C_SDA_BIT) = 1;
}
void I2C_noack(void)
{
SET(PT(I2C_SDA_PORT,DIR,I2C_SDA_BIT));
PT(I2C_SDA_PORT,OUT,I2C_SDA_BIT) = 1;
I2C_wait();
PT(I2C_SCL_PORT,OUT,I2C_SCL_BIT) = 1;
I2C_wait();
PT(I2C_SCL_PORT,OUT,I2C_SCL_BIT) = 0;
I2C_wait();
PT(I2C_SDA_PORT,OUT,I2C_SDA_BIT) = 1;
}
unsigned char I2C_start(void) //在scl高电平过程中,sda产生一个下降沿
{
SET(PT(I2C_SDA_PORT,DIR,I2C_SDA_BIT));
SET(PT(I2C_SDA_PORT,OUT,I2C_SDA_BIT));
I2C_wait();
SET(PT(I2C_SCL_PORT,OUT,I2C_SCL_BIT));
I2C_wait();
CLR(PT(I2C_SDA_PORT,DIR,I2C_SDA_BIT));
if(PT(I2C_SDA_PORT,IN,I2C_SDA_BIT) == 0)// SDA 为低,则说明有其他设备使用sda
return 0;
SET(PT(I2C_SDA_PORT,DIR,I2C_SDA_BIT));
PT(I2C_SDA_PORT,OUT,I2C_SDA_BIT) = 0; //产生一个下降沿
I2C_wait();
PT(I2C_SCL_PORT,OUT,I2C_SCL_BIT) = 0;
I2C_wait();
PT(I2C_SDA_PORT,OUT,I2C_SDA_BIT) = 1;
return 1;
}
void I2C_stop(void)
{
SET(PT(I2C_SDA_PORT,DIR,I2C_SDA_BIT));
PT(I2C_SDA_PORT,OUT,I2C_SDA_BIT) = 0;
I2C_wait();
PT(I2C_SCL_PORT,OUT,I2C_SCL_BIT) = 1;
I2C_wait();
PT(I2C_SDA_PORT,OUT,I2C_SDA_BIT) = 1; // rasing edge
I2C_wait();
PT(I2C_SCL_PORT,OUT,I2C_SCL_BIT) = 0;
I2C_wait();
PT(I2C_SDA_PORT,OUT,I2C_SDA_BIT) =1;
}
unsigned char I2C_waitack(void)
{
unsigned int x = 0xffff;
SET(PT(I2C_SDA_PORT,DIR,I2C_SDA_BIT));
SET(PT(I2C_SDA_PORT,OUT,I2C_SDA_BIT));
I2C_wait();
CLR(PT(I2C_SDA_PORT,DIR,I2C_SDA_BIT));
I2C_wait();
PT(I2C_SCL_PORT,OUT,I2C_SCL_BIT) = 0;
I2C_wait();
PT(I2C_SCL_PORT,OUT,I2C_SCL_BIT) = 1;
while(PT(I2C_SDA_PORT,IN,I2C_SDA_BIT) == 1)
{
x--;
if(!x)
{
PT(I2C_SCL_PORT,OUT,I2C_SCL_BIT) = 0;
return 0;
}
}
PT(I2C_SCL_PORT,OUT,I2C_SCL_BIT) = 0;
SET(PT(I2C_SDA_PORT,DIR,I2C_SDA_BIT));
return 1;
}
void I2C_send_bit(unsigned char value)
{
SET(PT(I2C_SDA_PORT,DIR,I2C_SDA_BIT));
if(value != 0)
PT(I2C_SDA_PORT,OUT,I2C_SDA_BIT) = 1;
else
PT(I2C_SDA_PORT,OUT,I2C_SDA_BIT) = 0;
I2C_wait();
PT(I2C_SCL_PORT,OUT,I2C_SCL_BIT) = 1;
I2C_wait();
PT(I2C_SCL_PORT,OUT,I2C_SCL_BIT) = 0;
I2C_wait();
PT(I2C_SDA_PORT,OUT,I2C_SDA_BIT) = 1; //拉高sda,不影响其他设备使用sda
}
void I2C_send_byte(unsigned char value,unsigned char order)
{
unsigned char i;
SET(PT(I2C_SDA_PORT,DIR,I2C_SDA_BIT));
if(order == 1) //先发送高位,在发送低位
{
for(i=0; i<8; i++)
{
I2C_send_bit(value & 0x80);
value <<= 1;
}
}
else//先发送低位,再发送高位
{
for(i=0; i<8; i++)
{
I2C_send_bit(value & 0x01);
value >>= 1;
}
}
}
unsigned char I2C_receive_bit(void)
{
unsigned char c;
PT(I2C_SCL_PORT,OUT,I2C_SCL_BIT) = 1;
I2C_wait();
if(PT(I2C_SDA_PORT,IN,I2C_SDA_BIT) == 1)
c = 1;
else
c = 0;
PT(I2C_SCL_PORT,OUT,I2C_SCL_BIT) = 0;
I2C_wait();
return c;
}
unsigned char I2C_receive_byte(unsigned char order)
{
unsigned char i, value = 0;
SET(PT(I2C_SDA_PORT,DIR,I2C_SDA_BIT));
SET(PT(I2C_SDA_PORT,OUT,I2C_SDA_BIT)); //将sda拉高,防止影响
CLR(PT(I2C_SDA_PORT,DIR,I2C_SDA_BIT));
if(order == 1) //数据从高位开始接收
{
for(i = 0; i < 8; i++)
{
value <<= 1;
if(I2C_receive_bit() == 1)
value |= 0x01;
}
}
else//数据从低位开始接收
{
for(i = 0;i < 8; i++)
{
value >>= 1;
if(I2C_receive_bit() == 1)
value |= 0x80;
}
}
SET(PT(I2C_SDA_PORT,DIR,I2C_SDA_BIT));
SET(PT(I2C_SDA_PORT,OUT,I2C_SDA_BIT));
return value;
}
set就是 置1, clr 就是置0:
希望对你有帮助