打印

IIC问题

[复制链接]
1639|4
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
dfsa|  楼主 | 2014-2-25 19:09 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
请教个问题,现在手头上有个板子,主控是PIC18F6520,有一支持IIC协议的ADS1115,模拟量转换芯片。现在想通过ADS1115来测量模拟电压,采用PIC内部硬件IIC与AD芯片通信,问题是ADS1115没有应答信号,也没收到数据?板子上IIC从器件一共有三个,ADS1115,24C08,pcf8563,这三个器件是接在同一IIC口上的,但是器件地址不同,PIC同24C08通信,发数据,24C08有应答,可就是ADS1115也没有应答。AD芯片是好事的,因为AD芯片在51开发板上用IO口模拟IIC时,能成功与其通信并读出测量值,到了PIC板子上就不能通信了。
   给器件不论发送地址数据还是其他数据,芯片 都没有应答信号,仿真就能看到,程序死在等待应答上了。
   各位大侠看看,程序到底出了什么问题了,都调试了好几天了,一点进展都没有。。。
   




以下是ADS1115.h同文件


/*
* ADS1115.h
*
*  Created on: 2012-7-30
*      Author: Piao
*/
#ifndef ADS1115_H_
#define ADS1115_H_

/**********ADDR宏定义***************/
#define ADDRESS_0  0x90   //ADDR PIN ->GND
#define ADDRESS_1  0x92   //ADDR PIN ->VDD
#define ADDRESS_2  0x94   //ADDR PIN ->SDA
#define ADDRESS_3  0x96   //ADDR PIN ->SCL


/************POINTER REGISTER*****************/
#define Pointer_0  0x00   //Convertion register
#define Pointer_1  0x01   //Config register
#define Pointer_2  0x02   //Lo_thresh register
#define Pointer_3  0x03   //Hi_thresh register

/************CONFIG REGISTER*****************/
#define OS_0   0x0000
#define OS_1   0x8000

#define MUX_0  0x0000  //AINp=AIN0, AINn=AIN1
#define MUX_1  0x1000  //AINp=AIN0, AINn=AIN3
#define MUX_2  0x2000  //AINp=AIN1, AINn=AIN3
#define MUX_3  0x3000  //AINp=AIN2, AINn=AIN3
#define MUX_4  0x4000  //AINp=AIN0, AINn=GND
#define MUX_5  0x5000  //AINp=AIN1, AINn=GND
#define MUX_6  0x6000  //AINp=AIN2, AINn=GND
#define MUX_7  0x7000  //AINp=AIN3, AINn=GND

#define PGA_0  0x0000   //FS=6.144V
#define PGA_1  0x0200   //FS=4.096V
#define PGA_2  0x0400  //FS=2.048V
#define PGA_3  0x0600  //FS=1.024V
#define PGA_4  0x0800  //FS=0.512V
#define PGA_5  0x0A00  //FS=0.256V
#define PGA_6  0x0C00  //FS=0.256V
#define PGA_7  0x0E00  //FS=0.256V

#define MODE_0 0x0000
#define MODE_1 0x0100

#define DR_0   0x0000   //Data Rate = 8
#define DR_1   0x0020   //Data Rate = 16
#define DR_2   0x0040   //Data Rate = 32
#define DR_3   0x0060   //Data Rate = 64
#define DR_4   0x0080   //Data Rate = 128
#define DR_5   0x00A0   //Data Rate = 250
#define DR_6   0x00C0   //Data Rate = 475
#define DR_7   0x00E0   //Data Rate = 860

#define COMP_MODE_0  0x0000
#define COMP_MODE_1  0x0010

#define COMP_POL_0   0x0000
#define COMP_POL_1   0x0008

#define COMP_LAT_0   0x0000
#define COMP_LAT_1   0x0040

#define COMP_QUE_0   0x0000
#define COMP_QUE_1   0x0001
#define COMP_QUE_2   0x0002
#define COMP_QUE_3   0x0003

#endif
/* ADS1115_H_ */



#include <pic18.h>
#include <pic18fxx20.h>
#include <math.h>
#include <ADS1115.h>
/********************************引脚分配*******************/
//---lcd控制线
#define std RA4        // 串行数据端口
#define cs RA5 // lcd片选
#define sclk RC1        // 写数据时钟
#define LEDK RB3        //液晶背光控制

#define SCL RC3
#define SDA RC4        

//---ADS1115
#define ADDRESS    ADDRESS_0   //ADDR PIN ->GND
#define ADDRESS_W  ADDRESS|0x00  //写地址
#define ADDRESS_R  ADDRESS|0x01    //读地址
/*************Config Initial*********************/
#define OS         OS_1
#define MUX_A0     MUX_4      //AINp=AIN0, AINn=GND
#define MUX_A1     MUX_5      //AINp=AIN1, AINn=GND
#define MUX_A2     MUX_6      //AINp=AIN2, AINn=GND
#define MUX_A3     MUX_7      //AINp=AIN3, AINn=GND
#define PGA        PGA_0      //FS=6.144V
#define MODE       MODE_1     //Continuous conversion mode
#define DR         DR_7       //Data Rate = 860
#define COMP_QUE   COMP_QUE_3


void ADS1115Init(unsigned int mux);
unsigned int ADS1115Read(void);
/***********************************自定义变量********************/

#define uint  unsigned int
#define uchar unsigned char
//----液晶相关
#define x1    0x80
#define x2    0x88
#define y     0x80
#define comm  0
#define dat   1
uchar LcdRam[4][17];//LCD缓冲区4行*16字节
uchar datachar[10];//液晶数值数据缓冲区---999999999.9
uchar timebuff[6];//时间缓冲区---10:10

uchar date_lcd[16];//日期"2013-05-05"
uchar time_lcd[16];//时间,周"05:05:05 4"
uchar di_lcd[16];//DI"DI=10101010"
uchar do_lcd[16];//Do"Do=10101010"
uchar ai_lcd[4][16];//AI"AI1=XXXXX"

void delay(unsigned int i);//延时
void intdelay(unsigned int i);//中断延时
void low_intdelay(unsigned int i);
//-----中断函数
void interrupt  _int_ (void);//中断处理函数
void interrupt low_priority LOW_ISR(void);

/******************子函数定义*******************************/
void ADS1115Init(unsigned int MUX)
{
        unsigned int Config;
        Config=0x0000;
        Config = OS+MUX+PGA+MODE+DR+COMP_QUE;
        SEN=1;//产生启动信号
        delay(100);
        do{;}while(SSPIF==0);
        SSPIF=0;
        
        SSPBUF=ADDRESS_W;//从地址
        do{;}while(ACKSTAT==1);//应答信号
        do{;}while(SSPIF==0);
            SSPIF=0;
   
            SSPBUF=Pointer_1;//寄存器地址
        do{;}while(ACKSTAT==1);//应答信号
        do{;}while(SSPIF==0);
            SSPIF=0;

        SSPBUF=Config/256;
        do{;}while(ACKSTAT==1);//应答信号
        do{;}while(SSPIF==0);
            SSPIF=0;
        while(BF);
        
        SSPBUF=Config%256;
        do{;}while(ACKSTAT==1);//应答信号
        do{;}while(SSPIF==0);
            SSPIF=0;
        while(BF);
        
            PEN=1;//产生停止信号
            do{;}while(SSPIF==0);
        SSPIF=0;
        delay(100);
}
unsigned int ADS1115Read(void)
{
        unsigned int result;

        SEN=1;//产生启动信号
            //delay(100);
        do{;}while(SSPIF==0);
        SSPIF=0;
        
        SSPBUF=ADDRESS_W;//从地址
        do{;}while(SSPIF==0);
            SSPIF=0;
   
            SSPBUF=Pointer_0;//寄存器地址(伪写操作)
            do{;}while(SSPIF==0);
        SSPIF=0;
        
        RSEN=1;//重启        
    do{;}while(SSPIF==0);
        SSPIF=0;
        
        SSPBUF=ADDRESS_R;//从地址
        do{;}while(SSPIF==0);
            SSPIF=0;
            
        RCEN=1;//接受使能
            do{;}while(SSPIF==0);
            SSPIF=0;
            while(BF==0);
        result=SSPBUF*256;
        ACKDT=0;//应答0   
            ACKEN=1;
        do{;}while(SSPIF==0);
            SSPIF=0;
        
        RCEN=1;//接受使能
            do{;}while(SSPIF==0);
            SSPIF=0;
            while(BF==0);
        result+=SSPBUF;
        ACKDT=1;//应答1   
            ACKEN=1;
        do{;}while(SSPIF==0);
            SSPIF=0;

        PEN=1;//产生停止信号
            do{;}while(SSPIF==0);
        SSPIF=0;
   
        return result;

}
void wr_lcd (uchar dat_comm,uchar content)//LCD写命令
{
  uchar a,i,j;
  delay (50);
  a=content;
  cs=1;
  sclk=0;
  std=1;
  for(i=0;i<5;i++)//5个1
  {
    sclk=1;
    sclk=0;
  }
  std=0;//rw=0写
  sclk=1;
  sclk=0;
  if(dat_comm)
    std=1;   //rs=1 data
  else
    std=0;   //rs=0 command
  sclk=1;
  sclk=0;
  std=0;//插入0
  sclk=1;
  sclk=0;
  for(j=0;j<2;j++)
  {
    for(i=0;i<4;i++)
    {
      if((a&0x80)==0x00)
      {
      std=0;
      }
      else
      {
          std=1;
      }
      
      sclk=1;
      sclk=0;
      a=a<<1;
    }
    std=0;
    for(i=0;i<4;i++)
    {
      sclk=1;
      sclk=0;
    }
  }
}
void updatelcd(uchar line,uchar row,uchar count,uchar *p)//Lcd按行、列、字节数更新
{
        //line0-3;row0-7;
        uchar add,i;
        if(line>3 || row>7) return;
        if(line==0) add=0x80;
        if(line==1) add=0x90;
        if(line==2) add=0x88;
        if(line==3) add=0x98;
        wr_lcd(comm,0x30);
        wr_lcd(comm,add+row);
        for(i=0;i<count;i++)
        {
                wr_lcd(dat,p[i]);
               
        }
}
void init_lcd()//lcd初始化
{
  wr_lcd (comm,0x30);  /*30---基本指令动作*/   
  wr_lcd (comm,0x01);  /*清屏,地址指针指向00H*/
  delay (400);
  wr_lcd (comm,0x06);  /*光标的移动方向*/
  wr_lcd (comm,0x0c);  /*开显示,关游标*/
}

void init_mcu()//单片机初始化
{
//输入输出方向控制
        TRISA=0x00;//00000000(RA4=RA5=0)
        TRISB=0x04;//00000100(RB3=0 RB2=1)
        TRISC=0x80;//10000000(RC0=0 RC1=0)
        TRISD=0x00;//00000000(RD0-RD7=0)
        TRISE=0x1c;//00011100(RE5=0 RE4-RE2=1)
        TRISF=0xff;//11111111(RF0-RF7=1)
        TRISG=0x04;//00000100
//输出引脚初始化
        //RA没有初始化;
        RB3=0;//背光关闭
        RC0=0;//关闭蜂鸣器
        RC6=0;
        PORTD=0xff;//关闭输出
        RE5=1;//关闭键盘
        //RF没有初始化
        //RG没有初始化

//中断优先级
        IPEN=1;//开中断优先级
        RBIP=0;//RB口中断优先级
        TMR1IP=0;//定时器1中断优先级
        RC1IP=1;//串口1接收中断优先级
        RC2IP=1;//串口2接收中断优先级
//中断使能
        INT0IE=0;//IN0中断使能位
        INT1IE=0;//IN1中断使能位
        INT2IE=0;//IN2中断使能位
        INT3IE=0;//IN3中断使能位
        RBIE=1;//RB端口电平变化中断使能位
        INTEDG0=0;//IN0中断触发方式
//定时器1
        TMR1H=0X25;//tmr1始终循环启动,为其他定时器的基数,500ms
        TMR1L=0XC3;
        T1CON=0B00110100;//1:8预分频,内部时钟源
        TMR1ON=1;//启动
        TMR1IE=1;//开TMR1中断
//开启所有中断
        GIE=1;        
        PEIE=1;
}
void init_i2c(void)//初始化IIC总线
{
        SSPCON1=0x28;//主控模式,时钟=Focs/(4*(SSPADD+1))
        SSPSTAT=0x80;//标准模式;不需要更新地址;
            SSPADD=0x02;//设置时钟
        SSPCON2=0x00;
        SSPEN=1;//总线使能
        SSPIE=0;//禁止进入中断
}
void lcd_disall(void)//lcd全部显示
{
        uchar i;
        wr_lcd (comm,0x30);
        wr_lcd (comm,0x80);
        for(i=0;i<16;i++)
        {
                wr_lcd(dat,LcdRam[0][i]);
        }
        wr_lcd (comm,0x90);
        for(i=0;i<16;i++)
        {
                wr_lcd(dat,LcdRam[1][i]);
        }
        wr_lcd (comm,0x88);
        for(i=0;i<16;i++)
        {
                wr_lcd(dat,LcdRam[2][i]);
        }
        wr_lcd (comm,0x98);
        for(i=0;i<16;i++)
        {
                wr_lcd(dat,LcdRam[3][i]);
        }
        
}
//主函数定义
void main(void)
{
        char i=0,j=0;
        unsigned int tmpresult;
        //器件初始化
        init_mcu();//初始化单片机
        init_232();//初始化串口
        init_i2c();//初始化IIC总线
        init_lcd();//初始化液晶
        
        LEDK=1;//打开背光电源
        //初始界面显示公司产品信息
        updatelcd(1,0,16,QidongzhongCode);//启动信息
        //图片清零
        
        
        while(1)
        {
                ADS1115Init(MUX_A0);
                //i2c_24c08_write(0x00,password,6);
                //delay(0x800);
                delay(400);
               
        }

}

相关帖子

沙发
火箭球迷| | 2014-2-25 19:18 | 只看该作者
没用过PIC I2C。建议

1 用示例程序改写编自己的程序
2 用示波器/逻辑分析仪 检查通讯信号

使用特权

评论回复
板凳
baidudz| | 2014-2-25 19:26 | 只看该作者
I2C上拉电阻用了多少的?建议你先去掉其它两个芯片,单独把ADC调通再接其它芯片,有时候可能是容抗和带载能力的问题。

使用特权

评论回复
地板
pkat| | 2014-2-25 19:32 | 只看该作者
如果是波形不好,可能连线阻抗/容抗偏大。简单点可以先降低通讯速率来调试,以后做了PCB再恢复高速通讯

使用特权

评论回复
5
love_321| | 2014-9-9 17:33 | 只看该作者
请问这个问题是怎么解决的

使用特权

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

本版积分规则

282

主题

2404

帖子

2

粉丝