搜索
bottom↓
回复: 5

那位大侠用过ADS1100啊?请指教一下啊

[复制链接]

出0入0汤圆

发表于 2010-4-13 11:09:40 | 显示全部楼层 |阅读模式
我手头的芯片应该是标记为AD1 iic地址为1001001X
读出来数据是FF,ack_check()函数应该是没有应答。
代码如下:

#include<reg52.h>
#include <intrins.h>
#include <absacc.h>
#include<stdio.h>

#define uchar unsigned char
#define uint unsigned int
#define  _Nop()  _nop_()       /*定义空指令,约1个微秒*/

sbit AP14=P1^4;
sbit BP15=P1^5;
sbit CP16=P1^6;
sbit DP17=P1^7;          //选通CD4067
sfr  WDT_CONTR=0xE1;

sbit EN=P3^7;

sbit SDA=P1^3;          /*I2C的SDA线定义*/
sbit SCL=P1^2;         /*I2C的SCL线定义*/ //ADS1100
/**********变量定义*****************/
uchar ACK;
uchar adc_h;     
uchar adc_l,adc_cfg;   
uint adc;  
uint adc_data;

/*************ad模块子程序*****************************/
void ads_start(void); //开始
void ads_stop(void); //停止
uchar ack_check(void); //应答
void ads_sendBYTE(uchar send_data);// 发送一个字节  
uchar ads_reciveBYTE(void); //接受一个字节  
void send_ack(void);  //发送应答信号
void send_nack(void); //发送非应答信号
void write_ads(uchar snd_data); //写器件地址和配置字。
uint read_ads(void);        //从ADS1100中读出数据,返回 adc=(adc_h<<8)+adc_l;



   /*****************ads1100模块区*******************************************************/
/*****************************************************/               
/*    函数原型: void ads_start (void)               */   
/*    功    能: 提供I2C总线工作时序中的起始位。      */      
/*****************************************************/           
void ads_start (void) //在SCL高的情况下,SDA由高到低的变化造成START。     
  {   
    SDA=1;   
    _nop_();  
_nop_();     
    SCL=1;   
    _nop_();   
    _nop_();   
    _nop_();
    _nop_();   
    _nop_();   
    _nop_();
    SDA=0;   
    _nop_();   
    _nop_();   
    _nop_();  
    _nop_();   
    _nop_();   
    _nop_();   
    SCL=0;   
    _nop_();   
    _nop_();   
    _nop_();   
    _nop_();   
  }   
/**********************************************************/   
/*    函数原型: void ads_stop(void)                       */   
/*    功    能: 提供I2C总线工作时序中的停止位。           */   
/**********************************************************/   
void ads_stop(void) //在SCL高的情况下,SDA由低到高的变化造成STOP。     
  {   
   
    SDA=0;   
    _nop_();  
_nop_();   
    SCL=1;   
    _nop_();   
    _nop_();   
    _nop_();  
    _nop_();   
    _nop_();   
    _nop_();     
    SDA=1;   
    _nop_();   
    _nop_();   
    _nop_();  
    _nop_();   
    _nop_();   
    _nop_();   
    SCL=0;   
    _nop_();   
    _nop_();   
    _nop_();   
    _nop_();   
  }
/*****************************************************************************/   
/*    函数原型: uchar ack_check(void)                                        */   
/*    功    能: 提供I2C总线的时钟信号, 并返回在时钟电平为高期间SDA 信号线上状*/   
/*              态。本函数可用于数据发送, 也可用于数据接收。                  */   
/*****************************************************************************/   
uchar ack_check(void) // 检查 从机 应答信号 SDA为低电平为应答   
  {  
    //SCL=0;   
    SCL=1;   
    _nop_();
    _nop_();      
    if(SDA) ACK = 1;  
    else  ACK = 0;
    SCL=0;   
    return(ACK);  // 如果收到ACK应答则返回0, 否则返回1。           
  }   
/*******************************************************/   
/*    函数原型: void ads_sendBYTE(uch data)            */   
/*    功    能: 向I2C总线发送8位数据。                 */   
/*******************************************************/   
void ads_sendBYTE(uchar send_data) // 发送一个字节     
{   
uchar bitcount=8;         // 发送8位数据。     
do   
{
if((send_data&0x80)==0x80)SDA=1;   //写 1        
else SDA=0; //写 0     
SCL=0;         //在时钟大于4u秒期间写数据     
SCL=1;   
_nop_();   
_nop_();   
_nop_();   
_nop_();   
_nop_();
_nop_();   
_nop_();   
_nop_();   
_nop_();   
_nop_();   
SCL=0;   
send_data=send_data<<1;       //   待送数据左移一位.     
bitcount--;   
}while(bitcount);//等待数据写完
SDA=1;        //释放总线等待应答
_nop_();   
_nop_();   
_nop_();   
_nop_();   
_nop_();
    _nop_();   
_nop_();   
_nop_();   
_nop_();   
_nop_();
}  
/***************************************************************************/   
/*    函数原型: ads_reciveBYTE(void)                                       */   
/*    功    能: 从I2C总线上接收8位数据信号, 并将接收到8位数据作为一个字节  */   
/*              返回, 不回送应答信号ACK。主函数在调用本函数之前应保证SDA信 */   
/*              号线处于浮置状态, 即使8052的Px.x脚置1。                  */   
/***************************************************************************/   
uchar ads_reciveBYTE(void) //接受一个字节     
{   
uchar in_data=0;   
    uchar bitcount1=8;   
    do   
    {   
SCL=0; //在时钟大于4u秒期间读数据     
        SCL=1;   
  _nop_();   
_nop_();   
_nop_();   
_nop_();   
_nop_();
_nop_();   
_nop_();   
_nop_();   
_nop_();   
_nop_();
        if(SDA) in_data=in_data|0x01; //读 1     
        else in_data=in_data&0xfe; //读 0      
        SCL=0;     
        if(bitcount1-1) in_data=in_data<<1;   
bitcount1--;   
    }while(bitcount1);  
    return(in_data);   
}  
/****************************************************************************/   
/*    函数原型: void  send_Ack(void);                                      */   
/*    功    能: 向I2C总线发送一个应答信号ACK, 用于连续数据读取时。          */   
/****************************************************************************/   
void send_ack(void) // 发送连续读信号    主机应答信号  
  {   
    SDA=0;   //低电平应答
    SCL=0;   
    SCL=1;   
    _nop_();   
    _nop_();   
    _nop_();   
    _nop_();   
    _nop_();
    _nop_();   
    _nop_();   
    _nop_();   
    _nop_();   
    _nop_();
    SCL=0;   
  }     
void send_nack(void) // 发送不连续读信号   非应答信号  
  {   
    SDA=1;   //高电平非应答
    SCL=0;   
    SCL=1;   
    _nop_();   
    _nop_();   
    _nop_();   
    _nop_();   
    _nop_();   
_nop_();   
    _nop_();   
    _nop_();   
    _nop_();   
    _nop_();   
    SCL=0;   
  }   
/*********************************************************/   
/*    函数原型: void write_ads(uchar snd_data)           */   
/*    功    能: 写器件地址和配置字。                     */   
/*********************************************************/   
void write_ads(uchar snd_data)  //写器件地址和配置字     
  {   
  uchar i;     
  i=40;
    ads_start();            //开始写     
    ads_sendBYTE(0x92);     //写器件地址(写) 1001(固定) 001(器件编号) 0(写)
    do   
    {
     
                 i--;
        if(i==0)break;  ;
    }while(ack_check());     //等待应答     
    ads_sendBYTE(snd_data);     //写配置字
        i=40;   
    do   
    {        i--;
        if(i==0)break;   
     ;
    }while(ack_check());    //等待应答     
    ads_stop();             //结束写     
  }
/******************************************************/   
/*    函数原型: read_ads(void)                        */   
/*    功    能: 数据读取。                            */   
/******************************************************/   
uint read_ads(void)          //从ADS1100中读出数据     
  {   
  uchar i;     
  i=40;
    ads_start();             //开始读     
    ads_sendBYTE(0x93);      //写器件地址(读)    1001(固定) 001(器件编号) 1(读)
    do   
    {
        i--;
        if(i==0)break;   
     ;   
    }while(ack_check());     //等待应答
    adc_h = ads_reciveBYTE(); //读高8位     
    send_ack();                 //连续读     
    adc_l = ads_reciveBYTE();   //读低8位     
    send_ack();                 //连续读     
  adc_cfg = ads_reciveBYTE(); //读配置字     
    send_nack(); //发送不连续读信号
    ads_stop();                 //结束读     
adc=(adc_h<<8)+adc_l;
return adc;
  }  
/**********************************************************************************************/




/****************************************************************************************
功能:初始化串口
说明:波特2400  8 个数据位,一个停止位,一个起始位,无奇偶校验
      使用定时器1,SMOD=0;晶振11.0592
*****************************************************************************************/
void init_seril()
{

SCON = 0x50 ;      //SCON: serail mode 1, 8-bit UART, enable ucvr  
TMOD = 0x20 ;     //TMOD: timer 1, mode 2, 8-bit reload  
PCON = 0x00 ;    //SMOD=0;  
TH1 = 0xF4 ;     //Baud:2400 fosc=11.0592MHz
TL1 = 0xF4;
TR1 = 1 ;       // timer 1 run  */
}
/******************************************************************************************
功能:串口发送函数

*******************************************************************************************/
void sendbyte1 (unsigned char a)
{   
     TI=0;
//         EN=1;
         SBUF=a;
         while(TI==0);
         TI=0;
         //EN=0;
       
}

static Init_time0(void)
{
EA=0;
TR0=0;
TMOD&=0xF0;    //定时器工作于方式1
TMOD|=0x01;
TL0=0x00;
TH0=0x4C;      //定时器的初始值50MS
PT0=0;
ET0=1;
TR0=1;         //起动定时器
EA=1;
}
/*********************************************************************************************************
功能:延时函数,延时1ms

***********************************************************************************************************/
void delay(uint t)
{
        uint i;
        while(t--)
        {
                /* 对于11。0592M时钟,约延时1ms */
                for (i=0;i<120;i++)
                {}
        }
}
void main()
{

AP14=1;
BP15=1;
CP16=1;
DP17=1;
EN=1;
init_seril();
SDA=1;
SCL=1;
//write_ads(0x8C);//写配置字 转换速率8sps,16位  1倍增益,连续转换

while(1)
{
sendbyte1(0xAA);
//WDT_CONTR=0x35;
adc_data=read_ads();//读取ad转换值


sendbyte1(adc_h);
sendbyte1(adc_l);
   sendbyte1(adc_cfg);
delay(30);
}
}

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

 楼主| 发表于 2010-4-13 16:10:33 | 显示全部楼层
没人指点一下吗?

出0入0汤圆

发表于 2010-4-13 19:40:02 | 显示全部楼层
我用过ADS1110.标的是ED4,实际是ED1,你看下是否是一样的原因

出0入0汤圆

发表于 2010-4-13 21:35:44 | 显示全部楼层
file NAME:ads1110.c
HEAD file:ads1110.h  delay.h
说明:
chip:MEGA16L
编译器:CodeVisionAVR C Compiler
在ADS1100测试通过
i2c程序包包括:
             void     io_dir(uCHAR dir);
             void     ADS1100_start(void);                                       i2c start
             void     ADS1100_stop(void);                                        i2c stop
             uCHAR    ackby_ADS1100(void);                                       ADS1100应答
             void     ackby_master(void);                                        主机应答
             void     send_frame(uCHAR framedata);                               send 8bit to ADS1100
             uCHAR    read_frame(void);                                          read bbit from
其他函数为ADS1100用
其中引脚定义在ads1110.h定义,请更改引脚
编写日期:2006.04.27
作    者:吴青松
注:只供学习,不能商用
*/
#include <ads1110.h>     //
#include <delay.h>       //延时函数用,此为CodeVisionAVR C Compiler自带,其他编译器中的延时                         //则需要自己编写
/*====================================================================================
函数功能:改变I/O数据线的方向
如果是其他类型单片机,此处需要更改
======================================================================================*/
void     io_dir(uCHAR dir)
{                 
   out_data=1;
   if(dir==IN)
   {
      io_data=0;  
   }
   if(dir==OUT)
   {
      io_data=1;  
   }
}
/*
////////////////////////////////////////////////////////////////////////////////////////////
函数功能:I2C起动,注意起动前,保证scl=1,data=1,data =>out(i/o输出)
A start condition is when the clock LINE is HIGH and the data LINE goes from HIGH to LOW.
当时钟线为高电平时,数据线从1->0,形成一个开始条件
编写日期:2006.04.27
作    者:吴青松
////////////////////////////////////////////////////////////////////////////////////////////
*/
void     ADS1100_start(void)
{  
//inital:scl=1,data=1,data =>out
//data LINE putout      get bus
   
out_data=0;     //=0
delay_us(5);
scl=0;         //insure scl=0
delay_us(5);

//finally :scl=0,data=0,data =>out
}
/*
////////////////////////////////////////////////////////////////////////////////////////////
函数功能:I2C停止
A stop condition is when the clock LINE is HIGH and the data LINE goes from LOW to HIGH.
当时钟线为高电平时,数据线从0->1,形成一个开始条件
编写日期:2006.04.27
作    者:吴青松
////////////////////////////////////////////////////////////////////////////////////////////
*/
void     ADS1100_stop(void)
{            
  //initial:scl=0 data no confire
   
  //data LINE putout  get bus :data=0 =>out
  io_dir(OUT);
  delay_us(10);
  out_data=0;
  delay_us(10);
        
  // scl=1 data=0=>data=1
  scl=1;
  delay_us(10);     
  out_data=1;
  delay_us(10);  
  //finallay:scl=1,data=1,data =>out
}
/*
////////////////////////////////////////////////////////////////////////////////////////////函数功能:i2c从器件(ADS1100) 应答
参数说明:当i2c器件响应 返回1,否则返回0
编写日期:2006.04.27
作    者:吴青松
////////////////////////////////////////////////////////////////////////////////////////////
*/
uCHAR    ackby_ADS1100(void)
{                        
unsigned CHAR times=0;
//start:scl=0 data=>out
//give up bus     setup data in     

io_dir(IN);     
delay_us(5);  //wait for ADS1100 ready data           

//wait ADS1100 ack
scl=1;  
while((in_data==1)&&(times<100))           //wait for ads ack   data=0
{
    times++;
}

scl=0;                  //ready for next
delay_us(5);                             
//fianlly:scl=0;data <in     
if(times>90)
{
    return 0;
}           
else
{
    return 1;
}
}
/*
////////////////////////////////////////////////////////////////////////////////////////////
函数功能:主机应答
编写日期:2006.04.27
作    者:吴青松
////////////////////////////////////////////////////////////////////////////////////////////
*/   
void     ackby_master(voi

出0入0汤圆

发表于 2010-4-13 22:04:19 | 显示全部楼层
没时间看哈,用过,蛮好用的,当初数据很跳,后来是发现数字地和模拟地没隔离开,加磁珠隔离后效果还不错

也是网上程序,和楼主的应该是一样的。不过我用的是24M晶掁


/*****************ads1100模块区*******************************************************/
/***************************************************/
/*                ads1100初始化,写入配置字                  */       
/***************************************************/
void init_ads1100(void)
{
        SDA=1;
        Nop();
        Nop();
        SCL=1;
        Nop();
        Nop();
        write_ads(0x8C);//写配置字        转换速率8sps,16位  1倍增益,连续转换  (复位默认值)
//        write_ads(0x93);//转换速率128sps,12位, 8倍增益,单次转换,一次AD转换完后自动掉电
}
/*****************************************************/              
/*    函数原型: void ads_start (void)                      */   
/*    功    能: 提供I2C总线工作时序中的起始位。      */     
/*****************************************************/         
void ads_start (void) //在SCL高的情况下,SDA由高到低的变化造成START。   
  {   
    SDA=1;   
    _nop_();
        _nop_();   
    SCL=1;   
    _nop_();   
    _nop_();   
    _nop_();
    _nop_();   
    _nop_();   
    _nop_();
    SDA=0;   
    _nop_();   
    _nop_();   
    _nop_();
    _nop_();   
    _nop_();   
    _nop_();  
    SCL=0;   
    _nop_();   
    _nop_();  
    _nop_();   
    _nop_();  
  }   
/**********************************************************/   
/*    函数原型: void ads_stop(void)                       */   
/*    功    能: 提供I2C总线工作时序中的停止位。           */   
/**********************************************************/   
void ads_stop(void) //在SCL高的情况下,SDA由低到高的变化造成STOP。   
  {   
   
    SDA=0;   
    _nop_();
        _nop_();   
    SCL=1;   
    _nop_();   
    _nop_();   
    _nop_();
    _nop_();   
    _nop_();   
    _nop_();   
    SDA=1;   
    _nop_();   
    _nop_();   
    _nop_();
    _nop_();   
    _nop_();   
    _nop_();   
    SCL=0;   
    _nop_();   
    _nop_();  
    _nop_();   
    _nop_();  
  }
/*****************************************************************************/   
/*    函数原型: uchar ack_check(void)                                        */   
/*    功    能: 提供I2C总线的时钟信号, 并返回在时钟电平为高期间SDA 信号线上状*/   
/*              态。本函数可用于数据发送, 也可用于数据接收。                  */   
/*****************************************************************************/   
uchar ack_check(void) // 从机 应答信号 SDA为低电平为应答   
  {
    SCL=0;   
    SCL=1;   
    _nop_();
    _nop_();     
    if(SDA) ACK = 1;
    else  ACK = 0;
    SCL=0;   
    return(ACK);  // 如果收到ACK应答则返回0, 否则返回1。         
  }   
/*******************************************************/   
/*    函数原型: void ads_sendBYTE(uch data)            */   
/*    功    能: 向I2C总线发送8位数据。                 */   
/*******************************************************/   
void ads_sendBYTE(uchar send_data) // 发送一个字节   
{   
        uchar bitcount=8;         // 发送8位数据。   
        do   
        {
                if((send_data&0x80)==0x80)SDA=1;   //写 1      
                else SDA=0; //写 0   
                SCL=0;         //在时钟大于4u秒期间写数据   
                SCL=1;   
                _nop_();   //稳定数据
                _nop_();   
                _nop_();   
                _nop_();   
                _nop_();
                _nop_();   
                _nop_();   
                _nop_();          
                _nop_();   
                _nop_();  
                SCL=0;   
                send_data=send_data<<1;       //   待送数据左移一位.   
                bitcount--;   
        }while(bitcount);//等待数据写完
        SDA=1;        //释放总线等待应答
        _nop_();   
        _nop_();   
        _nop_();   
        _nop_();   
        _nop_();
           _nop_();   
        _nop_();   
        _nop_();   
        _nop_();   
        _nop_();
}
/***************************************************************************/   
/*    函数原型: ads_reciveBYTE(void)                                       */   
/*    功    能: 从I2C总线上接收8位数据信号, 并将接收到8位数据作为一个字节  */   
/*              返回, 不回送应答信号ACK。主函数在调用本函数之前应保证SDA信 */   
/*              号线处于浮置状态, 即使8052的Px.x脚置1。                  */   
/***************************************************************************/   
uchar ads_reciveBYTE(void) //接受一个字节   
{   
        uchar in_data=0;   
    uchar bitcount1=8;  
        SDA=1;
    do   
    {  
                SCL=0; //在时钟大于4u秒期间读数据   
        SCL=1;   
                _nop_();   
                _nop_();   
                _nop_();   
                _nop_();   
                _nop_();
                _nop_();   
                _nop_();   
                _nop_();          
                _nop_();   
                _nop_();
        if(SDA) in_data=in_data|0x01; //读 1   
        else in_data=in_data&0xfe; //读 0      
        SCL=0;   
        if(bitcount1-1) in_data=in_data<<1;   
                bitcount1--;   
    }while(bitcount1);
    return(in_data);   
}
/****************************************************************************/   
/*    函数原型: void  send_Ack(void);                                      */   
/*    功    能: 向I2C总线发送一个应答信号ACK, 用于连续数据读取时。          */   
/****************************************************************************/   
void send_ack(void) // 发送连续读信号    主机应答信号
  {   
    SDA=0;   //低电平应答
    SCL=0;   
    SCL=1;   
    _nop_();   
    _nop_();   
    _nop_();   
    _nop_();   
    _nop_();
    _nop_();   
    _nop_();   
    _nop_();   
    _nop_();   
    _nop_();
    SCL=0;   
  }   
void send_nack(void) // 发送不连续读信号   非应答信号
  {   
    SDA=1;   //高电平非应答
    SCL=0;   
    SCL=1;   
    _nop_();   
    _nop_();   
    _nop_();   
    _nop_();   
    _nop_();  
        _nop_();   
    _nop_();   
    _nop_();   
    _nop_();   
    _nop_();  
    SCL=0;   
  }   
/*********************************************************/   
/*    函数原型: void write_ads(uchar snd_data)           */   
/*    功    能: 写器件地址和配置字。                     */   
/*********************************************************/   
void write_ads(uchar snd_data)  //写器件地址和配置字   
  {   
    ads_start();            //开始写   
    ads_sendBYTE(0x90);     //写器件地址(写) 1001(固定) 000(器件编号) 0(写)
    do   
    {
     ;
    }while(ack_check());            //等待应答   
    ads_sendBYTE(snd_data);     //写配置字   
    do  
    {
     ;
    }while(ack_check());    //等待应答   
    ads_stop();             //结束写   
  }
/******************************************************/   
/*    函数原型: read_ads(void)                        */   
/*    功    能: 数据读取。                            */   
/******************************************************/   
uint read_ads(void)                         //从ADS1100中读出数据   
  {  

    ads_start();                            //开始读   
    ads_sendBYTE(0x91);                     //写器件地址(读)    1001(固定) 000(器件编号) 1(读)
    do   
    {   
     ;   
    }while(ack_check());            //等待应答
    adc_h = ads_reciveBYTE();        //读高8位
    send_ack();                 //连续读
        adc_l = ads_reciveBYTE();   //读低8位   
    send_ack();                 //连续读
        adc_cfg = ads_reciveBYTE(); //读配置字   
    send_nack();                                //发送不连续读信号
    ads_stop();                 //结束读   
        adc=adc_h;
        adc=(adc<<8)+adc_l;
        return adc;
  }
/**********************************************************************************************/

出0入0汤圆

发表于 2013-3-7 14:47:20 | 显示全部楼层
标记,参考下
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-23 18:26

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表