I2C外设

I2C外设_第1张图片

I2C的总结

I2C优点:

接口线少只有两根线,控制方式简单,通信速率较高;

I2C 是飞利浦公司开发的两线式串行总线;

I2C缺点:

硬件比较复杂,稳定性不太好,程序移植有点麻烦,用软件模拟I2C比较方便

物理层特点:

(1)支持多设备的总线

(2)一个总线只使用两根线,数据线SDA,时钟线SCL

(3)每个连接总线都设备都有一个独立的地址,查询设备都是靠这个地址

(4)总线通过上拉电阻,空闲的时候就输出高阻态,所有设备空间的时候,会拉成高电平

(5)多个主机同时使用总线的时候,就会使用仲裁

(6)总线传输模式,标准100kbits/s,快速模式400kbit.s

I2C协议有什么?

I2C 里面定义了通信的 6 个方面

1、起始和停止信号

2、数据有效性、

3、响应

4、仲裁

5、时钟同步

6、地址广播


(1)数据有效性

I2C外设_第2张图片

I2C传输数据,SCL时钟要为高电平期间,SDA传输数据的线必须稳定;

时钟为低电平的期间,数据线上的高电平或者低电平数据允许发生变化;

传输数据以字节为单位,每次传输的字节数不受限制;


(2)起始和停止信号

I2C外设_第3张图片

时钟SCL为高电平期间,SDA数据线由高电平向低电平变化表示起始信号;

时钟SCL为高电平期间,SDA数据线由低电平向高电平变化表示停止信号;

起始和停止信号都是由主机发出,发送起始信号后,总线就处于被占用的状态,主机发送停止信号后,总线就处于空闲状态;


(3)应答和响应

I2C外设_第4张图片

发送端传输完一个字节的数据后,后面必须要跟一个校验位,这个校验位是 从机 通过控制SDA(数据线)来实现的,主机可以继续发送数据,这个校验位就是数据或地址传输过程中的响应。

响应分为(应答ACK)和(非应答NACK)

作为从机 当 主机接收到I2C传输的一个字节数据或地址后,若让主机继续发送需要向对方发送应答ACk信号低电平脉冲,主机就会继续发送下一个数据;

若从机希望结束数据传输,则会向主机发送 非应答NACK信号高电平脉冲,主机收到非应答信号,就会产生停止信号,结束信号传输;

每个字节必须保证8位,先传送高位MSB ,在传输地位LSB,传送的字节要跟一位应答位 (一帧 9 位 )


(4)总线的寻址方式

I2C外设_第5张图片

分为两种,7位和10位的

D7~D1 是 从机的地址,D0位是数据传送方向位;

为0表示主机向从机写数据,为1 主机向 从机读数据;

主机发送一个地址,总线上每个器件都将头7位于自己的地址比较,一样,就会被主机选址

四位是固定的,3个可编程


(5)数据传输模式

I2C外设_第6张图片

主机发送起始信号,发送从机地址+使能位写数据,从机发送应答,主机发送数据,从机应答主机发送数据,非应答,主机 发送结束信号;

I2C外设_第7张图片

软件模拟:

#include "iic.h"


// at 芯片读写操作的
// 起始信号
void iic_start(void)
{
        IIC_SCL = 1;
        IIC_SDA = 1;
        delay_10us(1);
        IIC_SDA = 0;
        delay_10us(1);
        IIC_SCL = 0;
        // 处于占用

}


// 停止信号

void iic_stop(void)
{
        IIC_SCL = 1;
        IIC_SDA = 0;
        delay_10us(1);
        IIC_SDA = 1;
        delay_10us(1);
}


// 应答信号

void iic_ack(void)
{
        IIC_SCL = 0;
        IIC_SDA = 0;
        delay_10us(1);
        IIC_SCL = 1;
        delay_10us(1);
        IIC_SCL = 0;
}

// 非应答信号

void iic_nack(void)
{
        IIC_SCL = 0;
        IIC_SDA = 1;
        delay_10us(1);
        IIC_SCL = 1;
        delay_10us(1);
        IIC_SCL = 0;        

}


u8 iic_wait_ack(void)
{
        u8 time_temp =0;

        IIC_SDA = 1;
        delay_10us(1);
        while(IIC_SDA)
        {
                time_temp++;
                if(time_temp>100)
                {
                        iic_stop();
                        return 1; // 返回1 停止应答         
                }                        
        }
        IIC_SDA = 0;
        return 0;        

} 

// IIC写字节的操作
void iic_write_byte( u8 dat)        // 入参 传入字节
{
        //
        u8 i =0;
        IIC_SCL=0;
        for(i=0;i<8;i++)  //从高位 在地位 写入
        {
                if( (dat&0x80) > 1)  // 0x80 1000 0000  从最高位 判断最高位为1 如果大于0
                        IIC_SDA = 1;
                else
                        IIC_SDA = 0;
                dat <<= 1; // 左移一位
                IIC_SDA = 0;
                delay_10us(1);
                IIC_SCL=0;
                delay_10us(1); 
        } 
}

// IIC 读字节操作
u8 iic_read_byte(u8 ack)
{
        u8 i =0;
        u8 receive =0;

        for(i=0;i<8;i++)
        {
                IIC_SCL = 0;
                delay_10us(1);
                IIC_SCL=1;
                delay_10us(1);
                receive<<=1;
                if(IIC_SDA)receive++;         
        
        }
        
        if(!ack)iic_nack();
        else iic_ack();

        return receive;        

}

你可能感兴趣的:(51单片机,外设,单片机学习-通用知识,单片机,嵌入式硬件,51单片机)