关于IIC通讯协议的有关问题

问题:如何正确使用IIC这么优秀的通讯协议呢?

解决:
第一步:知道起始信号和终止信号

当SCL为1的时候,SDA从1变成0,这个就是起始信号,说明可以开始传输;当SCL为1的时候,SDA从0变成1,这个就是终止信号,说明传输停止。可想而知需要操作很多次,我们要编写相关函数。

第二步:知道ACK应答和NACK非应答

当传输完一个字节的数据的时候,如果还需要继续继续传输数据,那么从机需要给主机发送对应的信号,当还要继续传输的时候,SDA从1变成0;当SDA一直是1的时候,表示可以结束传输。

另外:应答的时候,SDA=0,SCL需要等于1,非应答的时候,SDA=1,SCL也需要等于1。

第三步:IIC到底是如何读写数据的呢?

一般而言,从机的设备地址为七位,剩下的一位表示读写,0表示写,1表示读.

例如图2 24c02,1010 0000表示给这个从机写入,1010 0001表示从这个从机读出。

第四步:其他,怎么连接?

这样接即可,需要接上拉电阻。图2说的是,当SCL=0的时候,数据才可以传递。

具体配置:起始,结束,应答,非应答

问题来了,从机发送信号给主机,是否继续传输信号,那么主机如何判断呢?没有接收到应答信号应该如何?这个时候就要写一个等待应答函数,没有应答超过一定时间,就停止传输。如下

那么数据到底是如何写和读的呢?如下

//产生IIC起始信号函数,具体配置如下
void IIC_start()
{
        SDA=1;
        delay_10us(1);
        SCL=1;
        delay_10us(1);
        SDA=0;
        delay_10us(1);
        SCL=0;    //为传输数据做准备
        delay_10us(1);
}

//产生IIC停止信号函数
void IIC_stop()
{
    SDA=0;
    delay_10us(1);
    SCL=1;
    delay_10us(1);
    SDA=1;
    delay_10us(1);
}

//产生ACK应答信号函数
void IIC_ack()
{
    SCL=0;    //产生ACK需要保证SCL=0
    SDA=0;    //低电平表示应答
    delay_10us(1);
    SCL=1;
    delay_10us(1);
    SCL=0;
}

//产生NACK非应答信号函数
void IIC_nack()
{
    SCL=0;    //产生ACK需要保证SCL=0
    SDA=1;    //高电平表示非应答
    delay_10us(1);
    SCL=1;
    delay_10us(1);
    SCL=0;
}

//等待接收ACK应答函数,如果接收到了返回1,没有接收到,返回0,等待应答是为了进行下次传输
u8 IIC_wait_ack()
{
        u8 num_time=0;
        SCL=1;
        delay_10us(1);
        while(SDA)
        {
            num_time++;
            if(num_time>100)
            {
                IIC_stop();//停止传输
                return 0;
            }
        }
        SCL=0;//允许传输
        return 1;
}

//IIC发送一个字节
void IIC_write_byte(u8 dat)
{
    u8 num_f;
    SCL=0;
    for(num_f=0;num_f<8;num_f++)
    {
            if((dat&0x80)>0)            SDA=1;//表示1高电平
            else                        SDA=0;//表示低电平
            dat=dat<<1;    //从高位依次写入
            delay_10us(1);
            SCL=1;
            delay_10us(1);
            SCL=0;
            delay_10us(1);
    }
}

//IIC接收一个字节,将接收到的返回,ack=1,表示应答,ack=0表示非应答
u8 IIC_read_byte(u8 ack)
{
        u8 num_f,receive=0;
    for(num_f=0;num_f<8;num_f++)
    {
            SCL=0;
            delay_10us(1);
            SCL=1;
            receive=receive<<1;//从高位依次读出
        if(SDA)  receive++;
                    delay_10us(1);

    }
    if(!ack)  IIC_nack();
    else         IIC_ack();
    return receive;
}

实际应用:

对到这个图理解效果会更好.

//往24c02里指定地址写入一个字节的数据
void AT24C02_write_byte(u8 address,u8 dat)
{
        IIC_start();//起始条件
      IIC_write_byte(0xA0);//从设备地址,并且是写入
        IIC_wait_ack();//等待应答
        IIC_write_byte(address);//写入地址数据
        IIC_wait_ack();//等待应答
        IIC_write_byte(dat);//发送数据
        IIC_wait_ack();//等待应答
        IIC_stop();//写入一个字节,停止一下
        delay_ms(10);
}

//在24c02里指定地址读出一个字节的数据
u8 AT24c02_read_byte(u8 address)
{
        u8 temp=0;
        IIC_start();//起始条件
      IIC_write_byte(0xA0);//从设备地址,表示读出
        IIC_wait_ack();//等待应答
      IIC_write_byte(address);//写入地址数据
        IIC_wait_ack();//等待应答,否则停止传输
        IIC_start();
      IIC_write_byte(0xA1);//发送读命令
        IIC_wait_ack();//等待应答
        temp=IIC_read_byte(0);//将读出的数据给temp,并且0表示非应答,表示结束
        IIC_stop();
        return temp;
}

注意:当SCL为0的时候,SDA状态可以变,用于传输数据,SCL为1的时候,SDA状态不能变,只能读。

  • 7
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
回答: IIC通信协议常见问题包括以下几个方面: 1. IIC总线的主设备如何结束通信过程?主设备可以通过产生一个停止条件来结束通信过程,停止条件由SCL上的0->1转换后SDA上的0->1(低到高)转换定义,SCL保持高电平。在正常的数据写操作时,SDA上的值应该不会在SCL为高电平时改变,以避免错误的停止条件。\[2\] 2. IIC总线的高级特性之一是10-bit地址是什么意思?10-bit地址是指在IIC总线中,地址可以使用10位来表示,相比于传统的7位地址,10-bit地址提供了更大的地址空间,可以连接更多的设备。\[3\] 3. IIC总线是一种多主机总线,如何处理多个主机同时启用总线的情况?当总线上有多个主机同时启用总线时,IIC总线具备冲突检测和仲裁的功能来防止错误产生。每个连接到IIC总线上的器件都有一个唯一的地址(7位),且每个器件都可以作为主机也可以作为从机,总线上的设备增加和删除不影响其他器件的正常工作。\[3\] 4. IIC通信总线的通信过程是怎样的?通信过程包括以下几个步骤:主机发送起始信号启用总线,主机发送一个字节数据指明从机地址和后续字节的传递方向,被寻址的从机发送应答信号回应主机,发送器发送一个字节数据,接收器发送应答信号回应发送器,循环进行数据传输,通信完成后主机发送停止信号释放总线。\[3\] 总的来说,IIC通信协议是一种串行、半双工的总线协议,主要用于近距离、低速的芯片之间的通信。它具有简单的硬件结构和低成本,并且在各个领域得到了广泛的应用。\[3\] #### 引用[.reference_title] - *1* *2* [【硬件通信协议】1. 详细解析IIC通信协议](https://blog.csdn.net/sishuihuahua/article/details/88128761)[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^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [stm32中常见的通信协议之IIC](https://blog.csdn.net/nbbskk/article/details/127861990)[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^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值