模拟IIC的实现

模拟IIC都使用了五年了,现在第一次以博客的形式分享出来,后续还会继续分享更多黑科技资料!
IIC总线目前在单片机开发应用当中非常的常见,比如四轴无人机要读取陀螺仪加速计的数据可以用IIC读取,读取磁力计需要用IIC读取,读取气压计需要用到IIC。IIC总线用法相对简单,硬件只需要接两根线就可以,一个时钟线(SCL),一个数据线(SDA);需要注意的是数据线在接硬件的时候一般需要外接上拉

IIC时许

模拟IIC的实现_第1张图片
对于IIC其信号主要有以下几个 :

开始信号、结束信号和应答/非应答信号。也如上图;

开始结束信号

模拟IIC的实现_第2张图片

应答非应答信号

模拟IIC的实现_第3张图片
然后我们直接上模拟IIC程序:
static void I2C_delay(void){volatile int i=3;while(i–);}//先定义一个IIC时延,用于后面IIC调整速率。

IIC开始信号

void I2C_Start(void)
{
SDA_OUT();
SDA_H;
SCL_H;
I2C_delay();
SDA_L; //START:when CLK is high,DATA change form high to low
I2C_delay();
SCL_L;
}

IIC结束信号

void I2C_Stop(void)
{
SDA_OUT();
SCL_L;
SDA_L;//STOP:when CLK is high DATA change form low to high
I2C_delay();
SCL_H;
SDA_H;
I2C_delay();
}

IIC应答信号

void I2C_Ack(void)
{
SCL_L;
SDA_OUT();
SDA_L;
I2C_delay();
SCL_H;
I2C_delay();
SCL_L;
}

IIC非应答信号

void I2C_NoAck(void)
{
SCL_L;
SDA_OUT();
SDA_H;
I2C_delay();
SCL_H;
I2C_delay();
SCL_L;
}

IIC等待应答信号

uint8 I2C_WaitAck(void)
{
uint8_t ucErrTime=0;
SDA_IN(); //SDAÉèÖÃΪÊäÈë
SDA_H;
I2C_delay();
SCL_H;
I2C_delay();
while(SDA_read)
{
ucErrTime++;
if(ucErrTime>50)
{
I2C_Stop();
return 0;
}
I2C_delay();
}
SCL_L;
return 1;
} //IIC发送完一个字节数据或者地址时需要等待应答,若收到应答则表示主机跟设备通信成功。

IIC写入数据和读数据

void I2C_SendByte(uint8 SendByte)
{
uint8_t t;   
 SDA_OUT();      
    SCL_L;
    I2C_delay();
 for(t=0;t<8;t++)
 {              
  	if(SendByte&0x80) 
   	   SDA_H;
 	 else
   	   SDA_L;
  	SendByte<<=1;    
 	I2C_delay();  
 	SCL_H;
	 I2C_delay();
 	SCL_L;
 	I2C_delay();
}
uint8 I2C_ReceiveByte(void)
{
	uint8_t i=0,receive=0;
	SDA_IN();
	for(i=0;i<8;i++ )
	 {
        		SCL_L; 
        		I2C_delay();
  		SCL_H;
        		receive<<=1;
       		 if(SDA_read) receive++;   
 		 I2C_delay();
    	}      
    return receive;
}

至此,IIC大概介绍完。
这几年在用IIC过程中遇到的比较多的问题就是软件IIC写好了但是硬件IIC没有加上拉,这个问题也可以通过示波器查看,一般在一个字节时钟内(8个时钟周期),SDA无法正常拉高拉低大概就是这个问题。

你可能感兴趣的:(模拟IIC的实现)