请问一下大家:
1、ADS1115的Config Register 在什么时候配置比较好,因为我需要采集双通道AD
2、写入的时候是不是要先写ADDR,然后Pointer Reg指向Config Reg,然后配置Config Reg,再ADDR,再Conversion Reg
读取的时候是不是只要先写ADDR,然后Pointer Reg指向Conversion Reg,再ADDR,然后输出的是Data
不知道我这样的理解对不对,还请大家帮忙指正,谢谢!
user151383853:
可以参考数据手册 QUICKSTART GUIDE
Carter Liu:
数据手册第11页介绍的很详细的,可以看看。另外Config Register在初始化配置,然后需要切换通道的时候需要重新配置
Qilai Zhao:
回复 Carter Liu:
您好!我现在遇到了另外一个问题,单个通道采集没有问题,但是两个通道交替采集时,出来的数据是一样的,请问一下怎么解决,谢谢!
Carter Liu:
回复 Qilai Zhao:
有可能是你没有切换到另外一个通道上去吧?
Qilai Zhao:
回复 Carter Liu:
我用单个通道都能正常工作,就是两个通道一起交替进行,就出问题了
Qilai Zhao:
回复 Carter Liu:
您好!请问一下对于切换通道,是不是只要在AD写入时改变配置寄存器的值,主要是MUX的值是么?烦请解答,谢谢!
Carter Liu:
回复 Qilai Zhao:
是的,如果有PGA值需要改变也一起改变。配置后请等待一下在开始转换,因为它需要一个startup time
Carter Liu:
回复 Carter Liu:
如果是one shot模式,MUX改变后下一次转换就是新的通道的数据;如果是连续转换模式,MUX 改变不改变当前的转换状态,当这一次转换完成后才切换到下一个通道开始转换。所以MUX切换后的第2租数据才是新通道的有效数据
Qilai Zhao:
回复 Carter Liu:
您好!我尝试按照您说的改了一下,可是结果还是一样,后面附带了我的代码,麻烦您抽空帮忙看一下,感激不尽!#include<avr/io.h> #include<stdio.h> #include <util/delay.h> #include<avr/interrupt.h>#define SS2 #define SCK5 #define MOSI3 #define DDR_SPIDDRB#define PORT_SPIPORTB#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);//DA1SPI_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);//DA2SPI_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); //DA3SPI_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); //DA4SPI_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) //DA2LD驱动电流{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;//关闭UART0UCSRA=0X00;//不使用倍速发送(异步)UCSRC=0X06;//无校验,8位数据,1位停止位UBRRH=0X00;UBRRL=0X33;//波特率9600UCSRB=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)); //置0DDRD&=~(_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;elseCLR_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;//失败elseack=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#0xC42#0xE4TwiWriteByte(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写入 指针寄存器指向配置寄存器 }
Carter Liu:
回复 Qilai Zhao:
稍等我仔细看看回复你
TI中文支持网




