This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

ADS1112 SLAVE ADDR 从机地址问题

Other Parts Discussed in Thread: ADS1112, ADS1100, ADS1110

我在总线上挂了三个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