微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 硬件电路设计 > TI模拟硬件电路设计 > ADS1115的配置

ADS1115的配置

时间:10-02 整理:3721RD 点击:

请问一下大家:

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();}		}

不客气!很高兴你的问题解决了!

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top