I2C扫描从设备方法

说明

这几天在研究0.96寸OLED屏;但是一直都点不亮,同事建议用I2C扫描从设备地址,如是写了这个函数;虽然最终确定不是软件问题,但是解题思路很好,因此记录下来;MCU是STM32F103VE.

思路

I2C发送从设备地址,检测哪些地址有应答,则把这些地址答应出来,即可知道此I2C挂载了多少从设备;

代码

I2C_SCAN.H

#ifndef __I2C_SCAN_H
#define __I2C_SCAN_H
#include "stm32f10x.h"
#include "stm32f10x_i2c.h"/**************************I2C参数定义,I2C1或I2C2********************************/
#define             EEPROM_I2Cx                                I2C1
#define             EEPROM_I2C_APBxClock_FUN                   RCC_APB1PeriphClockCmd
#define             EEPROM_I2C_CLK                             RCC_APB1Periph_I2C1
#define             EEPROM_I2C_GPIO_APBxClock_FUN              RCC_APB2PeriphClockCmd
#define             EEPROM_I2C_GPIO_CLK                        RCC_APB2Periph_GPIOB
#define             EEPROM_I2C_SCL_PORT                        GPIOB
#define             EEPROM_I2C_SCL_PIN                         GPIO_Pin_6
#define             EEPROM_I2C_SDA_PORT                        GPIOB
#define             EEPROM_I2C_SDA_PIN                         GPIO_Pin_7/*等待超时时间*/
#define I2CT_FLAG_TIMEOUT         ((uint32_t)0x1000)
#define I2CT_LONG_TIMEOUT         ((uint32_t)(10 * I2CT_FLAG_TIMEOUT))/*信息输出*/
#define EEPROM_DEBUG_ON         0#define EEPROM_INFO(fmt,arg...)           printf("<<-EEPROM-INFO->> "fmt"\n",##arg)
#define EEPROM_ERROR(fmt,arg...)          printf("<<-EEPROM-ERROR->> "fmt"\n",##arg)
#define EEPROM_DEBUG(fmt,arg...)          do{\if(EEPROM_DEBUG_ON)\printf("<<-EEPROM-DEBUG->> [%d]"fmt"\n",__LINE__, ##arg);\}while(0)void I2C_SCAN_Init(void);//主函数调用下面函数,如果检测地址0~200中间是否有外设的地址,把200写入进去即可
uint32_t I2C_SCAN(uint32_t TEST_ADDRESS);
#endif /*__BSP_I2C_24C02_H*/

I2C_SCAN.C

#include "i2c_scan.h"static __IO uint32_t  I2CTimeout = I2CT_LONG_TIMEOUT;   static uint32_t I2C_TIMEOUT_UserCallback(uint8_t errorCode);static  void I2C_GPIO_Config(void)
{//PB6=SCL;PB7=SDA   I2C1GPIO_InitTypeDef    GPIO_InitStructure;//使能GPIOB时钟;使能I2C时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1,ENABLE);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;//复用开漏输出GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB,&GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;//复用开漏输出GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB,&GPIO_InitStructure);
}static  void I2C_Mode_Config(void)
{I2C_InitTypeDef I2C_InitStructure;//设置速度为400KhzI2C_InitStructure.I2C_ClockSpeed = 100000;I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;//占空比1:2I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;//指定自身地址I2C_InitStructure.I2C_OwnAddress1 = 0x10;I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;//设备地址七位I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;I2C_Init(I2C1,&I2C_InitStructure);
}void I2C_SCAN_Init(void)
{I2C_GPIO_Config();I2C_Mode_Config();
}uint32_t I2C_SCAN(uint32_t TEST_ADDRESS)
{while(TEST_ADDRESS>0){/* Send STRAT condition */I2C_GenerateSTART(EEPROM_I2Cx, ENABLE);I2CTimeout = I2CT_FLAG_TIMEOUT;  /* Test on EV5 and clear it */while(!I2C_CheckEvent(EEPROM_I2Cx, I2C_EVENT_MASTER_MODE_SELECT))  {if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(0);} I2CTimeout = I2CT_FLAG_TIMEOUT;/* Send EEPROM address for write */I2C_Send7bitAddress(EEPROM_I2Cx, TEST_ADDRESS, I2C_Direction_Transmitter);/* Test on EV6 and clear it */while(!I2C_CheckEvent(EEPROM_I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)){if((--I2CTimeout) == 0) break;}if(I2CTimeout>0) printf("%#x\n",TEST_ADDRESS);  /* Send STOP condition */I2C_GenerateSTOP(EEPROM_I2Cx, ENABLE);TEST_ADDRESS--;}
}/*** @brief  Basic management of the timeout situation.* @param  errorCode:错误代码,可以用来定位是哪个环节出错.* @retval 返回0,表示IIC读取失败.*/
static  uint32_t I2C_TIMEOUT_UserCallback(uint8_t errorCode)
{/* Block communication and all processes */EEPROM_ERROR("I2C 等待超时!errorCode = %d",errorCode);return 0;
}

最终打印效果&不解的地方

本次挂载了两个从设备,一个是24C02地址为0XA0;一个是OLED,地址为0X78;但最终打印出来的数据如下:
0xaf
0xae
0xad
0xac
0xab
0xaa
0xa9
0xa8
0xa7
0xa6
0xa5
0xa4
0xa3
0xa2
0xa1
0xa0
0x79
0x78

不知道为什么会打印这么多;知道的讲一下哦!

I2C扫描从设备方法相关推荐

  1. linux设备和驱动匹配的方法,Linux使用设备树的i2c驱动与设备匹配方式

    Linux使用设备树的i2c驱动与设备匹配有3种方式: of_driver_match_device acpi_driver_match_device i2c_match_id 源码: static ...

  2. android 蓝牙不停扫描,android – BluetoothAdapter不会停止扫描BLE设备

    在我的应用程序中我有启动和停止按钮,当用户按下启动时我调用startScan方法 bluetoothAdapter.getBluetoothLeScanner().startScan(getLeSca ...

  3. linux i2c adapter 增加设备_Linux驱动之I2C驱动架构

    一.Linux的I2C体系结构 主要由三部分组成: (1) I2C核心 提供I2C控制器和设备驱动的注册和注销方法,I2C通信方法,与适配器无关的代码以及探测设备等. (2) I2C控制器驱动(适配器 ...

  4. 【转】Android bluetooth介绍(三): 蓝牙扫描(scan)设备分析

    原文网址:http://blog.csdn.net/xubin341719/article/details/38584469 关键词:蓝牙blueZ  A2DP.SINK.sink_connect.s ...

  5. 蓝牙能扫描到设备,但是无法成功配对,键盘需要键入PIN

    笔记本蓝牙功能异常 出现的情况描述: 更新驱动!没有用.删除卸载驱动没有用 不要下载什么驱动精灵!第三方的驱动!不靠谱 要么去官网找个靠谱的 写在最后! 出现的情况描述: 产品是联想thinkbook ...

  6. 二维码扫描讲解系统设计方法

    二维码扫描讲解系统设计方法 测试软件平台进入: http://www.cqu-media.top http://www.cqu-media.com/qrcode.aspx http://www.cqu ...

  7. php扫描蓝牙设备接口,微信硬件蓝牙扫描某个设备接口onScanWXDeviceResult

    好久没更新微信硬件蓝牙开发的技术文章了,最近闲来无事,翻了翻系列文章以及微信硬件jsapi接口,发现onScanWXDeviceResult扫描某个设备接口并没有做案例demo给大家分享出来,所以接着 ...

  8. sonar扫描普通JAVA执行,SonarQube扫描源代码的方法

    SonarQube扫描源代码的方法 雷建锋 一.分析源代码综述 一旦成功安装了SonarQube平台,您就可以开始安装一个分析器并开始创建项目了.在第一次分析时,该平台会自动创建一个项目.如果您需要在 ...

  9. 计算机开机扫描磁盘,电脑开机扫描磁盘的方法

    禁止电脑每次开机都要自动扫描磁盘的多种方法 点评:不管是正常关机还是非正常关机,启动时都会自动扫描D盘,我用了chkdsk /f 命令和诺顿磁盘医生,pq8等工具修复都没用,下面有几个不错的解决方法, ...

最新文章

  1. How is data replicted from HANA to AS
  2. 浅谈SQL注入风险 - 一个Login拿下Server(转)
  3. 《运营之光》《策略产品经理》《推荐系统实践》读书笔记随笔
  4. 将模块放入到一个项目中展示_一个号称NB的开源电商系统
  5. 我们的内存中都放了什么
  6. 用java判断x奇或偶_改善java程序——用偶判断,不用奇判断
  7. VMware11.1.2+centOS7.4虚拟机联网问题并设置静态IP
  8. Android:图解四种启动模式 及 实际应用场景解说
  9. vc6怎么新建一个c++程序?
  10. 强大的CHM电子书或CHM帮助文件的快速制作工具Easy CHM
  11. 计算机任务栏隐藏恢复,电脑任务栏不见了怎么办?如何找回?
  12. 【python】实现共享表格协同编辑
  13. ps里面的css,PS中如何添加图层样式
  14. java excel 创建控件_Java 添加、删除Excel表单控件
  15. wx.scanCode(Object object)使用详解
  16. oracle odi 配置安装,ODI的安装和配置
  17. 用U盘安装Windows server 2012 R2
  18. 基于C语言的AES加密算法实现
  19. 初识Python必看基础知识~ 续(3)
  20. PDN设计关键点之滤波电容位置

热门文章

  1. 内部类(成员内部类+局部内部类+静态内部类+匿名内部类)
  2. 滂什么大什么的成语(滂什么大什么四字成语大全)
  3. 利用cookie进行登录
  4. 关于vue中表单和组件的笔记
  5. 自定义Python排序函数比较方式
  6. 浅谈ANR及如何分析解决ANR(2)
  7. C语言斐波那契数列求和两种方法
  8. Android修改充电图片,安卓充电提示音修改教程
  9. 常见的SQL跟数据库优化
  10. TOEFL听力——笔记方法