ADS1115是一款高精度的ADC转换器,转换精度达到16位,工作电压适应范围宽,2.0V~5.5V。电流消耗低,连续工作模式下,只有150μA。内部有低温漂的基准电压。采用I2C方式通讯,地址可以通过引脚调整,地址在0x48~0x4B之间调整。四个输入端,可以作为四个通道使用,也可以当做两组差分输入端使用。ADS1115可以工作于连续模式,也可以工作与单次模式。单次模式下,采集完成后会自动关断,降低功耗。
内部结构:
应用电路例:
引脚说明:
ADDR用来选择地址。根据和其它引脚的而连接情况,决定从机地址,
ALERT引脚可以配置为转换就绪引脚,为此需要加载上拉电阻。这样 ,在连续转换的情况下,每次转换完,都会在该引脚提供一个短暂的脉冲。在单次关断模式下,若COM_POL为设为“0”,在转换完成时该引脚会变为低电平。
ADS1115有自己的一些内部寄存器:
要想读写上面这几个寄存器的数据,需要通过Pointer寄存器高知ADS1115,要访问的寄存器,通过Pointer寄存器的Bit1和Bit0来确定访问的寄存器。
Config寄存器的各位的功能说明,本次因为使用Arduino开发,操作过程只需要调用API就可,就不详细说明了。待后期使用其它单片机单独开发的时候,会做补充说明。
通讯时序要求:
与主机连接的典型电路:
主机只要能提供I2C功能(即使是IO口模拟的也没关系),就可以完成和ADS1115之间的通讯,操作ADS1115实现AD转换。
因为在之前的实验中,已经在面包板上搭建了TCA9548A电路,本次实验就在这个电路的基础上加入ADS1115模块,一起在Arduino下测试。
Arduino程序如下
/* * ESP8266通过TCA9548驱动两个OLED */ #include <SPI.h> #include <Wire.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> #include "TCA9548A.h" #include<ADS1115_WE.h> #define TCA9548_ADDR 0x70 // TCA9548A的地址 #define TCA9548_RESET 16 // 复位引脚 #define OLED_ADDR 0x3C // OLED的地址 #define ADS1115_ADDRESS 0x48 // ADS1115的地址 #define ADS1115_ALERT 0 // 转换完成后的通知引脚 GPIO0 TCA9548A I2CMux; ADS1115_WE adc = ADS1115_WE(ADS1115_ADDRESS); // 接线备注:SCL(GPIO5---D1), SDA(GPIO4---D2) // 分辨率: 128 * 32 像素单位 // 使用Wire默认总线:SCL(D1) - GPIO5 ; SDA(D2) - GPIO4 Adafruit_SSD1306 oled(128, 32, &Wire, -1); // 读取转换结果 float readChannel(ADS1115_MUX channel) { float voltage = 0.0; adc.setCompareChannels(channel); voltage = adc.getResult_V(); return voltage; } // 清除屏幕 void clear_oled(uint8_t ole_channel) { if (ole_channel > 7) { return; } // 打开显示用通道 I2CMux.openChannel(ole_channel); // 清除屏幕 oled.clearDisplay(); oled.display(); // 关闭显示用通道 I2CMux.closeChannel(ole_channel); } // 显示转换结果 void show_vol(uint8_t ole_channel, uint8_t x, uint8_t y, float vol) { if (ole_channel > 7) { return; } // 打开显示用通道 I2CMux.openChannel(ole_channel); // 显示位置 oled.setCursor(x, y); // 显示的文字 oled.println(vol); oled.display(); // 关闭显示用通道 I2CMux.closeChannel(ole_channel); } uint8_t cnt = 0; void setup() { // 初始化串口 Serial.begin(115200); Serial.println(); Serial.println("Test TCA9548A."); pinMode(TCA9548_RESET, OUTPUT); I2CMux.begin(Wire); I2CMux.closeAll(); // 选择ADS1115所在的口 I2CMux.openChannel(7); if(!adc.init()){ Serial.println("ADS1115 not connected!"); } else { Serial.println("ADS1115 is OK!"); // 参考电压上限 adc.setVoltageRange_mV(ADS1115_RANGE_4096); // adc.setCompareChannels(ADS1115_COMP_0_GND); // 持续采集 adc.setMeasureMode(ADS1115_CONTINUOUS); } I2CMux.closeChannel(7); // 选择第一个I2C口 I2CMux.openChannel(0); oled.begin(SSD1306_SWITCHCAPVCC, OLED_ADDR); // 白色字体 oled.setTextColor(WHITE); // 清屏 oled.clearDisplay(); // 设置字体大小 oled.setTextSize(2); // 设置显示位置 oled.setCursor(0, 0); // 显示的文字 oled.println("OLED0"); // 开显示 oled.display(); // 关闭通道 I2CMux.closeChannel(0); // 选择第一个I2C口 I2CMux.openChannel(1); oled.begin(SSD1306_SWITCHCAPVCC,0x3C); oled.setTextColor(WHITE);//开像素点发光 oled.clearDisplay();//清屏 oled.setTextSize(2);//设置字体大小 oled.setCursor(0, 0);//设置显示位置 oled.println("OLED1"); oled.display(); // 开显示 I2CMux.closeChannel(1); delay(5000); } void loop() { float vol1 = 0.0; float vol2 = 0.0; float vol3 = 0.0; float vol4 = 0.0; // 获取4个通道的转换结果 I2CMux.openChannel(7); vol1= readChannel(ADS1115_COMP_0_GND); vol2= readChannel(ADS1115_COMP_1_GND); vol3= readChannel(ADS1115_COMP_2_GND); vol4= readChannel(ADS1115_COMP_3_GND); I2CMux.closeChannel(7); Serial.print(" Vol1 = ");Serial.println(vol1); Serial.print(" Vol2 = ");Serial.println(vol2); Serial.print(" Vol3 = ");Serial.println(vol3); Serial.print(" Vol4 = ");Serial.println(vol4); // 显示到OLED上,前两个显示到OLED0, 后两个显示到OLED1 clear_oled(0); show_vol(0,0,0,vol1); show_vol(0,0,16,vol2); clear_oled(1); show_vol(1,0,0,vol3); show_vol(1,0,16,vol4); delay(1000); }
程序中,对转换器的操作为循环模式,没有使用Alert判断转换是否完成。程序同时处理四个输入端的转换,每秒读取处理转换结果,并在OLED上显示。ADC以外的电路,直接使用上次TCA 9548A 构成的I2C拓展电路。
从测结果上看,很稳定。ADS1115确实是一个很好的转换芯片。