210 lines
5.6 KiB
C
210 lines
5.6 KiB
C
#include <bsp_iic.h>
|
||
|
||
|
||
//初始化IIC
|
||
void Soft_IIC_Init(SIAS *i2c_dev)
|
||
{
|
||
if(i2c_dev->Soft_IIC_GPIO_Port_Init!=NULL){
|
||
i2c_dev->Soft_IIC_GPIO_Port_Init(); //初始化IIC的GPIO端口
|
||
}
|
||
i2c_dev->Soft_IIC_SCL(1);
|
||
i2c_dev->Soft_IIC_SDA(1);
|
||
}
|
||
|
||
//产生IIC起始信号
|
||
void Soft_IIC_Start(SIAS *i2c_dev)
|
||
{
|
||
i2c_dev->Soft_SDA_OUT(); //sda线输出
|
||
i2c_dev->Soft_IIC_SDA(1);
|
||
i2c_dev->Soft_IIC_SCL(1);
|
||
// delay_us(4);
|
||
i2c_dev->Soft_IIC_SDA(0);//START:when CLK is high,DATA change form high to low
|
||
i2c_dev->delay_us(1);
|
||
i2c_dev->Soft_IIC_SCL(0);//钳住I2C总线,准备发送或接收数据
|
||
}
|
||
//产生IIC停止信号
|
||
void Soft_IIC_Stop(SIAS *i2c_dev)
|
||
{
|
||
i2c_dev->Soft_SDA_OUT();//sda线输出
|
||
i2c_dev->Soft_IIC_SCL(0);
|
||
i2c_dev->Soft_IIC_SDA(0);//STOP:when CLK is high DATA change form low to high
|
||
// delay_us(4);
|
||
i2c_dev->Soft_IIC_SCL(1);
|
||
i2c_dev->Soft_IIC_SDA(1);//发送I2C总线结束信号
|
||
// delay_us(4);
|
||
}
|
||
//等待应答信号到来
|
||
//返回值:1,接收应答失败
|
||
// 0,接收应答成功
|
||
uint8_t Soft_IIC_Wait_Ack(SIAS *i2c_dev)
|
||
{
|
||
uint8_t ucErrTime=0;
|
||
i2c_dev->Soft_SDA_IN(); //SDA设置为输入
|
||
i2c_dev->Soft_IIC_SDA(1);i2c_dev->delay_us(1);
|
||
i2c_dev->Soft_IIC_SCL(1);i2c_dev->delay_us(1);
|
||
while(i2c_dev->Soft_READ_SDA())
|
||
{
|
||
ucErrTime++;
|
||
if(ucErrTime>250)
|
||
{
|
||
Soft_IIC_Stop(i2c_dev);
|
||
return 1;
|
||
}
|
||
}
|
||
i2c_dev->Soft_IIC_SCL(0);//时钟输出0
|
||
return 0;
|
||
}
|
||
//产生ACK应答
|
||
void Soft_IIC_Ack(SIAS *i2c_dev)
|
||
{
|
||
i2c_dev->Soft_IIC_SCL(0);
|
||
i2c_dev->Soft_SDA_OUT();
|
||
i2c_dev->Soft_IIC_SDA(0);
|
||
i2c_dev->delay_us(1);
|
||
i2c_dev->Soft_IIC_SCL(1);
|
||
// delay_us(2);
|
||
i2c_dev->Soft_IIC_SCL(0);
|
||
}
|
||
//不产生ACK应答
|
||
void Soft_IIC_NAck(SIAS *i2c_dev)
|
||
{
|
||
i2c_dev->Soft_IIC_SCL(0);
|
||
i2c_dev->Soft_SDA_OUT();
|
||
i2c_dev->Soft_IIC_SDA(1);
|
||
i2c_dev->delay_us(1);
|
||
i2c_dev->Soft_IIC_SCL(1);
|
||
// delay_us(2);
|
||
i2c_dev->Soft_IIC_SCL(0);
|
||
}
|
||
//IIC发送一个字节
|
||
//返回从机有无应答
|
||
//1,有应答
|
||
//0,无应答
|
||
void Soft_IIC_Send_Byte(SIAS *i2c_dev,uint8_t txd)
|
||
{
|
||
uint8_t t;
|
||
i2c_dev->Soft_SDA_OUT();
|
||
i2c_dev->Soft_IIC_SCL(0);//拉低时钟开始数据传输
|
||
for(t=0;t<8;t++)
|
||
{
|
||
i2c_dev->Soft_IIC_SDA((txd&0x80)>>7);
|
||
txd<<=1;
|
||
i2c_dev->delay_us(1);
|
||
i2c_dev->Soft_IIC_SCL(1);
|
||
i2c_dev->delay_us(1);
|
||
i2c_dev->Soft_IIC_SCL(0);
|
||
// delay_us(1);
|
||
}
|
||
}
|
||
//读1个字节,ack=1时,发送ACK,ack=0,发送nACK
|
||
uint8_t Soft_IIC_Receive_Byte(SIAS *i2c_dev,unsigned char ack)
|
||
{
|
||
unsigned char i,receive=0;
|
||
i2c_dev->Soft_SDA_IN();//SDA设置为输入
|
||
for(i=0;i<8;i++ )
|
||
{
|
||
i2c_dev->Soft_IIC_SCL(0);
|
||
i2c_dev->delay_us(1);
|
||
i2c_dev->Soft_IIC_SCL(1);
|
||
receive<<=1;
|
||
if(i2c_dev->Soft_READ_SDA())receive++;
|
||
// delay_us(1);
|
||
}
|
||
if (!ack)
|
||
Soft_IIC_NAck(i2c_dev);//发送nACK
|
||
else
|
||
Soft_IIC_Ack(i2c_dev); //发送ACK
|
||
return receive;
|
||
}
|
||
|
||
uint8_t Soft_IIC_Write_Byte(SIAS *i2c_dev,uint8_t addr,uint8_t reg,uint8_t data)
|
||
{
|
||
Soft_IIC_Start(i2c_dev);
|
||
Soft_IIC_Send_Byte(i2c_dev,addr|0);//发送器件地址+写命令
|
||
if(Soft_IIC_Wait_Ack(i2c_dev)) //等待应答
|
||
{
|
||
Soft_IIC_Stop(i2c_dev);
|
||
return 1;
|
||
}
|
||
Soft_IIC_Send_Byte(i2c_dev,reg); //写寄存器地址
|
||
Soft_IIC_Wait_Ack(i2c_dev); //等待应答
|
||
Soft_IIC_Send_Byte(i2c_dev,data);//发送数据
|
||
if(Soft_IIC_Wait_Ack(i2c_dev)) //等待ACK
|
||
{
|
||
Soft_IIC_Stop(i2c_dev);
|
||
return 1;
|
||
}
|
||
Soft_IIC_Stop(i2c_dev);
|
||
return 0;
|
||
}
|
||
|
||
uint8_t Soft_IIC_Read_Byte(SIAS *i2c_dev,uint8_t addr,uint8_t reg)
|
||
{
|
||
uint8_t res;
|
||
Soft_IIC_Start(i2c_dev);
|
||
Soft_IIC_Send_Byte(i2c_dev,addr|0);//发送器件地址+写命令
|
||
Soft_IIC_Wait_Ack(i2c_dev); //等待应答
|
||
Soft_IIC_Send_Byte(i2c_dev,reg); //写寄存器地址
|
||
Soft_IIC_Wait_Ack(i2c_dev); //等待应答
|
||
Soft_IIC_Start(i2c_dev);
|
||
Soft_IIC_Send_Byte(i2c_dev,addr|1);//发送器件地址+读命令
|
||
Soft_IIC_Wait_Ack(i2c_dev); //等待应答
|
||
res=Soft_IIC_Receive_Byte(i2c_dev,0);//读取数据,发送nACK
|
||
Soft_IIC_Stop(i2c_dev); //产生一个停止条件
|
||
return res;
|
||
}
|
||
|
||
uint8_t Soft_IIC_Write_Len(SIAS *i2c_dev,uint8_t addr,uint8_t reg,uint8_t len,uint8_t *buf)
|
||
{
|
||
uint8_t i;
|
||
Soft_IIC_Start(i2c_dev);
|
||
Soft_IIC_Send_Byte(i2c_dev,addr|0);//发送器件地址+写命令
|
||
if(Soft_IIC_Wait_Ack(i2c_dev)) //等待应答
|
||
{
|
||
Soft_IIC_Stop(i2c_dev);
|
||
return 1;
|
||
}
|
||
Soft_IIC_Send_Byte(i2c_dev,reg); //写寄存器地址
|
||
Soft_IIC_Wait_Ack(i2c_dev); //等待应答
|
||
for(i=0;i<len;i++)
|
||
{
|
||
Soft_IIC_Send_Byte(i2c_dev,buf[i]); //发送数据
|
||
if(Soft_IIC_Wait_Ack(i2c_dev)) //等待ACK
|
||
{
|
||
Soft_IIC_Stop(i2c_dev);
|
||
return 1;
|
||
}
|
||
}
|
||
Soft_IIC_Stop(i2c_dev);
|
||
return 0;
|
||
}
|
||
|
||
uint8_t Soft_IIC_Read_Len(SIAS *i2c_dev,uint8_t addr,uint8_t reg,uint8_t len,uint8_t *buf)
|
||
{
|
||
Soft_IIC_Start(i2c_dev);
|
||
Soft_IIC_Send_Byte(i2c_dev,addr|0);//发送器件地址+写命令
|
||
if(Soft_IIC_Wait_Ack(i2c_dev)) //等待应答
|
||
{;
|
||
printf("未检测到IIC设备");
|
||
Soft_IIC_Stop(i2c_dev);
|
||
return 1;
|
||
}
|
||
Soft_IIC_Send_Byte(i2c_dev,reg); //写寄存器地址
|
||
Soft_IIC_Wait_Ack(i2c_dev); //等待应答
|
||
Soft_IIC_Start(i2c_dev);
|
||
Soft_IIC_Send_Byte(i2c_dev,addr|1);//发送器件地址+读命令
|
||
Soft_IIC_Wait_Ack(i2c_dev); //等待应答
|
||
while(len)
|
||
{
|
||
if(len==1)*buf=Soft_IIC_Receive_Byte(i2c_dev,0);//读数据,发送nACK
|
||
else *buf=Soft_IIC_Receive_Byte(i2c_dev,1); //读数据,发送ACK
|
||
len--;
|
||
buf++;
|
||
}
|
||
Soft_IIC_Stop(i2c_dev); //产生一个停止条件
|
||
return 0;
|
||
}
|
||
|
||
|
||
|