热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

GPIO实现I2C从机的设计[2]

在上篇文章中,实现了GPIO模拟I2C从机的初步设计,但在实际的使用过程中,发现了一些问题,为了解决实际传输过程中发生的数据传输错误问题,在本篇文章中,会根据实际测试情况对上篇的代码做一些修改。

在上篇文章中,实现了GPIO模拟I2C从机的初步设计,但在实际的使用过程中,发现了一些问题,为了解决实际传输过程中发生的数据传输错误问题,在本篇文章中,会根据实际测试情况对上篇的代码做一些修改。

问题描述
主从机传输主要发生在从机接收数据部分,下图1是使用示波器(500MHz 2.5GS/s)抓取的主机发送的时钟和数据信号关系。可以在图中看出:
①时钟占空比并不是50%
②数据变化并不是在时钟的高电平或者低电平的中间部位发生变化,而是在时钟刚发生跳变之后就发生了变化。(图中测试发现时钟变化150ns之后数据信号就发生了变化)
图1
图1

根据上篇文章的代码(见下)

while(!recFinish)
{
    for(bitcount = 0; bitcount <8; bitcount ++)
    {
        while(GET_SCL_DAT);
        SDA_IN;
        while(!GET_SCL_DAT);

        r0 = GET_SDA_DAT;
        while(GET_SCL_DAT)
        {
            r1 = GET_SDA_DAT;
            if((r0 == 0) && (r1 == 1))
            {
                recFinish = 1;
                return 1;
            }
        }   
        rxbyte <<= 1;
        if(r1)
            rxbyte |= 0x01;
        else
            rxbyte |= 0x00; 
    }
    buf[(*len)++] = rxbyte;
    IIC_SLAVE_SEND_ACK;
}
return 0;

在r1位置的极限情况下,r1会采样到SCL刚变为低的值,这样就会发生错误的采样,在实际测试中发生了下列错误的采样(主机将数据写入从机,并从从机中读取以验证)
图2
图2 读写测试

可以看到一些规律,每一个Byte只会发生一次错误,所有的错误都是高位没有采样到。原因就发生才r1采样的时候采样错误。

为了改正这种错误,就需要重新确定采样值。

        if(r1)
            rxbyte |= 0x01;
        else
            rxbyte |= 0x00;

有两种修改方法:一种是在取采样值的时候,取r0,这样避免在取r1的时候出现数据跳变,即上面的代码修改为:

        if(r0)
            rxbyte |= 0x01;
        else
            rxbyte |= 0x00;

但这种修改方法还是有不完善的地方,因为r0也有可能发生跳变,也有可能是一个不稳定的采样点,那么最理想的状态是采样图1中r2的值,r1可能在SCL发生跳变的瞬间也发生数据的跳变,但是r2一定是在SCL为高的时候的采样点,是不会发生数据的跳变的。

代码可修改如下:

while(!recFinish)
{
    for(bitcount = 0; bitcount <8; bitcount ++)
    {
        while(GET_SCL_DAT);
        SDA_IN;
        while(!GET_SCL_DAT);

        r0 = GET_SDA_DAT;
        r1 = r0;
        while(GET_SCL_DAT)
        {
            r2 = r1;
            r1 = GET_SDA_DAT;
            if((r0 == 0) && (r2 == 1))
            {
                recFinish = 1;
                return 1;
            }
        }

        rxbyte <<= 1;
        if(r2)
            rxbyte |= 0x01;
        else
            rxbyte |= 0x00; 
    }
    buf[(*len)++] = rxbyte;
    IIC_SLAVE_SEND_ACK;
}
return 0;

由此修改后,可以保证采样值正确,接收数据也正常,不会发生数据错误。

在此,GPIO模拟I2C从机的设计告一段落。


推荐阅读
  • 先看官方文档TheJavaTutorialshavebeenwrittenforJDK8.Examplesandpracticesdescribedinthispagedontta ... [详细]
  • 本文讨论了在VMWARE5.1的虚拟服务器Windows Server 2008R2上安装oracle 10g客户端时出现的问题,并提供了解决方法。错误日志显示了异常访问违例,通过分析日志中的问题帧,找到了解决问题的线索。文章详细介绍了解决方法,帮助读者顺利安装oracle 10g客户端。 ... [详细]
  • 合并列值-合并为一列问题需求:createtabletab(Aint,Bint,Cint)inserttabselect1,2,3unionallsel ... [详细]
  • 本文介绍了设计师伊振华受邀参与沈阳市智慧城市运行管理中心项目的整体设计,并以数字赋能和创新驱动高质量发展的理念,建设了集成、智慧、高效的一体化城市综合管理平台,促进了城市的数字化转型。该中心被称为当代城市的智能心脏,为沈阳市的智慧城市建设做出了重要贡献。 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • 本文介绍了C#中生成随机数的三种方法,并分析了其中存在的问题。首先介绍了使用Random类生成随机数的默认方法,但在高并发情况下可能会出现重复的情况。接着通过循环生成了一系列随机数,进一步突显了这个问题。文章指出,随机数生成在任何编程语言中都是必备的功能,但Random类生成的随机数并不可靠。最后,提出了需要寻找其他可靠的随机数生成方法的建议。 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • 本文介绍了在CentOS上安装Python2.7.2的详细步骤,包括下载、解压、编译和安装等操作。同时提供了一些注意事项,以及测试安装是否成功的方法。 ... [详细]
  • 配置IPv4静态路由实现企业网内不同网段用户互访
    本文介绍了通过配置IPv4静态路由实现企业网内不同网段用户互访的方法。首先需要配置接口的链路层协议参数和IP地址,使相邻节点网络层可达。然后按照静态路由组网图的操作步骤,配置静态路由。这样任意两台主机之间都能够互通。 ... [详细]
  • MPLS VP恩 后门链路shamlink实验及配置步骤
    本文介绍了MPLS VP恩 后门链路shamlink的实验步骤及配置过程,包括拓扑、CE1、PE1、P1、P2、PE2和CE2的配置。详细讲解了shamlink实验的目的和操作步骤,帮助读者理解和实践该技术。 ... [详细]
  • 本文由编程笔记#小编整理,主要介绍了关于数论相关的知识,包括数论的算法和百度百科的链接。文章还介绍了欧几里得算法、辗转相除法、gcd、lcm和扩展欧几里得算法的使用方法。此外,文章还提到了数论在求解不定方程、模线性方程和乘法逆元方面的应用。摘要长度:184字。 ... [详细]
  • Android自定义控件绘图篇之Paint函数大汇总
    本文介绍了Android自定义控件绘图篇中的Paint函数大汇总,包括重置画笔、设置颜色、设置透明度、设置样式、设置宽度、设置抗锯齿等功能。通过学习这些函数,可以更好地掌握Paint的用法。 ... [详细]
  • 本文介绍了在Android开发中使用软引用和弱引用的应用。如果一个对象只具有软引用,那么只有在内存不够的情况下才会被回收,可以用来实现内存敏感的高速缓存;而如果一个对象只具有弱引用,不管内存是否足够,都会被垃圾回收器回收。软引用和弱引用还可以与引用队列联合使用,当被引用的对象被回收时,会将引用加入到关联的引用队列中。软引用和弱引用的根本区别在于生命周期的长短,弱引用的对象可能随时被回收,而软引用的对象只有在内存不够时才会被回收。 ... [详细]
  • 由于工作需要,接手别人用bpel写的工作流程序,一点都不懂就到网上找到一篇入门的文章,觉得这篇不错,就copy下来并添加了读书笔计以红字标记,感激写此文章的人.许多开发人员觉得BPEL很神秘,不知道 ... [详细]
  • 基于FPGA的串口通讯设计
    这个小项目是在2013年初学FPGA时所做的,现把当时的设计笔记贴出来。RS232C电气规定EIA-RS-232C对电气特定、逻辑电平和各信号线功能都做了相关规定。在此部分,只简单 ... [详细]
author-avatar
mobiledu2502912677
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有