注册 登录
电子工程世界-论坛 返回首页 EEWORLD首页 频道 EE大学堂 下载中心 Datasheet 专题
lq_automatic的个人空间 https://home.eeworld.com.cn/space-uid-319070.html [收藏] [复制] [分享] [RSS]
日志

PIC 硬件IIC通信,从器件应答问题

已有 888 次阅读2014-1-8 23:10

    请教个问题,现在手头上有个板子,主控是PIC18F6520,有一支持IIC协议的ADS1115,模拟量转换芯片。现在想通过ADS1115来测量模拟电压,采用PIC内部硬件IIC与AD芯片通信,问题是ADS1115没有应答信号,也没收到数据?板子上IIC从器件一共有三个,ADS1115,24C08,pcf8563,这三个器件是接在同一IIC口上的,但是器件地址不同,PIC同24C08通信,发数据,24C08有应答,可就是ADS1115也没有应答。AD芯片是好事的,因为AD芯片在51开发板上用IO口模拟IIC时,能成功与其通信并读出测量值,到了PIC板子上就不能通信了。
   各位大侠看看,程序到底出了什么问题了,都调试了好几天了,一点进展都没有。。。
   
#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);
               
        }
}

/*--------------清DDRAM------------------*/
void clrram (void)
{
        int i,j;
          wr_lcd (comm,0x30);
          wr_lcd (comm,0x01);
          delay (180);
          for(i=0;i<4;i++)
          for(j=0;j<17;j++) LcdRam[j]=0x20;
}

void condisp(int LineNum,char ColNum,char width,uchar data)//行反白控制,row起始行,col起始列,width列宽
{
        uchar rowadd=0, coladd=0;
        uchar i,j;
        if(LineNum>3) return;
        if(ColNum+width>8) return;
        if((LineNum==0) || (LineNum==2)) coladd=0x80;
        if((LineNum==1) || (LineNum==3)) coladd=0x90;
        if(LineNum>1)
        {
                rowadd=0x88+ColNum;
        }
        else
        {
                rowadd=0x80+ColNum;
        }
        for(j=0;j<16;j++)
        {
                for(i=0;i<width;i++)
                {
                        wr_lcd(comm,0x34);
                        wr_lcd(comm,coladd+j);
                        wr_lcd(comm,rowadd+i);
                        wr_lcd(comm,0x30);
                        wr_lcd(dat,data);
                        wr_lcd(dat,data);
                }
        }
        wr_lcd(comm,0x36);
}
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没有初始化
//模拟量直接采集设置       
        ADCON0=0x01;//模拟量输入控制:通道编号=0;ADON=1;GODONE=0;
        ADCON1=0x0f;//模拟量输入端口控制:AN0-AN9,VRef+=AVDD,VRef-=AVSS;
        ADCON2=0x81;//模拟量输入控制:Right justified,Fosc/8
        ADIF=0;//模拟量采集标志位
        ADIP=0;//模拟量采集优先级
//从动并口       
        PSPMODE=0;//与从动并口相关
//比较器
        CVREN=0;//关比较器
        CVROE=0;
        CMCON=0x07;

        RBPU=0;//开RB端口上拉

//中断优先级
        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]);
        }
        wr_lcd (comm,0x90);
        for(i=0;i<16;i++)
        {
                wr_lcd(dat,LcdRam[1]);
        }
        wr_lcd (comm,0x88);
        for(i=0;i<16;i++)
        {
                wr_lcd(dat,LcdRam[2]);
        }
        wr_lcd (comm,0x98);
        for(i=0;i<16;i++)
        {
                wr_lcd(dat,LcdRam[3]);
        }
       
}
//主函数定义
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);
               
        }

}


以下是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_ */

本文来自论坛,点击查看完整帖子内容。

评论 (0 个评论)

facelist doodle 涂鸦板

您需要登录后才可以评论 登录 | 注册