ADS1115简介:
ADS1115是TI生产的具有I2C接口的16位ADC。
内部ADC采样率 8、16、32、64、128、250、475、860 SPS可调。
四通道输入可选,可选四通道间的差分输入,可也选择测量与GND间的单端电位差。
PGA增益 2/3、1、2、4、8、16 可调。
I2C器件地址 0x48(GND)、0x49(VDD)、0x4A(SDA)、0x4B(SCL) 可选。
ADC采样值超出可编程比较器的设定值时,会在 ALERT/RDY 引脚上输出一个电平信号。
3.1 Pointer register (Write-Only) (8Bit) -- 指针寄存器
注:Pointer register并不是有地址空间的的寄存器,而是 I2C消息帧的从机寄存器地址。
3.2 Conversion register (Read-Only)(16Bit) -- 转换结果寄存器
3.3 Config Register (Read/Write)(16Bit) -- 配置寄存器
3.4 Lo_thresh register (Read/Write)(16Bit) -- 比较器下限阈值寄存器
Hi_thresh register (Read/Write)(16Bit) -- 比较器上限阈值寄存器
配置 Config Register 寄存器,配置 输入通道、采样率、PGA放大倍数、比较器模式。
配置 Lo_thresh register、Hi_thresh register 可编程比较器。
循环读 Conversion register,此为ADC转换后的值。
如果ADC采样值超出可编程比较器的设定值时,会在 ALERT/RDY 引脚上输出一个电平信号。
ads1115的通信总线为 I2C,但使用上来讲,和标准的 I2C设备并不一样。
ads1115因为引入了一个8Bit的 Pointer register,使ads1115的 I2C读时序跟标准 I2C设备不同。
ads1115的 I2C写时序是与标准I2C设备相同的。
标准 I2C设备的读时序为:从机器件地址 + 从机寄存器地址 + 从机的寄存器数据
ads1115的读时序为:从机器件地址 + 从机的寄存器数据(前提是要先设置 Pointer register)
设置 Pointer register 的I2C时序:从机器件地址 + Pointer register(只需要配置这一次,以后的读都是从Pointer register读)
I2C读的差异见数据手册24、25页。
代码差异见下面代码。有条件的看看示波器、逻辑分析仪。
ads1115.c
#include "ads1115.h"
#include "myiic.h"
#include "delay.h"
#include
/**
******************************************************************************
* @file ads1115.c
* @author zhiLiangMa
* @version V0.1.0
* @date 2019/06/30
* @brief ads1115.c.h包含了ads1115基本驱动函数,超范围触发跳变沿,和称重传感器的单位转换
******************************************************************************
* @attention
*
* 1.使用此驱动前注意。ads1115的iic时序跟at24c02,mpu6050这种标准iic协议有所不同
* ,不同主要体现在读取上。详见手册24页,写数据是跟标准iic一致的
* ,正常的iic的读,先发设备iic的ID,再发要读的寄存器地址,再发设备iic的ID+1
* 。而ads引入了设备指针寄存器,不用在每帧的iic帧中携带寄存器地址
* 2.ads的正确读法为,iic写数据,将指针寄存器指向想读的寄存器地址
* ,再将iic的设备ID的最后一位当作读/写控制位,读1写0,省略标准iic帧中的寄存器地址。直接读数据。
* 3.简而言之,标准iic读到用户想要的数据之前,需要发三个字节:设备ID,用户所需的设备寄存器地址,设备ID+1
* 。而ads,在得到用户想要的数据之前,只需要发送一个字节:包括读写控制位的设备ID。。。不过在此之前要写指针控制器将所需的地址写入
* 4.还要注意,写16位寄存器的时候,一次必须写满16位。16位只写8位,后面8位没法寻址
******************************************************************************
*/
/*====================================================================================================*/
/*====================================================================================================*
** 函数名称: ADS1115_WriteOneByte(uint8_t ads_addr, uint8_t WriteAddr,uint8_t DataToWrite)
** 功能描述: 向ads1115内部寄存器,的指定地址写入1Byte数据
** 输 入: ads_addr 选中的ads1115的IIC器件地址
WriteAddr 写入数据的目的地址
DataToWrite 写入的1Byte数据
** 输 出: void
** 说 明: ads1115的写数据和标准IIC的写是一致的
**====================================================================================================*/
/*====================================================================================================*/
void ADS1115_WriteOneByte(uint8_t ads_addr, uint8_t WriteAddr,uint8_t DataToWrite)
{
IIC_Start();
IIC_Send_Byte(ads_addr); //发送写命令
IIC_Wait_Ack();
IIC_Send_Byte(WriteAddr); //发送高地址
IIC_Wait_Ack();
IIC_Send_Byte(DataToWrite); //发送字节
IIC_Wait_Ack();
IIC_Stop(); //产生一个停止条件
}
/*====================================================================================================*/
/*====================================================================================================*
** 函数名称: ADS1115_WriteMulByte(uint8_t ads_addr, uint8_t WriteAddr,uint8_t xnum,uint8_t* xData)
** 功能描述: 向ads1115内部寄存器,的指定地址写入多个Byte数据
** 输 入: ads_addr 选中的ads1115的IIC器件地址
WriteAddr 写入数据的目的地址
xnum 写入的Byte个数
*xData 写入的数据数组
** 输 出: void
** 说 明: ads1115的写数据和标准IIC的写是一致的
**====================================================================================================*/
/*====================================================================================================*/
void ADS1115_WriteMulByte(uint8_t ads_addr, uint8_t WriteAddr,uint8_t xnum,uint8_t* xData)
{
uint8_t i=0;
IIC_Start(); //开启I2C
IIC_Send_Byte(ads_addr);
IIC_Wait_Ack();
IIC_Send_Byte(WriteAddr);
IIC_Wait_Ack();
for(i=0; i>8) & 0x00FF;
xsend[1] = LowerThreshold & 0x00FF;
//数字电压比较器电压下限阈值设定
ADS1115_WriteMulByte(ads_addr, LoThreshRegister, 2, xsend);
delay_ms(2);
xsend[0] = (UpperThreshold>>8) & 0x00FF;
xsend[1] = UpperThreshold & 0x00FF;
//数字电压比较器电压上限阈值设定
ADS1115_WriteMulByte(ads_addr, HiThreshRegister, 2, xsend);
}
/*====================================================================================================*/
/*====================================================================================================*
** 函数名称: ADS1115_AlertGPIOInit(void)
** 功能描述: Alert引脚的STM32的GPIO配置。可以选中断触发,也可以选择扫描电平的方式。
** 输 入: void
** 输 出: void
** 说 明: 因为ads1115的采样频率比较低,选择扫描电平的方式,会漏掉很多超出阈值的时刻
** 强烈建立用GPIO的中断输入来做。高电平还是低电平触发中断,详见上面那条函数的配置方式
**====================================================================================================*/
/*====================================================================================================*/
void ADS1115_AlertGPIOInit(void)
{
/* 初始化ADS1115_Alert - PC8 的IO为上拉输入 */
GPIO_InitTypeDef GPIO_InitStructure; //定义结构体变量
RCC_APB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE); //使能GPIOC时钟
//ADS1115_Alert - PC8
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;//普通输入模式
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100M
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
GPIO_Init(GPIOC, &GPIO_InitStructure);
}
/*====================================================================================================*/
/*====================================================================================================*
** 函数名称: void ADS1115_Init(void)
** 功能描述: ADS1115的初始化,包括IIC引脚设置,数字电压比较器设置,Alert中断引脚设置,A/D转换速率设置,PGA增益设置,输入引脚通道设置
** 输 入: void
** 输 出: void
** 说 明: 整合上面所有配置,每次配置之间加100ms延时,是防止模拟IIC连续发送后的串扰
**====================================================================================================*/
/*====================================================================================================*/
uint16_t itemp,otemp = 0;
void ADS1115_Init(void)
{
//IIC引脚初始化
IIC_Init(); //初始化IIC接口,SCL-PC9,SDA-PA8
//单片机Alert输入引脚配置,Alert - PC8
ADS1115_AlertGPIOInit();
//数字电压比较器,上下阈值设定;比较器分传统比较器和窗口比较器,详见53页数据手册的19页
delay_ms(10);
ADS1115_Comparator_Threshold(ads1115_GND_iic_addr, -200, 200);
//采样率大,噪声也会大。详见53页数据手册的13页
//窗口比较器,非锁存比较器
//128SPS采样率。PGA增益为16,引脚最大输入电压为±0.256 +0.3V
//Aler引脚,低电平有效。也就是说超出数字电压比较器设定阈值后,Alert输出低电平
delay_ms(10);
ADS1115_ConfigRegister(ads1115_GND_iic_addr);
//读取 ConfigRegister数据,不为FFFF则 I2C写入正常
delay_ms(10);
ADS1115_PointRegister(ads1115_GND_iic_addr, ConfigRegister);
delay_ms(10);
otemp = ADS1115_ReadConversionRegister(ads1115_GND_iic_addr);// 读取ads1115的ConversionRegister,验证 I2C写入读取是否正确
//内部指针寄存器的指向地址,指向A/D转换结果寄存器。
delay_ms(10);
ADS1115_PointRegister(ads1115_GND_iic_addr, ConversionRegister);
}
ads1115.h
#ifndef __ADS1115_H
#define __ADS1115_H
#include "stm32f4xx.h"
/**
******************************************************************************
* @file ads1115.h
* @author zhiLiangMa
* @version V0.1.0
* @date 2019/06/30
* @brief ads1115.c.h包含了ads1115基本驱动函数,超范围触发跳变沿,和称重传感器的单位转换
******************************************************************************
* @attention
*
* 1.使用此驱动前注意。ads1115的iic时序跟at24c02,mpu6050这种标准iic协议有所不同
* ,不同主要体现在读取上。详见手册24页,写数据是跟标准iic一致的
* ,正常的iic的读,先发设备iic的ID,再发要读的寄存器地址,再发设备iic的ID+1
* 。而ads引入了设备指针寄存器,不用在每帧的iic帧中携带寄存器地址
* 2.ads的正确读法为,iic写数据,将指针寄存器指向想读的寄存器地址
* ,再将iic的设备ID的最后一位当作读/写控制位,读1写0,省略标准iic帧中的寄存器地址。直接读数据。
* 3.简而言之,标准iic读到用户想要的数据之前,需要发三个字节:设备ID,用户所需的设备寄存器地址,设备ID+1
* 。而ads,在得到用户想要的数据之前,只需要发送一个字节:包括读写控制位的设备ID。。。不过在此之前要写指针控制器将所需的地址写入
* 4.还要注意,写16位寄存器的时候,一次必须写满16位。16位只写8位,后面8位没法寻址
******************************************************************************
*/
/* ADDR引脚连接不同电平时,设备显现出不同的I2C地址 */
#define ads1115_GND_iic_addr 0x90
#define ads1115_VDD_iic_addr 0x92
#define ads1115_SDA_iic_addr 0x94
#define ads1115_SCL_iic_addr 0x96
/* ADS1115寄存器地址 */
#define ConversionRegister 0x00
#define ConfigRegister 0x01
#define LoThreshRegister 0x03
#define HiThreshRegister 0x04
/* 读取Alert引脚电平,判断是否超出数字比较器量程 */
#define GetADS1115Alert GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_8)
/* 使用联合体&位域来配置寄存器 */
//联合体和位域结合 http://www.stmcu.org.cn/module/forum/forum.php?mod=viewthread&tid=610197
//因为位域的内存累计是从低位开始的,所以将手册中高位的寄存器放在位域定义的尾部
union xADS1115ConfigRegisterH
{
uint8_t value;
struct{
uint8_t MODE:1;
uint8_t PGA:3;
uint8_t MUX:3;
uint8_t OS:1;
}RegisterH;
};
union xADS1115ConfigRegisterL
{
uint8_t value;
struct{
uint8_t COMP_QUE:2;
uint8_t COMP_LAT:1;
uint8_t COMP_POL:1;
uint8_t COMP_MODE:1;
uint8_t DR:3;
}RegisterL;
};
/************************************************
ads1115内部寄存器功能定义
************************************************/
//运行状态或单次转换位
//运行状态或单次转换启动此位确定设备的运行状态。 OS只能在掉电状态下写入,并且在转换正在进行时无效。
enum OS
{
No_effect=0, //无效
Start_single_conversion //开启一次单次转换
};
//输入多路复用器配置
//这些位配置输入多路复用器
enum MUX
{
AIN0_AIN1=0, //MUX选通的连接到PGA的引脚为AIN0和AIN1
AIN0_AIN3,
AIN1_AIN3,
AIN2_AIN3,
AIN0_GND,
AIN1_GND,
AIN2_GND,
AIN3_GND
};
//可编程增益放大器配置
//这些位设置可编程增益放大器的FSR
//此参数表示ADC缩放的满量程范围。 请勿对器件的模拟输入施加超过VDD + 0.3 V的电压
enum PGA
{
Gain_2_3_6144V=0, //增益为2/3,引脚最大输入电压为±6.144 +0.3V
Gain_1_4096V, //增益为1,引脚最大输入电压为±4.096 +0.3V
Gain_2_2048V, //增益为2,引脚最大输入电压为±2.048 +0.3V
Gain_4_1024V, //增益为4,引脚最大输入电压为±1.024 +0.3V
Gain_8_0512V, //增益为8,引脚最大输入电压为±0.512 +0.3V
Gain_16_0256V, //增益为16,引脚最大输入电压为±0.256 +0.3V
Gain_16_0256V1, //增益为16,引脚最大输入电压为±0.256 +0.3V
Gain_16_0256V2 //增益为16,引脚最大输入电压为±0.256 +0.3V
};
//设备运行模式
//该位控制操作模式。
enum MODE
{
Continuous_conversion_mode=0, //连续转换模式
Single_shot_mode //单次模式或掉电状态
};
//数据速率
//这些位控制数据速率设置。
enum DR
{
Rate_8=0, //8 SPS
Rate_16, //16 SPS
Rate_32, //32 SPS
Rate_64, //64 SPS
Rate_128, //128 SPS
Rate_250, //250 SPS
Rate_475, //475 SPS
Rate_860 //860 SPS
};
//比较器模式
//该位配置比较器工作模式
enum COMP_MODE
{
Traditional_comparator=0, //传统比较器
Window_comparator //窗口比较器
};
//比较器极性
//该位控制ALERT / RDY引脚的极性
enum COMP_POL
{
Active_low=0, //低电平有效
Active_high //高电平有效
};
//比较器锁存
//该位控制ALERT / RDY引脚在置位后是锁存还是在转换后的阈值上限和下限范围内清零
enum COMP_LAT
{
Nonlatching=0, //非锁存比较器
Latching //锁存比较器
};
//比较器队列和失能
//这些位执行两个功能。 设置为11时,比较器禁用,ALERT / RDY引脚设置为高阻态。 当设置为任何其他值时,ALERT / RDY引脚和比较器功能被使能,并且设置值确定在断言ALERT / RDY引脚之前超过所需的上限或下限的连续转换次数
enum COMP_QUE
{
One=0, //一次转换后断言
Two, //两次转换后断言
Four, //四次转换后断言
Disable //禁用比较器并将ALERT / RDY引脚设置为高阻态
};
/*====================================================================================================*/
/*====================================================================================================*
** 函数名称: ADS1115_ReadConversionRegister(uint8_t ads_addr)
** 功能描述: 读取ADS1115的16位ADC转换数据,注意类型,是int16,有符号
** 输 入: ads_addr 选中的ads1115的IIC器件地址
** 输 出: 16位ADC转换数据,注意类型,是int16,有符号
** 说 明: 注意类型,是int16,有符号
**====================================================================================================*/
/*====================================================================================================*/
int16_t ADS1115_ReadConversionRegister(uint8_t ads_addr);
/*====================================================================================================*/
/*====================================================================================================*
** 函数名称: ADS1115_GetAinVoltage(uint8_t ads_addr)
** 功能描述: 获取ADS1115的输入端口电压,根据寄存器的配置,得到实际的电压值
** 输 入: ads_addr 选中的ads1115的IIC器件地址
** 输 出: float类型的电压数据
** 说 明: 电压单位为V
** Table 3. Full-Scale Range and Corresponding LSB Size ti官网53页手册的17页
** FSR LSB SIZE
** ±6.144 V(1) 187.5 μV
** ±4.096 V(1) 125 μV
** ±2.048 V 62.5 μV
** ±1.024 V 31.25 μV
** ±0.512 V 15.625 μV
** ±0.256 V 7.8125 μV
**====================================================================================================*/
/*====================================================================================================*/
float ADS1115_GetAinVoltage(uint8_t ads_addr);
/*====================================================================================================*/
/*====================================================================================================*
** 函数名称: ADS1115_PointRegister(uint8_t ads_addr,uint8_t point)
** 功能描述: 设置内部指针寄存器的指向地址,指向ADS1115指针寄存器用于准备读取数据
** 输 入: ads_addr 选中的ads1115的IIC器件地址
point 内部指针寄存器的指向地址
** 输 出: void
** 说 明: 想要读取ADC转换的值,必须调用这个函数将指针指向ADC转换数据寄存器,然后IIC读取。
** 所以就不用在IIC读中携带ADC转换数据寄存器地址
**====================================================================================================*/
/*====================================================================================================*/
void ADS1115_PointRegister(uint8_t ads_addr,uint8_t point);
/*====================================================================================================*/
/*====================================================================================================*
** 函数名称: ADS1115_ConfigRegister(uint8_t ads_addr)
** 功能描述: 配置ADS1115内部寄存器,来完成通道选择,抓换速率,PGA增益倍数等信息配置
** 输 入: ads_addr 选中的ads1115的IIC器件地址
** 输 出: void
** 说 明: 如果需要更改设置,请更改下面的联合体的结构体内容
**====================================================================================================*/
/*====================================================================================================*/
void ADS1115_ConfigRegister(uint8_t ads_addr);
/*====================================================================================================*/
/*====================================================================================================*
** 函数名称: ADS1115_Comparator_Threshold(uint8_t ads_addr, int16_t LowerThreshold, int16_t UpperThreshold)
** 功能描述: 设置数字电压比较器的上下限阈值
** 输 入: ads_addr 选中的ads1115的IIC器件地址
** LowerThreshold 阈值下限
** UpperThreshold 阈值上限
** 输 出: void
** 说 明: 如果开启的数字电压比较器的ALERT输出,超出阈值下限或者上限,都会在ALERT引脚上产生电平跳变
**====================================================================================================*/
/*====================================================================================================*/
void ADS1115_Comparator_Threshold(uint8_t ads_addr, int16_t LowerThreshold, int16_t UpperThreshold);
/*====================================================================================================*/
/*====================================================================================================*
** 函数名称: ADS1115_AlertGPIOInit(void)
** 功能描述: Alert引脚的STM32的GPIO配置。可以选中断触发,也可以选择扫描电平的方式。
** 输 入: void
** 输 出: void
** 说 明: 因为ads1115的采样频率比较低,选择扫描电平的方式,会漏掉很多超出阈值的时刻
** 强烈建立用GPIO的中断输入来做。高电平还是低电平触发中断,详见上面那条函数的配置方式
**====================================================================================================*/
/*====================================================================================================*/
void ADS1115_AlertGPIOInit(void);
/*====================================================================================================*/
/*====================================================================================================*
** 函数名称: void ADS1115_Init(void)
** 功能描述: ADS1115的初始化,包括IIC引脚设置,数字电压比较器设置,Alert中断引脚设置,A/D转换速率设置,PGA增益设置,输入引脚通道设置
** 输 入: void
** 输 出: void
** 说 明: 整合上面所有配置,每次配置之间加100ms延时,是防止模拟IIC连续发送后的串扰
**====================================================================================================*/
/*====================================================================================================*/
void ADS1115_Init(void);
#endif
main.c
int16_t ads1115_ch1_adValue; //ads1115的adc转换值
uint8_t ads1115AlertPin;
int main(void)
{
ADS1115_Init();
while(1)
{
ads1115_ch1_adValue = ADS1115_ReadConversionRegister(ads1115_GND_iic_addr);// 读取ads1115的AD值
ads1115AlertPin = GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_8);// 读取Alert引脚电平,判断adc转换值是否超出比较器阈限
delay_ms(100);
}
}
如需对 ads1115的 输入通道、采样率、PGA进行配置,直接修改 void ADS1115_ConfigRegister(uint8_t ads_addr)内容
使用联合体、位域 构建结构体的方法,使用起来更加直观。
如需对 ads1115的 可编程比较器 进行配置,直接修改 ADS1115_Comparator_Threshold(ads1115_GND_iic_addr, -200, 200);