【转】三种方法让你在I2C通信中同时和多个从机通信
ref:http://tieba.baidu.com/p/3769008030
对于不同地址的模块就不用多说了,直接分别对其地址进行通信即可。那么若拿到相同地址的模块,或者直接是相同的多个模块怎么办呢?
经过楼主对adxl345的苦苦摸索,这里给大家分享三种方法。
方法一:(内置了两种地址的模块)
对于内置了两种地址的模块,可以通过对某个引脚置高或置低来选择其中一个地址,现假设置高为A,置低为B。
假设你有三个模块要同时通信,首先将模块1置高,模块2、模块3的地址选择口置低,这样仅有模块1在地址A,然后对地址A进行通信即可防止其他模块干扰。接下来将模块1置低,模块2置高,即可对模块2通信。循环下去即可实现同时对三个模块通信。
方法二:(具有使能端的模块)
若你手中的模块某个引脚必须拉低或拉高才能正常使用,那么仿照方法一,对其中一个使能,其他均处于非使能状态,如此便可以仅对其中一个模块通信咯。
如果以上都不行,那就只能方法三了。
万能方法三:(什么都没有,仅有一种地址的模块)
原本买来六个ADXL345来读取不同地方的加速度信息,datasheet里说可以通过对某个引脚置高置低来选择其中一个地址。然而发现并不能改变地址!于是只好想出这样一个邪恶的方法。
用到的工具是模拟开关,楼主以CD4053为例,这货非常便宜,几元钱可以买一大把。
简单来说模拟开关相当于多个单刀双掷开关,可以通过IO口输出高低电平控制某两路连通。
我们知道I2C通信有 SCL和SDA两根线,我们通过调整模拟开关使仅有一个模块完整接入I2C BUS即可实现只对其中一个通信。
具体实施方式:
假设有模块1 2 3
CD4053的 ay by cy悬空 ax bx cx并接到单片机的SCL
将模块1的SCL口接CD4053的a口
将模块2的SCL口接CD4053的b口
将模块3的SCL口接CD4053的c口
这样只需将A置高,B、C置低,即可与模块1通信
故同理,将B置高,A、C置低,即可与模块2通信
故同理,将C置高,A、B置低,即可与模块3通信
亲测有效,读数稳定,
不过注意一定要将CD4053 VEE和VSS都接地,不然读数抖动不稳定,楼主在这里卡死了很久。
上代码 以ADXL345为例:
boolean x=true; //是否调试输出 //CD4053的接入方式
//INH口接地 aY->SCL1 bY->SCL2 cY->SCL3 a.b.c->SCL_Arduino #define CD4053_C 10
#define CD4053_B 9
#define CD4053_A 8 //----------1
//CBA 000 不接通
//CBA 100 C接通
//CBA 010 B接通
//CBA 001 A接通 //----------2 //PIN
#define PIN_SDA 20
#define PIN_SCL 21 //I2C (sparkfun breakout)
#define Register_ID 0
#define Register_2D 0x2D
#define Register_X0 0x32
#define Register_X1 0x33
#define Register_Y0 0x34
#define Register_Y1 0x35
#define Register_Z0 0x36
#define Register_Z1 0x37 #include <Wire.h>
int ADXAddress = 0x53; // the default 7-bit slave address
int reading = ;
int val=;
int X0,X1,X_out;
int Y0,Y1,Y_out;
int Z1,Z0,Z_out;
double Xg,Yg,Zg;
int flag=; //标志变量 void Wire_Start(){
Wire.beginTransmission(ADXAddress);
Wire.write(Register_2D);
Wire.write(); //measuring enable
Wire.endTransmission(); // stop transmitting
} void Wire_Get()
{
//--------------X
Wire.beginTransmission(ADXAddress); // transmit to device
Wire.write(Register_X0);
Wire.write(Register_X1);
Wire.endTransmission();
Wire.requestFrom(ADXAddress,);
if(Wire.available()<=)
{
X0 = Wire.read();
X1 = Wire.read();
X1=X1<<;
X_out=X0+X1;
}
//------------------Y
Wire.beginTransmission(ADXAddress); // transmit to device
Wire.write(Register_Y0);
Wire.write(Register_Y1);
Wire.endTransmission();
Wire.requestFrom(ADXAddress,);
if(Wire.available()<=)
{
Y0 = Wire.read();
Y1 = Wire.read();
Y1=Y1<<;
Y_out=Y0+Y1;
}
//------------------Z
Wire.beginTransmission(ADXAddress); // transmit to device
Wire.write(Register_Z0);
Wire.write(Register_Z1);
Wire.endTransmission();
Wire.requestFrom(ADXAddress,);
if(Wire.available()<=)
{
Z0 = Wire.read();
Z1 = Wire.read();
Z1=Z1<<;
Z_out=Z0+Z1;
}
//----------------
Xg=X_out/256.0;
Yg=Y_out/256.0;
Zg=Z_out/256.0;
} void setup()
{
Wire.begin();
if(x)
Serial.begin();
delay(); pinMode(CD4053_A,OUTPUT);
pinMode(CD4053_B,OUTPUT);
pinMode(CD4053_C,OUTPUT);
// enable to measute g data digitalWrite(CD4053_A,HIGH);
digitalWrite(CD4053_B,LOW);
digitalWrite(CD4053_C,LOW);
delay();
Wire_Start(); //初始化模块1 digitalWrite(CD4053_A,LOW);
digitalWrite(CD4053_B,HIGH);
delay();
Wire_Start(); //初始化模块2 digitalWrite(CD4053_B,LOW);
digitalWrite(CD4053_C,HIGH);
delay();
Wire_Start(); //初始化模块3 }
void loop()
{
if(x){
Serial.print("----");
Serial.print((flag+));
Serial.println("----");}
switch(flag){
case : {
digitalWrite(CD4053_A,HIGH);
digitalWrite(CD4053_C,LOW);
Wire_Get(); //读取模块1
flag=;
break;
}
case :{ digitalWrite(CD4053_B,HIGH);
digitalWrite(CD4053_A,LOW);
Wire_Get(); //读取模块2
flag=;
break;
}
case :{ digitalWrite(CD4053_C,HIGH);
digitalWrite(CD4053_B,LOW);
Wire_Get(); //读取模块3
flag=;
break;
}
} if(x)
{
Serial.print("X= ");
Serial.print(Xg);
Serial.print(" ");
Serial.print("Y= ");
Serial.print(Yg);
Serial.print(" ");
Serial.print("Z= ");
Serial.println(Zg);
}
delay(); //改变参数可以改变读取频率
}
【转】三种方法让你在I2C通信中同时和多个从机通信的更多相关文章
- python更新数据库脚本三种方法
最近项目的两次版本迭代中,根据业务需求的变化,需要对数据库进行更新,两次分别使用了不同的方式进行更新. 第一种:使用python的MySQLdb模块利用原生的sql语句进行更新 import MySQ ...
- 像画笔一样慢慢画出Path的三种方法(补充第四种)
今天大家在群里大家非常热闹的讨论像画笔一样慢慢画出Path的这种效果该如何实现. 北京-LGL 博客号@ligl007发起了这个话题.然后各路高手踊跃发表意见.最后雷叔 上海-雷蒙 博客号@雷蒙之星 ...
- JAVA之线程同步的三种方法
最近接触到一个图片加载的项目,其中有声明到的线程池等资源需要在系统中线程共享,所以就去研究了一下线程同步的知识,总结了三种常用的线程同步的方法,特来与大家分享一下.这三种方法分别是:synchroni ...
- java解析xml的三种方法
java解析XML的三种方法 1.SAX事件解析 package com.wzh.sax; import org.xml.sax.Attributes; import org.xml.sax.SAXE ...
- 【Android】Eclipse自动编译NDK/JNI的三种方法
[Android]Eclipse自动编译NDK/JNI的三种方法 SkySeraph Sep. 18th 2014 Email:skyseraph00@163.com 更多精彩请直接访问SkySer ...
- DataTable数据批量写入数据库三种方法比较
DataTable数据批量写入数据库三种方法比较 标签: it 分类: C#1) insert循环插入:2) sqldataadapter.update(dataset,tablename); ...
- 转载:WinForm中播放声音的三种方法
转载:WinForm中播放声音的三种方法 金刚 winForm 播放声音 本文是转载的文章.原文出处:http://blog.csdn.net/jijunwu/article/details/4753 ...
- [mysql]三种方法为root账户指定密码
前言:前段时间把mysql安装后一直没管它,当时就在奇怪为什么mysql登陆不要密码,原来一直用的超用户账户登陆的(简称超级用户) 其实只怪自己太无知,之前一直用的phpbydamin进行的数据库的可 ...
- 三种方法查看MySQL数据库的版本
1.使用-V参数 首先我们想到的肯定就是查看版本号的参数命令,参数为-V(大写字母)或者--version 使用方法: D:\xampp\mysql\bin>mysql -V 或者 D:\xam ...
随机推荐
- Robot Framework(十八) 支持工具
5支持工具 5.1库文档工具(libdoc) libdoc是一种用于为HTML和XML格式的测试库和资源文件生成关键字文档的工具.前一种格式适用于人类,后者适用于RIDE和其他工具.Libdoc也没有 ...
- python数据分析与应用
python数据分析与应用笔记 使用sklearn构建模型 1.使用sklearn转换器处理数据 import numpy as np from sklearn.datasets import loa ...
- ubantu 安装boost库 c++connector
安装libmysqlcppconn: sudo apt-get install libmysqlcppconn-dev 安装libboost: sudo apt-get install libboos ...
- C之内存地址
计算机的内存地址 * 32位系统最多能识别4G内存 * 32位系统的地址总线长度是32位的,也就是说能分配给内存地址的数字是 2的32次方个 * 内存中每一个字节都需要一个内存地址 * 一个数字对用一 ...
- spring中的原型模式
大家好,我原本是神剑山庄的铸剑师,名叫小赵,本来干的好好的,后来一时兴起,睡了三少爷的小姨子,与其一直提心吊胆,干脆来个逃之夭夭. 但是,我也要吃饭的呀,工作也得找,神剑山庄去不得,还有断剑山庄.藏剑 ...
- Flutter路由_fluro引入配置和使用
Flutter本身提供了路由机制,作个人的小型项目,完全足够了.但是如果你要作企业级开发,可能就会把入口文件变得臃肿不堪.而再Flutter问世之初,就已经了企业级路由方案fluro. flutter ...
- Opengl_入门学习分享和记录_03_渲染管线(三)借助顶点数组对象VAO提高绑定属性效率
目前我们已经知道了,如果想要顶点着色器解释理解我们的输入数据,就必须要按照以下繁琐的步骤:第一步:将输入的数据复制一份到缓冲区,供OpenGL使用.而这块新出现的区域由VBO管理和表示.(若有多个输入 ...
- Session服务器之Memcached与Redis
安装Memcached[root@nginx ~]# yum -y install libevent memcached 指定用户大小等信息,工作环境中常指定大小一般为4到8G,此信息测试使用.[ro ...
- 【编程开发】C语言中随机数rand使用注意事项
[编程开发]C语言中随机数rand使用注意事项 标签: [编程开发] 声明:引用请注明出处http://blog.csdn.net/lg1259156776/ 说明:随机数在编程开发中非常重要,以C语 ...
- 记录一次SignalR服务端实现过程
前言:最近手上一个项目需要后端实时推送数据到前端,第一个想到的就是微软的SignalR,由于之前都是平时没事写的Demo,没有用到实际项目中,这次恰好用到了,因此记录下来整个实现过程(网上也有很多类似 ...