ADS1112 SLAVE ADDR 从机地址问题
我在总线上挂了三个ADS1112,A1,A0分别接的GND,GND;
VCC,NC;VCC,VCC;结果就只有地址0X90有反应,理论上地址应该分别为0X90,0X9A,0X9D,快帮忙吧,头都大了,谢谢
/*********************************************************************
* Filename: adc.c
* Revised: Date: 2012-08-05 19:50 (七)
* Revision: $
* Writer: $Wuming Shen.
*
* Description: ADS读写程序
*
* Notes:
* QQ:276193028
* E-mail:shenchangwei945@163.com
*
* All copyrights reserved to Wuming Shen.
*
*********************************************************************/
/*********************************************************************
* INCLUDES
*/
#include "Global.h"
#include "STC12C5A60S2.H"
#include "ADC.h"
#include "Uart.h"
/*********************************************************************
* CONSTANTS
*/
INT8U code ADS_ADDR[3] = { 0X90, 0X9A, 0X9C };
/*********************************************************************
* MACROS
*/
/*********************************************************************
* TYPEDEFS
*/
/*********************************************************************
* LOCAL VARIABLES
*/
sbit ADS_SDA = P0^0; /*I2C的ADS_SDA线定义*/
sbit ADS_SCL = P0^1; /*I2C的ADS_SCL线定义*/
//sbit ADS_SDA = P1^1; /*I2C的SDA线定义*/
//sbit ADS_SCL = P1^0; /*I2C的SCL线定义*/
//sbit ADS_A0 = P0^0;
//sbit ADS_A1 = P0^1;
/*********************************************************************
* GLOBAL VARIABLES
*/
/*********************************************************************
* LOCAL FUNCTIONS
*/
BOOL ADS_Config ( INT8U addr, INT8U cfg );
/*********************************************************************
* GLOBAL FUNCTIONS
*/
/*********************************************************************
* EXTERN VARIABLES
*/
/*********************************************************************
* EXTERN FUNCTIONS
*/
/*********************************************************************/
/*********************************************************************
* @fn &:main
* @brief &:First function called after startup.
* @return &:don't care
*********************************************************************/
/*********************************************************************
* 名 称:DDS_Init()
* 功 能:
* 入口参数:无
* 出口参数:无
* 作 者:无名沈
* 创建日期:2011-04-07
* 修 改:
* 修改日期:
*********************************************************************/
void ADS_Init( void )
{
/***********************************************
* 描述:配置转换精度为16位
* BIT 7 6 5 4 3 2 1 0
* NAME ST/DRDY INP1 INP0 SC DR1 DR0 PGA1 PGA0
* DEFAULT 1 0 0 0 1 1 0 0
*
* DR1 DR0 DATA RATE RESOLUTION
* 0 0 240SPS 12 Bits
* 0 1 60SPS 14 Bits
* 1 0 30SPS 15 Bits
* 1(1) 1(1) 15SPS(1) 16 Bits(1)
*/
#define ADS_ACC_12_BIT 0X80
#define ADS_ACC_14_BIT 0X84
#define ADS_ACC_15_BIT 0X88
#define ADS_ACC_16_BIT 0X8C
//ADS_A0 = 0;
//ADS_A1 = 1;
ADS_Config(ADS_ADDR[0], 0x8c); //0x84 14BOOL;0x8c 16BOOL;
ADS_Config(ADS_ADDR[1], 0x8c); //0x84 14BOOL;0x8c 16B
ADS_Config(ADS_ADDR[2], 0x8c); //0x84 14BOOL;0x8c 16BOOL;OOL;
}
/*********************************************************************
* 名 称:DDS_Init()
* 功 能:
* 入口参数:无
* 出口参数:无
*/
//发起始位
#define start() { ADS_SDA=1; \
ADS_SCL=1; \
ADS_SDA=0; \
ADS_SCL=0; \
}
//发停止位
#define stop() { ADS_SDA=0; \
ADS_SCL=1; \
ADS_SDA=1; \
ADS_SCL=0; \
}
//发应答位
#define mack() { ADS_SDA=0; \
ADS_SCL=1; \
ADS_SDA=0; \
ADS_SCL=0; \
}
//发非应答位
#define mnack() { ADS_SDA=0; \
ADS_SCL=1; \
ADS_SDA=0; \
ADS_SCL=0; \
}
//应答位测试
BOOL sack(void)
{
BOOL ack = 0;
INT8U timeOut = 20;
ADS_SDA = 1;
ADS_SCL = 1;
do {
ack = ADS_SDA;
} while (ack && --timeOut);
ADS_SCL = 0;
return (ack );
}
/*********************************************************************
* 名 称:ADSWriteByte()
* 功 能:发一字节数据
* 入口参数:无
* 出口参数:无
* 作 者:无名沈
* 创建日期:2011-04-07
* 修 改:
* 修改日期:
*********************************************************************/
void ADS_WriteByte(INT8U dat)
{
INT8U i;
for (i=0;i<8;i++) {
ADS_SDA = dat & 0X80; // 高发送低位
dat = dat << 1;
ADS_SCL = 1;
ADS_SCL = 0;
}
}
/*********************************************************************
* 名 称:ADSReadByte()
* 功 能:收一字节数据
* 入口参数:无
* 出口参数:无
* 作 者:无名沈
* 创建日期:2011-04-07
* 修 改:
* 修改日期:
*********************************************************************/
INT8U ADS_ReadByte(void)
{
INT8U dat,i;
dat = 0;
// ADS_SCL = 0;
for (i=0;i<8;i++) {
ADS_SDA = 1;
ADS_SCL = 1;
dat |= (INT8U)ADS_SDA; // 先收低位
dat <<= 1;
ADS_SCL = 0;
}
return (dat);
}
/*********************************************************************
* 名 称:ADCReadData()
* 功 能:读取AD转换值
* 入口参数:无
* 出口参数:无
* 作 者:无名沈
* 创建日期:2011-04-07
* 修 改:
* 修改日期:
*********************************************************************/
INT16S ADS_ReadData( INT8U addr, INT8U ch, INT8S times )
{
//INT8U addr;
INT8U dataH; // AD高8位
INT8U dataL; // AD低8位
INT8U cfgReg;
float result = 0.0;
INT8S cnt = 0;
INT8U timeOut = 20;
bit cpu_sr;
/***********************************************
* 描述:
*/
//addr = addr;//ADS_ADDR[ch/2];
//ch = 0;//ch%2;
UART_Printf(0,"Waddr:0x%X ch:%d\r\n",(INT16U)addr,(INT16U)ch);
/***********************************************
* 描述:
*/
if ( !ADS_Config( addr, 0x0C | ( ch << 5 ) ) ) { //0B10001100
UART_Printf(0,"Config Err\r\n");
return FALSE;
}
addr += 1;
UART_Printf(0,"Raddr:0x%X ch:%d\r\n",(INT16U)addr,(INT16U)ch);
/***********************************************
* 描述:
*/
do {
timeOut = 10;
again:
cpu_sr = EA; // 保存当前中断使能状态
EA = 0; // 关闭中断
/***********************************************
* 描述:开始读
*/
start(); // 发起始位
ADS_WriteByte( addr ); // ED0的读地址
if ( sack() ) {
EA = cpu_sr; // 恢复中断状态
return FALSE;
}
/***********************************************
* 描述:读取数据
*/
dataH = ADS_ReadByte();
mack(); // 发应答位
dataL = ADS_ReadByte();
mack(); // 发应答位
cfgReg = ADS_ReadByte();
mnack(); // 发非应答位
stop(); // 发送停止位
UART_Printf(0,"H:0x%x L:0x%x R:0x%x\r\n",(INT16U)dataH,(INT16U)dataL,(INT16U)cfgReg);
EA = cpu_sr; // 恢复中断状态
/***********************************************
* 描述:
*/
if ( cfgReg & 0X80 ) { // 判断是否有新的AD采样值,最高位为1表示无新值
if ( --timeOut <= 0 )
return 0xffff;
OSTimeDly(OS_TICKS_PER_SEC/15); // 16位精度为15次每秒
goto again; // 重新读取
}
result += (float)( ( (INT16S)dataH << 8 ) + dataL );
} while ( ++cnt < times );
/***********************************************
* 描述:
*/
if ( times > 0 )
result /= times;
return ( INT16S )result;
}
/*********************************************************************
* 名 称:ADS_Config()
* 功 能:设置ADS1100
* 入口参数:无
* 出口参数:无
* 作 者:无名沈
* 创建日期:2011-04-07
* 修 改:
* 修改日期:
*********************************************************************/
BOOL ADS_Config( INT8U addr, INT8U cfg )
{
bit cpu_sr = EA;
EA = 0; // 关闭中断
//addr = ADS_ADDR[addr];
start(); /*发起始位*/
ADS_WriteByte( addr );
if ( sack() ) {
stop();
EA = cpu_sr; // 恢复中断状态
return FALSE;
}
ADS_WriteByte( cfg );
if ( sack() ) {
stop();
EA = cpu_sr; // 恢复中断状态
return FALSE;
}
stop();
EA = cpu_sr; // 恢复中断状态
return TRUE;
}
/*********************************************************************
* end of file
*********************************************************************/
建议你用示波器确认一下I2C的时序,可以参照datasheet: www.ti.com/.../getliterature.tsp 第十二页Figure 2/3.
Waddr:0X90 ch:0
Raddr:0X91 ch:0
H:0X0C L:0XC9 R:0X0C
ch=0,code:0X0CC9,vol=0.204563
Waddr:0X90 ch:1
Raddr:0X91 ch:1
H:0X0C L:0XC5 R:0X2C
ch=1,code:0X0CC5,vol=0.204313
Waddr:0X90 ch:0
Raddr:0X91 ch:0
H:0X0C L:0XCA R:0X4C
ch=0,code:0X0CCA,vol=0.204625
Waddr:0X90 ch:0
Raddr:0X91 ch:0
H:0X0C L:0XC8 R:0X6C
ch=0,code:0X0CC8,vol=0.204500
这是地址0x90,0x91读出来的值,实际上我的A1,A0接的是VCC,其他的两个设备我把SDA去掉了,SCL仍然连接,读出来的值跟万用表测试的是一致的,但是,只能读出通道0的值,其他通道的读不出来,地址也不对,但是也可以读
还有就是,AIN1和AIN3接到一起与被电压的地连接,AIN0和AIN2做为输入端,这样接有没有问题?会不会有影响?
1. 从手册上看,地址应该是7位,为什么你的应用里冒出来0x90,0x9A,0x9D这样的8位地址?
2. “还有就是,AIN1和AIN3接到一起与被电压的地连接,” -- “被电压”指哪个电压?“被电压的地”指哪个地?
Analog Input Voltage模拟输入电压的范围是GND-0.2V到VDD+0.2V. 故AIN1和AIN3可以到连接到GND, 只是满刻度范围减半。
在网上找了一下,很多人都遇到过地址和通道的问题,好像都没有人解决,不知道这个是不是ADS1112本身的问题还是我们的方法不对,如果说时序不对,那么应该读不出数据来了,更不可能数据是对的(通道0,其他通道值与通道0一相同),我觉得,如果ADS的所有功能服操作确实如手册上所说,而大家又都 有这样的问题,那官方就有义务给一个测试程序,让我们这些为之迷芒的人摆脱迷芒
0X90,是写,0x91,是读
1,7位左移一位,再加一个读写信号不就是8位吗?
2,被测电压有两个路,为共地信号,一路为接AIN0和AIN1,另一路接AIN2,AIN3,AIN1和AIN3短接;
备注:
读写字节的程序稍微做了修改,之前的是有一点点问题,只是改了以后读出来的值准确了,但是之前的那些现象还是依然存在,
修改后读写程序
#define start() { ADS_SDA=1; \
ADS_SCL=1; \
ADS_SDA=0; \
ADS_SCL=0; \
}
//发停止位
#define stop() { ADS_SDA=0; \
ADS_SCL=1; \
ADS_SDA=1; \
ADS_SCL=0; \
}
//发应答位
#define mack() { ADS_SDA=0; \
ADS_SCL=1; \
ADS_SCL=0; \
ADS_SDA=1; \
}
//发非应答位
#define mnack() { ADS_SDA=1; \
ADS_SCL=1; \
ADS_SDA=0; \
ADS_SCL=0; \
}
//应答位测试
BOOL sack(void)
{
BOOL ack = 0;
INT8U timeOut = 20;
ADS_SDA = 1;
ADS_SCL = 1;
do {
ack = ADS_SDA;
} while (ack && --timeOut);
ADS_SCL = 0;
return (ack );
}
/*********************************************************************
* 名 称:ADSWriteByte()
* 功 能:发一字节数据
* 入口参数:无
* 出口参数:无
* 作 者:无名沈
* 创建日期:2011-04-07
* 修 改:
* 修改日期:
*********************************************************************/
void ADS_WriteByte(INT8U dat)
{
INT8U i;
for (i=0;i<8;i++) {
ADS_SDA = dat & 0X80; // 高发送高位
dat = _crol_(dat, 1);
ADS_SCL = 1;
ADS_SCL = 0;
}
}
/*********************************************************************
* 名 称:ADSReadByte()
* 功 能:收一字节数据
* 入口参数:无
* 出口参数:无
* 作 者:无名沈
* 创建日期:2011-04-07
* 修 改:
* 修改日期:
*********************************************************************/
INT8U ADS_ReadByte(void)
{
INT8U dat,i;
dat = 0;
for (i=0;i<8;i++) {
ADS_SDA = 1;
ADS_SCL = 1;
dat |= ADS_SDA; // 先收高位
dat = _crol_(dat, 1); // 循环左移1位
ADS_SCL = 0;
}
dat = _cror_(dat, 1); // 多移一位再反过来移一位
return (dat);
}
1. 模拟部分,从手册上看,测差分信号时,AIN0和AIN1可接受一路,AIN2和AIN3可接受一路,但是为什么要把AIN1和AIN3短接?你到底是要测差分信号还是要测单端信号?建议如果是检查软件程序,那可以先只开AIN0一路,把一个固定电压,如1/2 Vref,加到AIN0上,其他3路不接信号,这样,先把软件方面的问题排除,再回来考虑模拟方面的问题。
2. 软件部分看看是不是高低位的收发顺序搞错了。从手册上看,应该先收高位。
我觉得ADS1112的手册是有问题的,有自相矛盾的地方
1:表4(P10)中有A1:Float,A0:Float, SLAVE ADDRESS:Invalid
2:图4(P12)Typical Connection of the ADS1112中又是将A1,A0悬空的,那么从机地址是多少呢?
图4应该只是个示意图,为了说明问题的方便,没有把A1和A0做具体连接。还是建议你循序渐进地定位问题,
1. 先试单通道,单地址
2. 再试双/多通道,单地址。
3. 单通道,多地址。
可能这样做有助于你定位问题究竟出现在哪里。
数据部分我都用示波器看过了,是正确的,如果 不正确,就不可能会有一个地址,和一个通道读出来的值是正确的,而且我以前用过这个芯片,好像以前也遇到过一个问题,有些芯片可以读出通道012的值,且是不同的,有些芯片三个通道的值是一样的,因为我的前端有继电器切换,后来就没去管这个问题了,但是现在没有继电器切换,所以就没办法了
我把其他两个设备已经隔离,AIN2我也没有接地了,已经割断,这样应该就只是0,1,2对3的电压了吧?输入输入部分应该也没有问题,通信只有0X90/写,0X91/读是有响应的,就说明A1,和A0接VCC的从机地址是0X1001000,如果还要查问题的话,我估计就是把输入全去掉,然后再把与SCL连接的其他两个设备也割掉了
测试数据:
Waddr:0X90 ch:0 // 写地址
Raddr:0X91 ch:0 // 读地址
H:0X32 L:0XB1 R:0X0C
ch=0,code:0X32B1,vol=0.811063
Waddr:0X90 ch:1
Raddr:0X91 ch:1
H:0X32 L:0XB1 R:0X2C // 三个寄存器值,H数据高8位,L数据低8位,R配置寄存器
ch=1,code:0X32B1,vol=0.811063
Waddr:0X90 ch:2
Raddr:0X91 ch:2
H:0X32 L:0XB0 R:0X4C
ch=2,code:0X32B0,vol=0.811000
Waddr:0X90 ch:3
Raddr:0X91 ch:3
H:0X32 L:0XB0 R:0X6C
ch=3,code:0X32B0,vol=0.811000
Waddr:0X90 ch:0
Raddr:0X91 ch:0
H:0X6B L:0X6E R:0X0C
ch=0,code:0X6B6E,vol=1.718875
Waddr:0X90 ch:1
Raddr:0X91 ch:1
H:0X6B L:0X6B R:0X2C
ch=1,code:0X6B6B,vol=1.718688
Waddr:0X90 ch:2
Raddr:0X91 ch:2
H:0X6B L:0X6B R:0X4C
ch=2,code:0X6B6B,vol=1.718688
Waddr:0X90 ch:3
Raddr:0X91 ch:3
H:0X6B L:0X6A R:0X6C
ch=3,code:0X6B6A,vol=1.718625
Waddr:0X90 ch:0
Raddr:0X91 ch:0
H:0X7D L:0X2A R:0X0C
ch=0,code:0X7D2A,vol=2.002625
Waddr:0X90 ch:1
Raddr:0X91 ch:1
H:0X7D L:0X28 R:0X2C
ch=1,code:0X7D28,vol=2.002500
Waddr:0X90 ch:2
Raddr:0X91 ch:2
H:0X7D L:0X28 R:0X4C
ch=2,code:0X7D28,vol=2.002500
Waddr:0X90 ch:3
Raddr:0X91 ch:3
H:0X7D L:0X28 R:0X6C
ch=3,code:0X7D28,vol=2.002500
Waddr:0X90 ch:0
Raddr:0X91 ch:0
H:0XFF L:0XC2 R:0X0C
ch=0,code:0XFFC2,vol=-0.003875
Waddr:0X90 ch:1
Raddr:0X91 ch:1
H:0XFF L:0XBD R:0X2C
ch=1,code:0XFFBD,vol=-0.004188
Waddr:0X90 ch:2
Raddr:0X91 ch:2
H:0XFF L:0XBB R:0X4C
ch=2,code:0XFFBB,vol=-0.004313
Waddr:0X90 ch:3
Raddr:0X91 ch:3
H:0XFF L:0XBA R:0X6C
ch=3,code:0XFFBA,vol=-0.004375
我现在只要能切换通道就心满意足了,从机地址我倒再想办法,多用两个SDA就行了,关键是通道切换也没用
TI的高级工程师位,帮帮我吧!
我把A1,A0悬空后,发10010000/10010001才能正确的读写,任何地址也只有这个能读写,读出来的数据是准确的,改变通道,读出来的通道是一一对应的,但值永远都只是通道0的
我也还加长了SCL的延时,结果还是一样,这让我想起了ADS1110,结果跟ADS1110的手册很吻合。
1. 你测试的时候,AIN0,AIN1,AIN2加的都是什么电压?AIN3加的是多少伏的共模?要是3个输入加同样电压,那读出来的数据当然应该是一样的啊。
2. 你的芯片来源?从哪里买来的?从手册上看A1,A0悬空是非法态啊,不应该用90/91读写啊。
我也遇到了同样的问题,不管怎么配置寄存器,始终只能得到第一通道的数据,而且其他通道的值与第一通道的值相同
问题已解决,不是程序问题也不是电路问题,当然也不是我的人品问题,是芯片的质量问题
问题芯片:
1、字符为:BHU 085C;
2、商家为:深圳广腾电子;
3、阿里旺旺为:秋生电子;
4、链接:store.taobao.com/.../view_shop.htm
此商家的芯片比别人的要贵好多,当初只以为他的东西比较全才买的,其实是被欺骗了,发货速度也慢,前天拍的,第二天还打电话我要什么东西,请朋友们以后多注意,此商家的态度不好,有问题找他就借口:他的东西都是原装进口,不予退货!
我后来又换了了个商家
1、芯片字符为:BHU 73Z3
2、商家为:楠兴电子
3、旺旺号:850423608qq
4、链接:shop69008624.taobao.com/.../search.htm
此商家承诺若与手册功能不符,全额退货
TI芯片购买建议找TI授权代理商(质量有保障), 设计阶段可以直接在TI网站上申请免费样片:www.ti.com.cn/.../homepage.tsp