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确实是一个很好的转换芯片。
我要赚赏金
