zhuyi2576 发表于 2009-6-3 17:17:00

请大家帮我看看ADS1100程序哪里错了?!

老得不到数据
出来的都是乱码

我是按网上给的程序写的
//24M晶掁
#include <reg2051.H>
#include <INTRINS.H>
#define                uchar        unsigned        char
#define                uint        unsigned        int       
#define                ulong        unsigned        long
#define                true        1
#define                false        0
#define                dis_null        0x11//数码管全灭段码   17
#define                dis_full        0x12//数码管全亮段码        18
#define                null                0x00//数据缺省状态为零
#define         Nop()                _nop_()

/*********ADS1100引脚定义**************/
sbit SDA = P1^0;
sbit SCL = P1^1;//加了上拉电阻1K

/**********变量定义*****************/
uchar ACK;
uchar adc_h;   
uchar adc_l;
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;
//void dis_adc();

/************主程序********************/
void main()
{
//        delayms(500);
        init_mcu();
        SDA=1;
        SCL=1;
        write_ads(0x8C);//写配置字        转换速率8sps,16位1倍增益,连续转换
//        write_ads(0x93);//转换速率128sps,12位, 8倍增益,单次转换,一次AD转换完后自动掉电
        while(1)
        {       
                adc_data=read_ads();//读取ad转换值

                dis_buf=adc_l<<4;/*这一段只是我的显示程序,没全贴上来,我只是看看转换后的16位数是多少
                dis_buf=adc_l>>4;
                dis_buf=adc_h<<4;
                dis_buf=adc_h>>4;
                display_some(0,4);
        }
}

/*****************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;
    elseACK = 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);   
}
/****************************************************************************/   
/*    函数原型: voidsend_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中读出数据   
{
        uchar adc_cfg;   
    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<<8)+adc_l;
        return adc;
}
/**********************************************************************************************/

jishanlaike 发表于 2009-6-3 17:37:52

if((send_data&0x80)==0x80)SDA=1;   //写 1      
                else SDA=0; //写 0   
                SCL=0;         //在时钟大于4u秒期间写数据   
                SCL=1;   

这里不对吧,应该是scl=0时改变sda,你这里怎么先改变sda,再scl啊

iic关键的一点scl==0时改变sda

tangqianqian 发表于 2009-6-3 17:46:19

没用过,但帮你顶下.

zhuyi2576 发表于 2009-6-4 09:33:39

知道错在哪了
我的显示写错了,应该是
                dis_buf=adc_l&0x0f
                dis_buf=adc_l>>4;
                dis_buf=adc_h&0x0f;
                dis_buf=adc_h>>4;
郁闷,害我调了一天,时序看了好遍。

awing 发表于 2010-5-19 13:53:36

zhuyi2576老兄留个qq好吗,请教一下,谢谢

w492901074 发表于 2013-3-7 14:44:42

标记,正在调试ADS1100
页: [1]
查看完整版本: 请大家帮我看看ADS1100程序哪里错了?!