请问一下大家:
1、ADS1115的Config Register 在什么时候配置比较好,因为我需要采集双通道AD
2、写入的时候是不是要先写ADDR,然后Pointer Reg指向Config Reg,然后配置Config Reg,再ADDR,再Conversion Reg
读取的时候是不是只要先写ADDR,然后Pointer Reg指向Conversion Reg,再ADDR,然后输出的是Data
不知道我这样的理解对不对,还请大家帮忙指正,谢谢!
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.
请问一下大家:
1、ADS1115的Config Register 在什么时候配置比较好,因为我需要采集双通道AD
2、写入的时候是不是要先写ADDR,然后Pointer Reg指向Config Reg,然后配置Config Reg,再ADDR,再Conversion Reg
读取的时候是不是只要先写ADDR,然后Pointer Reg指向Conversion Reg,再ADDR,然后输出的是Data
不知道我这样的理解对不对,还请大家帮忙指正,谢谢!
您好!我现在遇到了另外一个问题,单个通道采集没有问题,但是两个通道交替采集时,出来的数据是一样的,请问一下怎么解决,谢谢!
您好!请问一下对于切换通道,是不是只要在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();
}
}