热门标签 | 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从机的设计告一段落。


推荐阅读
  • golang常用库:配置文件解析库/管理工具viper使用
    golang常用库:配置文件解析库管理工具-viper使用-一、viper简介viper配置管理解析库,是由大神SteveFrancia开发,他在google领导着golang的 ... [详细]
  • 优化ListView性能
    本文深入探讨了如何通过多种技术手段优化ListView的性能,包括视图复用、ViewHolder模式、分批加载数据、图片优化及内存管理等。这些方法能够显著提升应用的响应速度和用户体验。 ... [详细]
  • 本文基于刘洪波老师的《英文词根词缀精讲》,深入探讨了多个重要词根词缀的起源及其相关词汇,帮助读者更好地理解和记忆英语单词。 ... [详细]
  • 本教程涵盖OpenGL基础操作及直线光栅化技术,包括点的绘制、简单图形绘制、直线绘制以及DDA和中点画线算法。通过逐步实践,帮助读者掌握OpenGL的基本使用方法。 ... [详细]
  • 深入理解Redis的数据结构与对象系统
    本文详细探讨了Redis中的数据结构和对象系统的实现,包括字符串、列表、集合、哈希表和有序集合等五种核心对象类型,以及它们所使用的底层数据结构。通过分析源码和相关文献,帮助读者更好地理解Redis的设计原理。 ... [详细]
  • 深入解析Android自定义View面试题
    本文探讨了Android Launcher开发中自定义View的重要性,并通过一道经典的面试题,帮助开发者更好地理解自定义View的实现细节。文章不仅涵盖了基础知识,还提供了实际操作建议。 ... [详细]
  • 本文详细介绍了Java中org.neo4j.helpers.collection.Iterators.single()方法的功能、使用场景及代码示例,帮助开发者更好地理解和应用该方法。 ... [详细]
  • Explore how Matterverse is redefining the metaverse experience, creating immersive and meaningful virtual environments that foster genuine connections and economic opportunities. ... [详细]
  • 本文探讨了如何在给定整数N的情况下,找到两个不同的整数a和b,使得它们的和最大,并且满足特定的数学条件。 ... [详细]
  • 基于KVM的SRIOV直通配置及性能测试
    SRIOV介绍、VF直通配置,以及包转发率性能测试小慢哥的原创文章,欢迎转载目录?1.SRIOV介绍?2.环境说明?3.开启SRIOV?4.生成VF?5.VF ... [详细]
  • MySQL DateTime 类型数据处理及.0 尾数去除方法
    本文介绍如何在 MySQL 中处理 DateTime 类型的数据,并解决获取数据时出现的.0尾数问题。同时,探讨了不同场景下的解决方案,确保数据格式的一致性和准确性。 ... [详细]
  • 深入解析TCP/IP五层协议
    本文详细介绍了TCP/IP五层协议模型,包括物理层、数据链路层、网络层、传输层和应用层。每层的功能及其相互关系将被逐一解释,帮助读者理解互联网通信的原理。此外,还特别讨论了UDP和TCP协议的特点以及三次握手、四次挥手的过程。 ... [详细]
  • 由于工作需要,接手别人用bpel写的工作流程序,一点都不懂就到网上找到一篇入门的文章,觉得这篇不错,就copy下来并添加了读书笔计以红字标记,感激写此文章的人.许多开发人员觉得BPEL很神秘,不知道 ... [详细]
  • Java动态代理的应用
    MathJax.Hub.Config({showMathMenu:false}); ... [详细]
  • 基于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社区 版权所有