【转】三种方法让你在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 = 0; int val=0; int X0,X1,X_out; int Y0,Y1,Y_out; int Z1,Z0,Z_out; double Xg,Yg,Zg; int flag=1; //标志变量void Wire_Start(){ Wire.beginTransmission(ADXAddress); Wire.write(Register_2D); Wire.write(8); //measuring enable Wire.endTransmission(); // stop transmitting }void Wire_Get(){//--------------XWire.beginTransmission(ADXAddress); // transmit to deviceWire.write(Register_X0);Wire.write(Register_X1);Wire.endTransmission();Wire.requestFrom(ADXAddress,2);if(Wire.available()<=2){X0 = Wire.read();X1 = Wire.read();X1=X1<<8;X_out=X0+X1;}//------------------YWire.beginTransmission(ADXAddress); // transmit to deviceWire.write(Register_Y0);Wire.write(Register_Y1);Wire.endTransmission();Wire.requestFrom(ADXAddress,2);if(Wire.available()<=2){Y0 = Wire.read();Y1 = Wire.read();Y1=Y1<<8;Y_out=Y0+Y1;}//------------------ZWire.beginTransmission(ADXAddress); // transmit to deviceWire.write(Register_Z0);Wire.write(Register_Z1);Wire.endTransmission();Wire.requestFrom(ADXAddress,2);if(Wire.available()<=2){Z0 = Wire.read();Z1 = Wire.read();Z1=Z1<<8;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(9600);delay(100);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(10);Wire_Start(); //初始化模块1 digitalWrite(CD4053_A,LOW);digitalWrite(CD4053_B,HIGH);delay(10);Wire_Start(); //初始化模块2 digitalWrite(CD4053_B,LOW);digitalWrite(CD4053_C,HIGH);delay(10);Wire_Start(); //初始化模块3 } void loop() {if(x){Serial.print("----");Serial.print((flag+0));Serial.println("----");}switch(flag){case 1: {digitalWrite(CD4053_A,HIGH);digitalWrite(CD4053_C,LOW);Wire_Get(); //读取模块1flag=2;break;}case 2:{digitalWrite(CD4053_B,HIGH);digitalWrite(CD4053_A,LOW);Wire_Get(); //读取模块2flag=3;break;}case 3:{digitalWrite(CD4053_C,HIGH);digitalWrite(CD4053_B,LOW);Wire_Get(); //读取模块3flag=1;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(33); //改变参数可以改变读取频率 }
转载于:https://www.cnblogs.com/schips/p/10795711.html
【转】三种方法让你在I2C通信中同时和多个从机通信相关推荐
- java持久层用文件_JAVA中用三种方法将字符串持久化到文件中
经常需要将数据进行持久化,而我们的文件系统是最古老也是最可靠的保存方式.这里就给出一个在JAVA中把字符串保存到文件中的例子.如下: package test.base; import java.io ...
- matlab中 三种方法计算 Ax b,在MATLAB中,方程Ax=B的解可以用哪个命令求得? matlab 求助 解方程组...
matlab中解方程组还是很方便的,例如,对于代数方程组Ax=b(A为系数矩阵,非奇异)的求解,MATLAB中有两种方法: (1)x=inv(A)*b - 采用求逆运算解方程组: (2)x=A\B - ...
- 三种方法,Python轻松提取PDF中全部图片
有时我们需要将一份或者多份PDF文件中的图片提取出来,如果采取在线的网站实现的话又担心图片泄漏,手动操作又觉得麻烦,其实用Python也可以轻松搞定! 今天就跟大家系统分享几种Python提取 PDF ...
- php mysql 表字段_php mysql获取表字段名称和字段信息的三种方法
php mysql获取表字段名称和字段信息的三种方法 先给出本实例中使用的表的信息: 使用desc获取表字段信息 php代码如下: mysql_connect("localhost" ...
- Spark创建DataFrame的三种方法
跟关系数据库的表(Table)一样,DataFrame是Spark中对带模式(schema)行列数据的抽象.DateFrame广泛应用于使用SQL处理大数据的各种场景.创建DataFrame有很多种方 ...
- Functional vs OOP vs Procedural三种方法 JavaScript 示例
#有什么问题? 当谈到编写好的代码时,您可以深入探讨关于好的代码到底是什么样子以及您应该遵循哪种编程范式的高度哲学讨论. 不过,本文(和视频,见上文)不会参与这些讨论 - 相反,我们将深入探讨三种非常 ...
- 【Android开发】三种方法实现Button点击事件响应
目录 1.在xml中对onclick()进行指定方法 2.NEW一个OnClickListenner()接口实现 3.实现OnClickListener接口(Switch方法) Hello,你好呀,我 ...
- linux下dd做优盘启动_Linux中制作U盘启动盘的三种方法,使用启动盘创建器/dd命令和Etcher...
本文介绍在Linux系统中制作U盘启动盘的三种方法:使用启动盘创建器.dd命令和Etcher,以下以优麒麟Ubuntu Kylin 19.04为例,为你介绍这三种方法.如果要在Windows中制作U盘 ...
- JAVA输出数组元素的三种方法(for/for each/toString)
2022_02_19学习输出数组元素的三种方法以及c语言和java中数组的不同点 方法一:for循环输出数组元素 方法二:for each循环语句 方法三:Arrays类中的toString方法 c语 ...
最新文章
- 哪种营销方法效果最差_营销软文写作的三大技巧,你知道吗?
- 干货丨除了深度学习,你还应该了解这些发展方向
- 百度地图离线_“高德地图”和“百度地图”有什么差别? 专家: 细节决定成败!...
- 全球及中国斜交胎市场品牌竞争形势与投资策略分析报告2022年
- 学习 jQuery下拉框,单选框,多选框整理
- 计算机房安全等级标准,电子计算机房的分级标准
- C# 如何提取SaveFileDialog的保存路径?
- 过年用计算机弹奏,过年实用,你可能需要的亲戚称呼计算器
- Linux OpenSSH后门的添加与防范
- 1.1.3开启线程(Starting a Thread)
- mysql基础之数据库备份和恢复实操
- 385.迷你语法分析器
- CSS入门学习笔记+案例
- java redis学习记录
- 移动通信原理B-------课后作业2
- 用亿图软件怎么画数据模型图?
- DP 动态规划(一) ——背包问题 学习总结(闫氏DP分析法)
- 不得不看的黑客工具集
- 基于51单片机的音乐盒彩灯频谱喷泉原理图方案设计
- 路侧停车系统有利有弊