This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

ADS1115的配置

Other Parts Discussed in Thread: ADS1115

请问一下大家:

1、ADS1115的Config Register 在什么时候配置比较好,因为我需要采集双通道AD

2、写入的时候是不是要先写ADDR,然后Pointer Reg指向Config Reg,然后配置Config Reg,再ADDR,再Conversion Reg

      读取的时候是不是只要先写ADDR,然后Pointer Reg指向Conversion Reg,再ADDR,然后输出的是Data

不知道我这样的理解对不对,还请大家帮忙指正,谢谢!

  • 可以参考数据手册 QUICKSTART GUIDE

  • 数据手册第11页介绍的很详细的,可以看看。另外Config Register在初始化配置,然后需要切换通道的时候需要重新配置

  • 您好!我现在遇到了另外一个问题,单个通道采集没有问题,但是两个通道交替采集时,出来的数据是一样的,请问一下怎么解决,谢谢!

  • 有可能是你没有切换到另外一个通道上去吧?

  •  我用单个通道都能正常工作,就是两个通道一起交替进行,就出问题了

  • 您好!请问一下对于切换通道,是不是只要在AD写入时改变配置寄存器的值,主要是MUX的值是么?烦请解答,谢谢!

  • 是的,如果有PGA值需要改变也一起改变。配置后请等待一下在开始转换,因为它需要一个startup time

  • 如果是one shot模式,MUX改变后下一次转换就是新的通道的数据;如果是连续转换模式,MUX 改变不改变当前的转换状态,当这一次转换完成后才切换到下一个通道开始转换。所以MUX切换后的第2租数据才是新通道的有效数据

  • 您好!我尝试按照您说的改了一下,可是结果还是一样,后面附带了我的代码,麻烦您抽空帮忙看一下,感激不尽!
    
    
    #include<avr/io.h>
    #include<stdio.h>
    #include <util/delay.h>
    #include<avr/interrupt.h>
    
    #define SS      2
    #define SCK     5
    #define MOSI    3
    #define DDR_SPI   DDRB                   
    #define PORT_SPI  PORTB
    
    #define SET_SCL DDRD&=~_BV(PD6)   //*****
    #define CLR_SCL DDRD|=_BV(PD6)
    #define SET_SDA DDRD&=~_BV(PD7)
    #define CLR_SDA DDRD|=_BV(PD7)
    #define SDA_PIN  (PIND&_BV(PD7))
    
    #define ADS1115_WRITE	0x90  // SDA地址寄存器(写)
    #define ADS1115_READ	0x91  // SDA地址寄存器(读)
    
    
    #define TwiWaitAck() while(SDA_PIN);
    
    void delay(void);
    void adc_init(void);
    void uart_init(void);
    void uart_send(unsigned char);
    void SPI_MasterInit(void);
    void SPI_MasterTransmit(unsigned char cData);
    unsigned char EEPROM_read(unsigned int uiAddress);
    void EEPROM_write(unsigned int uiAddress, unsigned char ucData);
    
    void twi_delay_bus(void);
    void twi_ack(unsigned char ack);
    void TwiInit(void);
    unsigned char TwiStart(void);
    void TwiStop(void);
    unsigned char TwiWriteByte(unsigned char c);
    unsigned char TwiReadByte(unsigned char ack);
    void write_ads1115(unsigned char configreg);
    void ads1115_read_adc_val(int k);
    void ads1115_start_convert(unsigned char configreg);
    
    volatile unsigned char StartFlag;
    volatile unsigned char RecvIndex;
    volatile unsigned char DacFlag;
    unsigned char ADCResult[10][2];
    unsigned char RecvData[5];
    SIGNAL(SIG_UART_RECV);
    
    
    
    int main(void)
    {
      int i,j;
      volatile unsigned char RomH,RomL;  //volatile易变的,不是由程序去改变,而是由硬件去改变
      cli();
         
      DDRC=0x00;     //AVR单片机的IO是3态门,DDRC是C口的方向寄存器,PORTC是C口的数据寄存器,DDRC为0时,C口为输入,IO的高低从PORTC可以读出,DDRC为1时,c为输出,输出高低有PORTC控制。
      PORTC=0x00;   
      
      DDRD|=0x20;    //PD组,PD5输出,其他为输入
      //PORTD&=0xDF;
      PORTD|=0x20;  //PD5置1,LED2不亮
      
      StartFlag=0;
      DacFlag=0;
      RecvIndex=0;
      
      TwiInit();
      uart_init();
      SPI_MasterInit();
      PORT_SPI|=(1 << SS);
    		
      RomH=EEPROM_read(8);
      RomL=EEPROM_read(7);
      if((RomH==0x55)&&(RomL==0xaa)) //第一次下载程序,默认都是255,这时设置为0,防止输出过大
      {
    	RomH=EEPROM_read(4);
    	RomL=EEPROM_read(3);
    	PORT_SPI&=(~(1<<SS));
    	SPI_MasterTransmit(0x18);//DA1
    	SPI_MasterTransmit(RomH);
    	SPI_MasterTransmit(RomL);
    	PORT_SPI|=(1<<SS);
    	delay();
      }
      else
      {
        EEPROM_write(8,0x55);
        EEPROM_write(7,0xaa);
        EEPROM_write(4,0x0);
        EEPROM_write(3,0x0);
    	PORT_SPI&=(~(1<<SS));
    	SPI_MasterTransmit(0x18);
    	SPI_MasterTransmit(0);
    	SPI_MasterTransmit(0);
    	PORT_SPI|=(1<<SS);
    	delay();
      }
      
      RomH=EEPROM_read(6);
      RomL=EEPROM_read(5);
      if((RomH==0x55)&&(RomL==0xaa)) //第一次下载程序,默认都是255,这时设置为0,防止输出过大
      {
    	RomH=EEPROM_read(2);
    	RomL=EEPROM_read(1);
    	PORT_SPI&=(~(1<<SS));
    	SPI_MasterTransmit(0x19);//DA2
    	SPI_MasterTransmit(RomH);
    	SPI_MasterTransmit(RomL);
    	PORT_SPI|=(1<<SS);
      }
      else
      {
        EEPROM_write(6,0x55);
        EEPROM_write(5,0xaa);	
        EEPROM_write(2,0x0);
        EEPROM_write(1,0x0);
    	PORT_SPI&=(~(1<<SS));
    	SPI_MasterTransmit(0x19);
    	SPI_MasterTransmit(0);
    	SPI_MasterTransmit(0);
    	PORT_SPI|=(1<<SS);
      }
      
      RomH=EEPROM_read(18);
      RomL=EEPROM_read(17);
      if((RomH==0x55)&&(RomL==0xaa)) //第一次下载程序,默认都是255,这时设置为0,防止输出过大
      {
    	RomH=EEPROM_read(14);
    	RomL=EEPROM_read(13);
    	PORT_SPI&=(~(1<<SS));
    	SPI_MasterTransmit(0x1A); //DA3
    	SPI_MasterTransmit(RomH);
    	SPI_MasterTransmit(RomL);
    	PORT_SPI|=(1<<SS);
    	delay();
      }
      else
      {
        EEPROM_write(18,0x55);
        EEPROM_write(17,0xaa);
        EEPROM_write(14,0x0);
        EEPROM_write(13,0x0);
    	PORT_SPI&=(~(1<<SS));
    	SPI_MasterTransmit(0x1A);
    	SPI_MasterTransmit(0);
    	SPI_MasterTransmit(0);
    	PORT_SPI|=(1<<SS);
    	delay();
      }
      
      RomH=EEPROM_read(16);
      RomL=EEPROM_read(15);
      if((RomH==0x55)&&(RomL==0xaa)) //第一次下载程序,默认都是255,这时设置为0,防止输出过大
      {
    	RomH=EEPROM_read(12);
    	RomL=EEPROM_read(11);
    	PORT_SPI&=(~(1<<SS));
    	SPI_MasterTransmit(0x1B); //DA4
    	SPI_MasterTransmit(RomH);
    	SPI_MasterTransmit(RomL);
    	PORT_SPI|=(1<<SS);
      }
      else
      {
        EEPROM_write(16,0x55);
        EEPROM_write(15,0xaa);	
        EEPROM_write(12,0x0);
        EEPROM_write(11,0x0);
    	PORT_SPI&=(~(1<<SS));
    	SPI_MasterTransmit(0x1B);
    	SPI_MasterTransmit(0);
    	SPI_MasterTransmit(0);
    	PORT_SPI|=(1<<SS);
      }
       
      sei();
      
      while(1)
       {
    		if(StartFlag)                 //if (StartFlag!=0)
    		{			
    			for(i=0;i<10;i++)          //获得ADC值
    			{
    				ADCSRA=0x00;
    				ADMUX=(0x00|i);
    				ADCSRA=0xC6;
    				
    				for(j=0;j<3;j++)
    				{
    					
    					while(!(ADCSRA&0x10));
    			
    					ADCResult[i][1]=ADCL;
    					ADCResult[i][0]=ADCH;
    					
    					ADCSRA|=0x10;
    					ADCSRA|=0x40; 
    				}
    								
    				while(!(ADCSRA&0x10));
    			
    				ADCResult[i][1]=ADCL;
    				ADCResult[i][0]=ADCH;				
    				ADCSRA|=0x10;
    				
    					if(i==8)                  //ADS1115的1#ADC值
    				{
    					ads1115_start_convert(0xC5);  //##############################################
    					ads1115_read_adc_val(8);
    					
    					twi_delay_bus();
    					
    				}
    
    	        	if(i==9)                  //ADS1115的2#ADC值
    				{
    					ads1115_start_convert(0xE5);
    					ads1115_read_adc_val(9);
    			     
    					twi_delay_bus();
    				
    				}
    
    
    				uart_send('#');              //发送ADC值,十六进制码23,十进制码35,ASCII码#
    				uart_send(i);                //ADC通道
    				uart_send(ADCResult[i][0]);
    				uart_send(ADCResult[i][1]);	
    			
    				TwiInit();
    			}
    			delay();
    		}
    		else
    		{
    			ADCSRA=0x00;
    		}
    		
    		if(DacFlag>0)  //接收上位机指令
    		{
    			if(DacFlag==1) //DA1    腔温控1#
    			{		
    				PORT_SPI&=(~(1<<SS));
    				SPI_MasterTransmit(0x18);
    				SPI_MasterTransmit(RecvData[3]);
    				SPI_MasterTransmit(RecvData[4]);
    				PORT_SPI|=(1<<SS);
    				EEPROM_write(4,RecvData[3]);
    				EEPROM_write(3,RecvData[4]);
    				
    				
    			}
    			if(DacFlag==2) //DA2     LD驱动电流
    			{
    				PORT_SPI&=(~(1<<SS));
    				SPI_MasterTransmit(0x19);
    				SPI_MasterTransmit(RecvData[3]);
    				SPI_MasterTransmit(RecvData[4]);
    				PORT_SPI|=(1<<SS);
    				EEPROM_write(2,RecvData[3]);
    				EEPROM_write(1,RecvData[4]);
    			}			
    			if(DacFlag==0x0A) //DA3   腔温控2#
    			{		
    				PORT_SPI&=(~(1<<SS));
    				SPI_MasterTransmit(0x1A);
    				SPI_MasterTransmit(RecvData[3]);
    				SPI_MasterTransmit(RecvData[4]);
    				PORT_SPI|=(1<<SS);
    				EEPROM_write(14,RecvData[3]);
    				EEPROM_write(13,RecvData[4]);
    				
    				
    			}
    			if(DacFlag==0x0B)  //DA4
    			{
    				PORT_SPI&=(~(1<<SS));
    				SPI_MasterTransmit(0x1B);
    				SPI_MasterTransmit(RecvData[3]);
    				SPI_MasterTransmit(RecvData[4]);
    				PORT_SPI|=(1<<SS);
    				EEPROM_write(12,RecvData[3]);
    				EEPROM_write(11,RecvData[4]);
    			}
    			DacFlag=0;
    		}
       }
    }
    
    void uart_init(void)      //串口初始化
    {  
      UCSRB=0X00;  //关闭UART0
      UCSRA=0X00;  //不使用倍速发送(异步)
      UCSRC=0X06;  //无校验,8位数据,1位停止位
      UBRRH=0X00;
      UBRRL=0X33;  //波特率9600
      UCSRB=0X98;
    }
    
    SIGNAL(SIG_UART_RECV)
    { 
      unsigned char temp;
      cli();
      
      temp=UDR;
      if(RecvIndex==0)
      {
    	if(temp==0x55)
    		RecvData[RecvIndex++]=temp;
      }
      else
      {
    	RecvData[RecvIndex++]=temp;
      }
      
      if(RecvIndex==5)
      {
    	RecvIndex=0;
    	if(RecvData[1]==0xaa)
    	{
    		if(RecvData[2]==3)
    		{
    			if(RecvData[3]=='s')
    			{
    				StartFlag=1;
    				PORTD&=0xDF;
    			}
    			if(RecvData[3]=='p')
    				StartFlag=0;
    		}
    		else
    		{
    			if(RecvData[2]==1)
    				DacFlag=1;
    			if(RecvData[2]==2)
    				DacFlag=2;
    			if(RecvData[2]==0x0A)
    				DacFlag=0x0A;
    			if(RecvData[2]==0x0B)
    				DacFlag=0x0B;
    		}
    	}
      }
      sei();
    }
    
    
    void uart_send(unsigned char temp)   //串口发送子程序
    {
      while(!(UCSRA & 0x20));
      UDR=temp;
    }
    
    
    void adc_init(void)
    {
      ADCSRA=0x00;
      ADMUX=0x00;
      ADCSRA=0xC6;
     }
     
    void SPI_MasterInit(void)    //输出端初始化
    {
    	DDR_SPI = (1 << SS)|(1 << MOSI)|(1 << SCK);
    	SPCR = (1<<SPE)|(1<<MSTR)|(1<<CPHA)|(1<<SPR0);
    	SPSR = 0x00;
    	
    }
    
    void SPI_MasterTransmit(unsigned char cData)
    {
    	SPDR = cData;
    	while(!(SPSR & (1<<SPIF)));
    }
    
    void delay()
    {
      volatile unsigned char i,j,k,l;
      
      for(i=0;i<200;i++)
      {
    	for(j=0;j<100;j++)
    	{
    		for(k=0;k<5;k++)
    			l=k+j;
    	}
      }	
    }
    
    unsigned char EEPROM_read(unsigned int uiAddress)
    {
    /* 等待上一次写操作结束 */
    while(EECR & (1<<EEWE));
    /* 设置地址寄存器 */
    EEAR = uiAddress;
    /* 设置EERE 以启动读操作 */
    EECR |= (1<<EERE);
    /* 自数据寄存器返回数据 */
    return EEDR;
    }
    
    void EEPROM_write(unsigned int uiAddress, unsigned char ucData)
    {
    /* 等待上一次写操作结束 */
    while(EECR & (1<<EEWE));
    /* 设置地址和数据寄存器 */
    EEAR = uiAddress;
    EEDR = ucData;
    /* 置位EEMWE */
    EECR |= (1<<EEMWE);
    /* 置位EEWE 以启动写操作E */
    EECR |= (1<<EEWE);
    }
    
    void twi_delay_bus(void)  
    {
      _delay_loop_2(10);//20*4/8000000=5us
      //_delay_loop_2(20);//20*4/8000000=10us
    }
    
    void twi_ack(unsigned char ack)
    {
      if(!ack)  //非应答
        SET_SDA;            
      else    //应答
        CLR_SDA;
      twi_delay_bus();
      SET_SCL;
      twi_delay_bus();                  
      CLR_SCL;                     
      twi_delay_bus();
    }
    
    /*********以下为外部可调用的接口函数***********/
    //初始化本模块
    void TwiInit(void)
    {
      PORTD&=~(_BV(PD6)|_BV(PD7)); //置0
      DDRD&=~(_BV(PD6)|_BV(PD7));  //输入状态
    }
    //产生启动信号
    unsigned char TwiStart(void)
    {
      twi_delay_bus();
      SET_SDA;       
      twi_delay_bus();  
      SET_SCL;
      twi_delay_bus();
      CLR_SDA;           
      twi_delay_bus();
      CLR_SCL;         
      twi_delay_bus();  
      return 1;
    }
    //产生停止信号
    void TwiStop(void)
    {
      twi_delay_bus();
      CLR_SDA;    
      twi_delay_bus();  
      SET_SCL;
      twi_delay_bus();
      SET_SDA;    
      twi_delay_bus();  
    }
    
    //向总线写一字节,并返回有无应答
    unsigned char TwiWriteByte(unsigned char c)
    {
      unsigned char i,ack;
    
      for(i=0;i<8;i++)  
      {
        if(c&0x80)
          SET_SDA;   
        else  
          CLR_SDA;
        _delay_loop_2(1);                
        SET_SCL;       
        twi_delay_bus();        
        CLR_SCL; 
        c<<=1;
        twi_delay_bus();
      }
      twi_delay_bus();
    
      SET_SDA;                
      twi_delay_bus();
      SET_SCL;
      twi_delay_bus();
      if(SDA_PIN)
        ack=0;     //失败
      else 
        ack=1; 
      _delay_loop_2(1);       
      CLR_SCL;
      twi_delay_bus();
      return ack;  
    }
    
    //读一字节 ack: 1时应答,0时不应答
    unsigned char TwiReadByte(unsigned char ack)
    {
      unsigned char i,ret;
    
      ret=0; 
      SET_SDA;
      for(i=0;i<8;i++)
      { 
        twi_delay_bus();       
        CLR_SCL;                  
        twi_delay_bus();
        SET_SCL;                
        twi_delay_bus();
        ret<<=1;
        if(SDA_PIN)
          ret++;  
      }
      CLR_SCL;    
      twi_delay_bus();
      twi_ack(ack);
      return(ret);  
    }
    
    /******************************
    往ADS1115写入一个字节
    *******************************/
    
    void write_ads1115(unsigned char configreg)
    {
        twi_delay_bus();
    	TwiStart();                      //产生启动信号
        TwiWriteByte(ADS1115_WRITE);     // #define ADS1115_WRITE	0x90 =10010000  地址寄存器  最后那个0标识 写
    	TwiWriteByte(0x01);              //  0x01=00000001   写入指针寄存器指向配置寄存器
    	TwiWriteByte(configreg);        //Config reg的前8位,改变AD通道  1#0xC4  2#0xE4
        TwiWriteByte(0x83);             //Config reg的后8位,不变
        TwiStop();                       //产生停止信号
    	twi_delay_bus(); 
    
    
        TwiStart();                      //产生启动信号
        TwiWriteByte(ADS1115_WRITE);     // #define ADS1115_WRITE	0x90 =10010000  地址寄存器  最后那个0标识 写
        TwiWriteByte(0x00);              // 0x00=00000000   写入指针寄存器指向转换寄存器
    	TwiStop();                       //产生停止信号
        twi_delay_bus(); 
    
    	
    }
    
    /******************************
    从ADS1115读取ADC值
    *******************************/
    
    void ads1115_read_adc_val(int k)
    {   
        unsigned char DH,DL;
    	twi_delay_bus();
    
    	TwiStart();                   //产生启动信号
    	TwiWriteByte(ADS1115_READ);	 //#define ADS1115_READ	0x91=10010001 最后那个1标识 读
    	DH=TwiReadByte(1);           //读一字节数据 ack: 1时应答,0时不应答
    	DL=TwiReadByte(1);          //读一字节数据
    
        TwiStop();                  //产生停止信号
        twi_delay_bus();  
    
    	
    	ADCResult[k][1]=DL;
    	ADCResult[k][0]=DH; 
    
    	twi_delay_bus();  
    	
    	TwiInit();
    	
    }
    
    //开始一次转换
    
    void ads1115_start_convert(unsigned char configreg)
    {
    	write_ads1115(configreg);        //SDA写入 指针寄存器指向配置寄存器
    }
    
  • 稍等我仔细看看回复你

  • 请这样试一下:

    if(i==8) //ADS1115µÄ1#ADCÖµ
    {
    ads1115_start_convert(0xC5); //##############################################

    twi_delay_bus();//给足够的建立时间
    ads1115_read_adc_val(8);



    }

    if(i==9) //ADS1115µÄ2#ADCÖµ
    {
    ads1115_start_convert(0xE5);

    twi_delay_bus();//给足够的建立时间
    ads1115_read_adc_val(9);



    }


    uart_send('#'); //·¢ËÍADCÖµ£¬Ê®Áù½øÖÆÂë23£¬Ê®½øÖÆÂë35£¬ASCIIÂë#
    uart_send(i); //ADCͨµÀ
    uart_send(ADCResult[i][0]);
    uart_send(ADCResult[i][1]);

    //TwiInit();

    另外,如果还不行,建议你使用one shot模式配合OS位或者RDY信号精确控制。事实上这样更好,可以确保一个通道关闭,另外一个通道打开

  • 您好!感谢您的指导,我采用您的建议在写入后加了一个延时,同时重复调用3次,就实现了,感谢您的指导!
       	if(i==9)                  //ADS1115的2#ADC值
    				{
                        for(ql=0;ql<3;ql++)
    					{
    						ads1115_start_convert(0xE5);
    						twi_delay_bus();
    						twi_delay_bus();
    						ads1115_read_adc_val(9);
    			     
    						twi_delay_bus();
    					}
    				
    				}
  • 不客气!很高兴你的问题解决了!