我在总线上挂了三个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
*********************************************************************/
Johnsin Tao:
建议你用示波器确认一下I2C的时序,可以参照datasheet: www.ti.com/…/getliterature.tsp 第十二页Figure 2/3.
shen changwei:
回复 Johnsin Tao:
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的值,其他通道的读不出来,地址也不对,但是也可以读
shen changwei:
回复 shen changwei:
还有就是,AIN1和AIN3接到一起与被电压的地连接,AIN0和AIN2做为输入端,这样接有没有问题?会不会有影响?
Decapton Wang:
回复 shen changwei:
1. 从手册上看,地址应该是7位,为什么你的应用里冒出来0x90,0x9A,0x9D这样的8位地址?
2. “还有就是,AIN1和AIN3接到一起与被电压的地连接,” — “被电压”指哪个电压?“被电压的地”指哪个地?
Johnsin Tao:
回复 Decapton Wang:
Analog Input Voltage模拟输入电压的范围是GND-0.2V到VDD+0.2V. 故AIN1和AIN3可以到连接到GND, 只是满刻度范围减半。
shen changwei:
在网上找了一下,很多人都遇到过地址和通道的问题,好像都没有人解决,不知道这个是不是ADS1112本身的问题还是我们的方法不对,如果说时序不对,那么应该读不出数据来了,更不可能数据是对的(通道0,其他通道值与通道0一相同),我觉得,如果ADS的所有功能服操作确实如手册上所说,而大家又都 有这样的问题,那官方就有义务给一个测试程序,让我们这些为之迷芒的人摆脱迷芒
shen changwei:
回复 Decapton Wang:
0X90,是写,0x91,是读
shen changwei:
回复 Decapton Wang:
1,7位左移一位,再加一个读写信号不就是8位吗?
2,被测电压有两个路,为共地信号,一路为接AIN0和AIN1,另一路接AIN2,AIN3,AIN1和AIN3短接;
备注:
读写字节的程序稍微做了修改,之前的是有一点点问题,只是改了以后读出来的值准确了,但是之前的那些现象还是依然存在,
shen changwei:
回复 shen changwei:
修改后读写程序
#define start(){ADS_SDA=1;\
ADS_SCL=1; \
ADS_SDA=0;\
ADS_SCL=0; \
}
//发停止位
#definestop(){ADS_SDA=0;\
ADS_SCL=1; \
ADS_SDA=1;\
ADS_SCL=0; \
}
//发应答位
#definemack() {ADS_SDA=0;\
ADS_SCL=1; \
ADS_SCL=0; \
ADS_SDA=1;\
}
//发非应答位
#definemnack() {ADS_SDA=1;\
ADS_SCL=1; \
ADS_SDA=0;\
ADS_SCL=0; \
}
//应答位测试
BOOL sack(void)
{
BOOLack= 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)
{
INT8Udat,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);
}
Decapton Wang:
回复 shen changwei:
1. 模拟部分,从手册上看,测差分信号时,AIN0和AIN1可接受一路,AIN2和AIN3可接受一路,但是为什么要把AIN1和AIN3短接?你到底是要测差分信号还是要测单端信号?建议如果是检查软件程序,那可以先只开AIN0一路,把一个固定电压,如1/2 Vref,加到AIN0上,其他3路不接信号,这样,先把软件方面的问题排除,再回来考虑模拟方面的问题。
2. 软件部分看看是不是高低位的收发顺序搞错了。从手册上看,应该先收高位。