打印

PIC18F4620与ADS1110的通信问题

[复制链接]
4378|5
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
FXCH499062451|  楼主 | 2011-1-18 14:35 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
我用4620与ADS1110来作数据采集,我的程序如下,但是调了一个多月了,各种原因都找遍了,AD就是不工作,实在找不到原因了,求大神来指点一下小弟,不胜感激啊!
另外硬件应该没问题。

#include <pic18.h>
#include<stdio.h>
#include<math.h>
//AD端口声明
#define ADS1110_SCL  RC3  
#define ADS1110_SDA  RC4
#define REF_CE RA5
bank1 char dd1,dd2;  // 宏变量
//bank1 float Realdata;
//bank1 int i;
//bank1 int ad_i,ad_j;
//bank1 int max;
//bank1 float max_sum;
bank1 float xishu;
bank1  int result;
bank1 unsigned char TIME_COUNTER=0;
bank1 unsigned char first=1;
bank1 int real_ad_zero;
bank1 int real_ad_result_temp[8];
bank1 unsigned char caiji_counter;
bank1 float real_ad_result_sum;
bank1 int real_ad_result;
bank1 int real_ad_result_init;
unsigned char a,b,c,d;
//bank1 unsigned int ads1110_result;
//bank1 unsigned char d1,d2;
void TIMER1_Interrupt(void);
void  CPU_Interrupt(void);
//AD转换过程中用到的函数的声明
void ads1110_ack(void);  //发送连续读信号
void ads1110_nack(void);  //发送不连续读信号
void ads1110_start(void);   //开始
void ads1110_stop(void);  //结束
unsigned char ads1110_check(void);   //检查应答信号
void ads1110_send(unsigned char data);   //发送一个字节
unsigned char ads1110_recive(void);   //接受一个字节
void ads1110_wr(unsigned char conf);   //写期间地址和配置字
int ads1110_rd(void);   //从ADS1110中读取转换结果
void deal_int_date(unsigned int dat,unsigned char *a,unsigned char *b,unsigned char *c,unsigned char *d);
void SCI_Init(void); //串口初始化
void SCI_Send_Char(char Send_Data);  //串口发送函数
void delay(unsigned int num);

void delay(unsigned int num)
    {
while(num--) ;  
    }
//AD控制函数引用

void ads1110_ack(void)//发送连续读信号
{
TRISC3=0;
TRISC4=0;
    ADS1110_SDA=0;
    asm("nop");
    asm("nop");
    asm("nop");
    asm("nop");
    ADS1110_SCL=1;   
    asm("nop");
    asm("nop");
    asm("nop");
    asm("nop");
    ADS1110_SCL=0;
}
void ads1110_nack(void)//发送不连续读信号
{
TRISC3=0;
TRISC4=0;
    ADS1110_SDA=1;
    asm("nop");
    asm("nop");
    asm("nop");
    asm("nop");
    ADS1110_SCL=1;   
    asm("nop");
    asm("nop");
    asm("nop");
    asm("nop");
    ADS1110_SCL=0;
}
void ads1110_start(void)//开始
{
    TRISC3=0;
    TRISC4=0;
    ADS1110_SDA=1;
    ADS1110_SCL=1;
    asm("nop");
    asm("nop");
    ADS1110_SDA=0;
    asm("nop");
    asm("nop");
    ADS1110_SCL=0;
}
void ads1110_stop(void)//结束
{
    TRISC3=0;
    TRISC4=0;
       ADS1110_SDA=0;
       asm("nop");
    asm("nop");
    ADS1110_SCL=0;                // -----------结束I2C总线,即发送I2C结束条件.
    asm("nop");
    asm("nop");
    ADS1110_SCL=1;
    ADS1110_SDA=1;   
}
unsigned char ads1110_check(void)//检查应答信号
{
    unsigned char ACK;
    unsigned char errtime;
    errtime=40;
    TRISC3=0;
    TRISC4=0;
    ADS1110_SDA=1;
while(ADS1110_SDA)                //-----------等待ADS1100应答
    {
        errtime--;
        if(!errtime)
        {      
            ads1110_stop();
            ACK=1;
            return(ACK);
        }
    }
    ADS1110_SCL=1;
    asm("nop");
    asm("nop");  
    asm("nop");
    asm("nop");
    ADS1110_SCL=0;
    ACK=0;
    return(ACK);
}
void ads1110_send(unsigned char sendData)//发送一个字节
{
    unsigned char bitcount;
    TRISC3=0;
    TRISC4=0;//置输出
    ADS1110_SCL=0;//在时钟大于4us期间写数据
    for(bitcount=0;bitcount<8;bitcount++)
    {
        if(sendData & 0x80) ADS1110_SDA=1;
        else ADS1110_SDA=0;   
        asm("nop");   
        asm("nop");
        sendData<<=1;
        ADS1110_SCL=1;             //置时钟线为高,通知被控器开始接收数据位
        asm("nop");   
        asm("nop");  
        ADS1110_SCL=0;
    }
    TRISC4=1;//释放总线等待应答
   // return;
}
unsigned char ads1110_recive(void)//接受一个字节
{
    unsigned char data;
    unsigned char bitcount;
    TRISC3=0;
    TRISC4=1;//置输入
    for(bitcount=0;bitcount<8;bitcount++)
    {
        ADS1110_SCL=1;
        asm("nop");
        asm("nop");
        data=data<<1;
        ADS1110_SDA=1;
        if(ADS1110_SDA)
            data=data|0x01;
        else
            data=data&0xfe;
        ADS1110_SCL=0;
        asm("nop");
        asm("nop");
    }
    return(data);
}
void ads1110_wr(unsigned char conf)//写期间地址和配置字
{
  
        ads1110_start();
        ads1110_send(0x94);
  do
    {;}
    while(ads1110_check());//等待应答
ads1110_send(conf);//写配置字
do{;}while(ads1110_check());//等待应答
    ads1110_stop();
}
int ads1110_rd(void)     //从ADS1110中读取转换结果
{
int ads1110_result;
   // unsigned char d1,d2;
unsigned char conf;
    float temp;
         ads1110_start();
         ads1110_send(0x95);
       do
     {;}
     while(ads1110_check());//等待应答
        ads1110_result=256*ads1110_recive();
  ads1110_ack();
  ads1110_result+=ads1110_recive();
  ads1110_ack();
  conf=ads1110_recive();
  ads1110_nack();
  ads1110_stop();
        temp=(float)ads1110_result;
       // temp+=11.0;
// temp/=1.0292222222222222222222222222222;
    temp/=2.0;
temp*=xishu;

    ads1110_result=(int)temp;

    return( ads1110_result);  //正常采集到数据
}

void deal_int_date(unsigned int dat,unsigned char *a,unsigned char *b,unsigned char *c,unsigned char *d)
{
dat%=10000;
*a= dat/1000;
*b=(dat%1000)/100;
*c=(dat%100)/10;
*d= dat%10;
return;
}
void SCI_Init(void)
/************************************************************************/
/* 函数功能:串口发送模块初始化                                         */
/* 形参说明:无                                                         */
/* 返回值  :无                                                         */
/************************************************************************/
{
    SYNC=0;        //异步模式
    BRGH=1;        //高速波特率模式
    BRG16=0;  
    SPBRGH=0x00;   //设置波特率产生器,产生9600波特率
    SPBRG=0x33;    //设置波特率产生器,产生9600波特率
    SPEN=1;        //串行端口使能,将TX、RX配置为串行线
    TXEN=0;        //串行发送使能--NO
    //TX9=1;
    //TX9D=1;
}

void SCI_Send_Char(char Data)
/************************************************************************/
/* 函数功能:串口数据发送函数                                           */
/* 形参说明:要发送的字符型数据                                         */
/* 返回值  :无                                                         */
/************************************************************************/
{
    TRISA4=0;
    RA4=1;
    while(TRMT==0){};        //查询发送缓冲器寄存器是否为空
      
    TXREG=Data;       //当发送缓冲器寄存器为空后,将待发送的数据写入发送缓冲器寄存器
    TXEN=1;
    asm("nop");            //空指令,配合时序
     while(!TRMT);        //查询发送缓冲器寄存器是否为空
    RA4=0;
    TXEN=0;
}

void TIMER1_Interrupt(void)
{
    TMR1L=0x8e;
    TMR1H=0x0d;
    TMR1IF=0;  //中断标志清零
    ads1110_wr(0x9C);
      REF_CE=1;
         result=ads1110_rd();

if(result<0)
    {
    SCI_Send_Char('-');
    result=-result;
    }
else
   {
    SCI_Send_Char('+');
   }
    deal_int_date(result,&a,&b,&c,&d);
SCI_Send_Char(a+0x30);  // 二进制转为十进制
SCI_Send_Char(b+0x30);
SCI_Send_Char(c+0x30);
SCI_Send_Char(d+0x30);   

    SCI_Send_Char('1'); // 测试串口
    SCI_Send_Char('2');
}
   
void CPU_Interrupt(void)
{
    if(TMR1IF==1)       //定时器1中断
        TIMER1_Interrupt();
}

void main()
{
  OSCCON=0x78; //8MHz主频
    TRISA4=0;
    RA4=1;
    TRISA5=0;
    RA5=1;
    TRISE0=0;
    TRISE1=0;
    TRISE2=0;
    RE2=0;
    TRISC6=1;
    TRISC7=1;
//
T1CON=0x30;
    TMR1H=0xff;
    TMR1L=0xf0;
    PEIE=0;TMR1IF=0;TMR1IE=1;TMR1ON=1;  
//  SSPEN=0;
//
    SCI_Init();
    xishu=2.0;
   
while(1)
{
     ads1110_wr(0x9C);
     REF_CE=1;
     CPU_Interrupt();
     delay(40000);
    }
}
沙发
yewuyi| | 2011-1-19 08:46 | 只看该作者
从你给出的代码看,ADS1110应该是个IIC接口的AD芯片,关于IIC的通信,你可以到网络上去下载ADS1110的DEMO代码。

使用特权

评论回复
板凳
张逸飞521| | 2011-3-13 18:29 | 只看该作者
可以百度一下

使用特权

评论回复
地板
兰天白云| | 2011-3-14 17:11 | 只看该作者
这么长的代码确实没精力看,但可以给你几个建议
1:仔细看看ASD1110芯片,这应该是16位的AD芯片,IIC接口,特别注意时序
2:如果可以建议你用ADS1230,SPI接口,代码容易写,也可用硬件(很多单片机自带)
3:心不要太急,一段一段调试
4:实在不行,自己画个流程图,一目了然,查问题很快
5:AD芯片自身电路设计是否有错???

使用特权

评论回复
5
zhjun| | 2011-6-29 22:11 | 只看该作者
1# FXCH499062451 我用AVR编过,确实ADS1110的时序要求比较严,另外还没有中断输出,分辨力也不高,现在改用别的AD了

使用特权

评论回复
6
wdm| | 2011-6-30 08:11 | 只看该作者
ADS1110我七八年前用过,当时是用PIC16F877的汇编写的,芯片本身的问题应该是没有的

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

0

主题

2

帖子

1

粉丝