查看: 5329|回复: 0

[原创] 【我要创作】LPC824 Lite之GPIO模拟I2C,I2C总线设备扫描

[复制链接]
  • TA的每日心情
    开心
    14 小时前
  • 签到天数: 2927 天

    连续签到: 18 天

    [LV.Master]伴坛终老

    23

    主题

    4142

    帖子

    82

    金牌会员

    Rank: 6Rank: 6

    积分
    13782
    最后登录
    2025-7-23
    发表于 2017-3-12 21:56:14 | 显示全部楼层 |阅读模式
    本帖最后由 toofree 于 2017-3-12 22:07 编辑

            【我要创作】LPC824 Lite之GPIO模拟I2C,I2C总线设备扫描。

             在之前的两篇帖子中,两个I2C设备挂在了同一组I2C总线上。于是就想着,万一要是更多的设备同时挂在一组I2C总线上,会怎么样呢,怎么识别目前总线上挂的设备。那么I2C总线上到底挂着多少个设备,ID都是多少,最好是自动扫描出来。
            【我要创作】LPC824 Lite之GPIO模拟I2C,MPR121电容触摸传感器
    https://www.nxpic.org.cn/module/foru ... 9574&fromuid=307297
    (出处: 恩智浦技术社区)
            【我要创作】LPC824 Lite之GPIO模拟I2C,读写EEPROM
    https://www.nxpic.org.cn/module/foru ... 9573&fromuid=307297
    (出处: 恩智浦技术社区)
            
            网上查资料,看到过有人做过基于“gd32f1x0”的I2C总线扫描程序。但是他是基于硬件I2C模块的,没有看懂什么原理。查找相关I2C总线扫描内容,也没有找到有效的参考资料。
            于是从I2C协议着手,一点一点的找线索。大概思路是I2C地址范围从0x00到0x7f,逐个往后扫描。当然这其中有部分地址是保留的,有其它用处。但不妨碍我们做I2C扫描。当扫描到某个在线的I2C设备时,设备会发送应用信息ACK,如果没有ACK应答,则认为此地址上没有设备。


            关键的文件还是之前读写EEPROM时增加的4个文件,,“delay.c”、“delay.h”、“I2C_Driver.c”,“I2C_Driver.h”。在本实验中增加的几个函数,直接写在主函数中。
             傲游截图20170312214946.jpg

            实验硬件及连线同上一篇LPC824 Lite之GPIO模拟I2C,MPR121电容触摸传感器”。
            


            整体工程结构预览。原理在上面已经有讲。
             SNAG-0005.jpg

            增加了3个函数。      
    1. /* I2C总线释放总线 */
    2. void I2C_Release(void)
    3. {
    4.         uint8_t i=16;
    5.         SDA_H;
    6.         SCL_H;
    7.         I2C_delay();
    8.         I2C_delay();
    9.         
    10.         while(i--)
    11.         {
    12.                 SCL_L;
    13.                 I2C_delay();
    14.                 I2C_delay();
    15.                
    16.                 SCL_H;
    17.                 I2C_delay();
    18.                 I2C_delay();
    19.         }        
    20. }

    21. /* I2C总线广播呼叫,复位总线上所有器件 */
    22. uint8_t I2C_Reset(void)
    23. {
    24.         uint8_t state1=0,state2=0;
    25.         
    26.         I2C_Start();
    27.         
    28.         I2C_SendByte(0x00);                //广播呼叫
    29.         
    30.         state1 = I2C_WaitAck();
    31.         
    32.         I2C_SendByte(0x06);                //通过硬件写入和复位从机地址的可编程部分
    33.         
    34.         state2 = I2C_WaitAck();
    35.         
    36.         I2C_Stop();        
    37.         
    38.         //state1或state2 为FALSE,总线上没有从设备        
    39.         if ((state1 == FALSE) || (state2 == FALSE))
    40.                 return FALSE;
    41.         else
    42.                 return TRUE;        
    43. }

    44. uint8_t I2C_ScanOneAddr(uint8_t DeviceAddress)
    45. {
    46.         uint8_t state=0;
    47.         
    48.         I2C_Start();
    49.         
    50.         I2C_SendByte((DeviceAddress & 0xFE));//设置高起始地址+器件地址
    51.         
    52.         state = I2C_WaitAck();
    53.         
    54.         I2C_Stop();
    55.         
    56.         //state总线上没有从设备,state2总线上没有地址为DeviceAddress的从设备
    57.         if (state == FALSE)
    58.                 return FALSE;
    59.         else
    60.                 return TRUE;        
    61. }
    复制代码
           I2C_Release()为了释放I2C总线,同一条I2C总线挂多个设备时,不能保证总线在空闲状态,因此需要增加释放总线操作。这条不见得对所有I2C设备管用,但有总胜于无吧。
            I2C_Reset()这个函数请忽略,这是自己根据I2C协议写的,有些东西还没搞明白,不一定能行。在这里加上,是想着如果有高手研究过,或感兴趣可以看看。
            I2C_ScanOneAddr(uint8_t DeviceAddress),此函数就是今天的主角了。原理在上面已经描述过了,程序也是根据I2C扫描原理写的,简单明了,相信大家一看就明白。

            好了,不扯了。直接全速跑程序,看看效果吧。
             SNAG-0006.jpg
            目前总线上挂的就是这两个设备,地址正确。

            按照惯例,程序打包附上。 SDK(gpio_I2C_Scan).rar (472.71 KB, 下载次数: 42)
    回复

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /3 下一条

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2025-7-23 14:22 , Processed in 0.079312 second(s), 20 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

    快速回复 返回顶部 返回列表