IIC_Start:
SDA由高拉低 — >SCL再由高拉低。
void IIC_Start(void)
{
SDA_OUT;
SDA_H;
SCL_H;
delay_us(2);
SDA_L;
delay_us(2);
SCL_L;
delay_us(2);
}
IIC_Stop:
SCL先由低拉高 — >SDA再由低拉高。
void IIC_Stop(void)
{
SDA_OUT;
SCL_L;
SDA_L;
delay_us(2);
SCL_H;
delay_us(2);
SDA_H;
delay_us(2);
}
IIC_Wait_Ack:
主机发送数据给从机释放SDA为高电平,从机接收成功后主机要等待从机在SCL第9个时钟上拉低SDA告诉主机收到的应答信号。
uint8_t IIC_Wait_Ack(void)
{
uint16_t ucErrTime=0;
SDA_IN;
SDA_H; delay_us(2);
SCL_H; delay_us(2);
while(SDA_read)
{
ucErrTime++;
if(ucErrTime>250)
{
IIC_Stop();
return 1;
}
}
SCL_L;
delay_us(5);
return 0;
}
IIC_Ack:
应答:是一个低电平信号
主机读取从机的数据后,在SCL第9个时钟上从机需要发送低电平的应答信号。
void IIC_Ack(void)
{
SCL_L;
SDA_OUT;
delay_us(2);
SDA_L;
delay_us(2);
SCL_H;
delay_us(2);
SCL_L;
}
IIC_NAck:
非应答:是一个高电平信号
主机读取从机的数据后,在SCL第9个时钟上从机需要发送高电平的应答信号。
当主控器接收数据时接收到最后一个数据字节后,必须给被控器发送一个非应答位,使被控器发送器释放数 据线,以便主控制(注:应当是主控器,不是主控制)发送停止信号从而终止数据传输。
void IIC_NAck(void)
{
SCL_L;
SDA_OUT;
SDA_H;
delay_us(2);
SCL_H;
delay_us(2);
SCL_L;
}
IIC_Send_Byte:
发送数据(8bit)
void IIC_Send_Byte(uint8_t txd)
{
uint8_t t;
SDA_OUT;
SCL_L;
for(t=0;t<8;t++)
{
if((txd&0x80)>>7)
SDA_H;
else
SDA_L;
txd<<=1;
delay_us(2);
SCL_H;
delay_us(2);
SCL_L;
}
while(IIC_Wait_Ack());
}
IIC_Read_Byte(ask):
接收数据(8bit)
ask = 1:后面继续接收下一个8bit数据。//发送应答信号
ask = 0:停止接收数据。 //发送非应答信号
uint8_t IIC_Read_Byte(unsigned char ack)
{
unsigned char i,receive=0;
SDA_IN;
for(i=0;i<8;i++ )
{
receive<<=1;
SCL_L;
delay_us(2);
SCL_H;
if(SDA_read)receive++;
delay_us(2);
}
SCL_L;
if (!ack)
IIC_NAck();
else
IIC_Ack();
return receive;
}
实例读写操作:
读一个字节
IIC_Start(); //IIC开始信号
IIC_Send_Byte(0x94); //IIC器件的写地址,告诉IIC器件要写数据。
IIC_Send_Byte(0x03); //写IIC器件的寄存器
IIC_Stop(); //IIC停止信号
IIC_Start(); //IIC开始信号
IIC_Send_Byte(0x95); //写IIC器件的读地址,告诉IIC器件要读数据。
temp[0] = IIC_Read_Byte(0); //读IIC器件对应寄存器数据,只读一个字节,所以发送非应答信号
IIC_Stop(); //IIC停止信号
读二个字节
IIC_Start(); //IIC开始信号
IIC_Send_Byte(0x94); //IIC器件的写地址,告诉IIC器件要写数据。
IIC_Send_Byte(0x03); //写IIC器件的寄存器
IIC_Stop(); //IIC停止信号
IIC_Start(); //IIC开始信号
IIC_Send_Byte(0x95); //写IIC器件的读地址,告诉IIC器件要读数据。
temp[0] = IIC_Read_Byte(1); //读IIC器件对应寄存器数据,读第一个字节,所以发送应答信号
temp[1] = IIC_Read_Byte(0); //读IIC器件对应寄存器数据,读第二个字节,所以发送非应答信号
IIC_Stop(); //IIC停止信号
读多个字节
IIC_Start(); //IIC开始信号
IIC_Send_Byte(0x94); //IIC器件的写地址,告诉IIC器件要写数据。
IIC_Send_Byte(0x03); //写IIC器件的寄存器
IIC_Stop(); //IIC停止信号
IIC_Start(); //IIC开始信号
IIC_Send_Byte(0x95); //写IIC器件的读地址,告诉IIC器件要读数据。
temp[0] = IIC_Read_Byte(1); //读IIC器件对应寄存器数据,读第一个字节,所以发送应答信号
temp[1] = IIC_Read_Byte(1); //读IIC器件对应寄存器数据,读第二个字节,所以发送应答信号
...
...
temp[n] = IIC_Read_Byte(0); //读IIC器件对应寄存器数据,读第最后一个字节,所以发送非应答信号
IIC_Stop(); //IIC停止信号