IIC通讯详解笔记

IIC概述

IIC总线是一种串行半双工两线总线。一根是双向的数据线SDA,另一根是时钟线SCL。所有接到IIC总线设备上的串行数据SDA都接到总线的SDA上,各设备的时钟线SCL接到总线的SCL上。硬件拓扑如下图所示,且每个器件都有唯一的设备地址来确定每个器件,地址位通常为7bit。

IIC总线是一种多主机总线,连接在IIC总线上的器件可分为主机和从机。其中每个器件都可以作为主机也可以作为从机。(但同一时刻只能有一个主机)。主机有权发起和结束一次通讯。而从机只能被主机呼叫。并且,IIC总线的时钟信号是由主控器件(主机)产生。在传输速率上,串行的8位双向数据传输位速率在标准模式下可达100kbit/s,快速模式下可达400kbit/s,高速模式下可达3.4Mbit/s。

IIC总线上的器件增加和删除不会影响其他器件正常工作,并且IIC总线在通讯时总线上发送数据的器件称为发送器,接收数据的器件称为接收器

在这里插入图片描述

  • 对于硬件IIC和软件IIC各有优劣,考虑实际情况具体使用。为更好理解IIC,文章下描述的是采用软件IIC。

IIC协议

IIC的通信过程由开始、结束、发送、响应、接收五个部分构成。并且在通讯过程中,IIC的SCL线和SDA线遵循以下原则:

  • 当SCL高电平时采样SDA电平状态,此时SDA电平状态不允许改变。
  • 当SCL低电平时不采样SDA电平状态,此时SDA电平状态允许改变。
  • IIC在总线空闲状态时,这两根线通常是被外部上拉电阻拉高,保持着高电平。

IIC总线通讯过程

  1. 主机发送起始信号启用总线
  2. 主机发送一个字节数据,指明从机地址和后续字节的传输方向(7bit地址加1bit读写(0-主机写/1-主机读))
  3. 被寻址的从机发送应答信号回应主机
  4. 发送器发送一个字节数据
  5. 接收器发送应答信号回应发送机
  6. (…循环4.5)
  7. 通讯完成后,主机发送停止信号释放总线

典型的IIC时序

在这里插入图片描述
在这里插入图片描述
下面是拆分通讯过程的描述和代码实现。
开始信号与停止信号

  • 开始信号:当SCL为高期间,SDA由高到低的跳变;启动信号是一种电平跳变时序信号,而不是一个电平。
  • 停止信号:当SCL为高期间,SDA由低到高的跳变;停止信号也是一种电平跳变时序信号,而不是一个电平信号。
  • 此时的起始信号和停止信号都是由主机发出的,起始信号产生后,总线处于占用,停止信号产生后,总线处于空闲状态(MSB)。
    在这里插入图片描述
//产生IIC起始信号
void IIC_Start(void)
{
    SDA_OUT();      //1.设置SDA输出
    IIC_SDA=1;      //2.先拉高SDA      
    IIC_SCL=1;      //3.再拉高SCL,空闲状态
    delay_us(4);
    IIC_SDA=0;      //4.拉低SDA START:when CLK is high,DATA change form high to low 
    delay_us(4);
    IIC_SCL=0;      //5.钳住I2C总线,准备发送或接收数据 
}
//产生IIC停止信号
void IIC_Stop(void)
{
    SDA_OUT();     //1.sda线输出
    IIC_SCL=0;     //2.先拉低SCL
    IIC_SDA=0;     //3.再拉低SDA STOP:when CLK is high DATA change form low to high
    delay_us(4);
    IIC_SCL=1;     //4.拉高SCL
    IIC_SDA=1;     //5.拉高SDA 发送I2C总线结束信号
    delay_us(4);                                   
}

应答信号
发送器每发送一个字节(8个bit),就在时钟脉冲9期间释放数据线,由接收器反馈一个应答信号。

  1. 当主机向从机发送完一个字节的数据,主机总是需要等待从机给出一个应答信号,以确认从机是否成功接收到了数据,从机应答主机所需要的时钟仍是主机提供的。应答出现在每一次主机完成8个数据位传输后紧跟着的时钟周期,低电平0表示应答,1表示非应答。

在这里插入图片描述

//等待应答信号到来
//返回值:1,接收应答失败
//      0,接收应答成功
//1.设置SDA为输入
//2.拉高SDA
//3.拉高SCL
//4.等待接收器返回应答信号,如果数据线SDA一直为高,就一直等待,并返回1(无效应答),如果数据线SDA为低,返回0(有效应答)
u8 IIC_Wait_Ack(void)
{
    u8 ucErrTime=0;
    SDA_IN();      //SDA设置为输入  
    IIC_SDA=1;delay_us(1);       
    IIC_SCL=1;delay_us(1);     
    while(READ_SDA)
    {
        ucErrTime++;
        if(ucErrTime>250)
        {
            IIC_Stop();
            return 1;
        }
    }
    IIC_SCL=0;//时钟输出0        
    return 0;  
}
  1. 当从机向主机发送完一个字节的数据,从机也是需要等待主机给出一个应答信号。

//产生ACK应答
//这里就很清楚了,产生应答:SCL在SDA一直为低电平期间完成低高电平转换
void IIC_Ack(void)
{
    IIC_SCL=0;
    SDA_OUT();
    IIC_SDA=0;
    delay_us(2);
    IIC_SCL=1;
    delay_us(2);
    IIC_SCL=0;
}
//不产生ACK应答    
//这里就很清楚了,不产生应答:SCL在SDA一直为高电平期间完成低高电平转换
void IIC_NAck(void)
{
    IIC_SCL=0;
    SDA_OUT();
    IIC_SDA=1;
    delay_us(2);
    IIC_SCL=1;
    delay_us(2);
    IIC_SCL=0;
}

发送数据

//IIC发送一个字节
//返回从机有无应答
//1,有应答
//0,无应答            

//IIC_SCL=0;
//在SCL上升沿时准备好数据,进行传送数据时,拉高拉低SDA,因为传输一个字节,一个SCL脉冲里传输一个位。
//数据传输过程中,数据传输保持稳定(在SCL高电平期间,SDA一直保持稳定,没有跳变)
//只有当SCL被拉低后,SDA才能被改变
//总结:在SCL为高电平期间,发送数据,发送8次数据,数据为1,SDA被拉高,数据为0,SDA被拉低。
//传输期间保持传输稳定,所以数据线仅可以在时钟SCL为低电平时改变。
void IIC_Send_Byte(u8 txd)
{                        
    u8 t;   
    SDA_OUT();         
    IIC_SCL=0;//拉低时钟开始数据传输
    for(t=0;t<8;t++)
    {              
        //IIC_SDA=(txd&0x80)>>7;
        //获取数据的最高位,然后左移7位
        //如果某位为1,则SDA为1,否则相反
        if((txd&0x80)>>7)
            IIC_SDA=1;
        else
            IIC_SDA=0;
        txd<<=1;       
        delay_us(2);   //对TEA5767这三个延时都是必须的
        IIC_SCL=1;
        delay_us(2); 
        IIC_SCL=0;    
        delay_us(2);
    }     
}

接收数据


//读1个字节,ack=1时,发送ACK,ack=0,发送nACK   

//先拉低SCL,延时后拉高
//读取数据
//是否发送应答
u8 IIC_Read_Byte(unsigned char ack)
{
    unsigned char i,receive=0;
    SDA_IN();//SDA设置为输入
    for(i=0;i<8;i++ )
    {
        IIC_SCL=0; 
        delay_us(2);
        IIC_SCL=1;
        receive<<=1;
        if(READ_SDA)receive++;   
        delay_us(1); 
    }                     
    if (!ack)
        IIC_NAck();//发送nACK
    else
        IIC_Ack(); //发送ACK   
    return receive;
}

参考文章

[1]: IIC通信详解

  • 6
    点赞
  • 46
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
IIC(Inter-Integrated Circuit)是一种串行通信总线协议,用于在集成电路之间进行通信。它具有简单、高效、可靠的特点,广泛应用于各种电子设备中。 根据引用\[2\]中的内容,IIC总线协议包括以下几个步骤: 1. 起始状态和结束状态:通信开始时,主机发送起始信号,然后发送设备地址和读/写位。通信结束时,主机发送停止信号。 2. 数据传输:主机通过IIC总线向从机写入数据时,将数据发送到从机的地址中。主机从从机读取数据时,从机将数据发送到总线上。 3. 应答信号:在每个数据字节传输后,接收方会发送应答信号,表示是否成功接收数据。 根据引用\[1\]和引用\[3\]中的代码,可以看出顶层模块`iic_send_top`和`iic_recv_top`分别用于发送和接收数据。这些模块通过IIC总线与设备进行通信,并通过时钟信号和数据线进行数据传输。 综上所述,IIC verilog详解主要包括IIC总线协议的特点、通信步骤和数据传输方式,以及通过Verilog代码实现IIC发送和接收功能的设计思路和接口定义。 #### 引用[.reference_title] - *1* *2* *3* [IIC总线的原理与Verilog实现](https://blog.csdn.net/qq_38695100/article/details/119153048)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值