STM32 驱动 ADS1015 单端 差分 多通道模式 ADC 转换

发布于:2025-07-03 ⋅ 阅读:(14) ⋅ 点赞:(0)


一、ADS1015简介

ADS1015 是一款由德州仪器(TI)推出的 12 位高精度模数转换器(ADC),通过 I²C 接口与主控设备通信。它提供 4 路单端输入或 2 路差分输入,内置可编程增益放大器(PGA),支持多种电压测量范围,最高采样率可达 3300 次每秒,广泛应用于传感器数据采集、电压监测、工业控制等场合。
在这里插入图片描述

二、引脚功能

ADDR IIC地址选择
ALERT/RDY 比较器输出高低或转换就绪
GND 电源地
AIN0-AIN3 模拟量输入
VDD 电源正
SDA IIC时钟线
SCL IIC数据线

ADS1015引脚ADDR用于设置器件的IIC地址, 该引脚可以连接到GND、VDD、SDA、SCL,从而选择四个不同的IIC地址。本文使用的模块ADDR引脚接在GND上,故从机地址为0x90/0x91。
在这里插入图片描述

三、寄存器介绍

(只说明需要用到的两个寄存器,其它的不做说明可自行查看手册)

1.Conversion Register 转化数据存放寄存器

16 位转换寄存器(Conversion register)包含上一次转换的结果,格式为二进制补码。上电后,转换寄存器被清零为 0000h,并保持该值,直到第一次转换完成。
在这里插入图片描述

由图表可知 AD 转换后的 AD 值存放于该寄存器15-4位,而 3-0 位保留为0,故读取数据只需高 12 位即可

2.Config Register 配置寄存器

16位配置寄存器用于控制操作模式、输入选择、数据速率、满量程范围和比较器模式。

Bit 字段 类型 复位值 描述
15 OS R/W 1h 运行状态或单次转换启动该位决定设备的运行状态。
操作系统只能在下电状态下写入,在转换过程中没有作用。
写入:
0:没有效果
1:启动单次转换(在断电状态下)
读时:
0:设备当前正在执行转换
1:设备当前未执行转换
14:12 MUX[2:0] R/W 0h 输入多路复用配置
000 : AINP = AIN0 and AINN = AIN1 (default)
001 : AINP = AIN0 and AINN = AIN3
010 : AINP = AIN1 and AINN = AIN3
011 : AINP = AIN2 and AINN = AIN3
100 : AINP = AIN0 and AINN = GND
101 : AINP = AIN1 and AINN = GND
110 : AINP = AIN2 and AINN = GND
111 : AINP = AIN3 and AINN = GND
11:9 PGA[2:0] R/W 2h 可编程增益放大器配置
这些位设置可编程增益放大器的FSR
000 : FSR = ±6.144 V
001 : FSR = ±4.096 V
010 : FSR = ±2.048 V (default)
011 : FSR = ±1.024 V
100 : FSR = ±0.512 V
101 : FSR = ±0.256 V
110 : FSR = ±0.256 V
111 : FSR = ±0.256 V
8 MODE R/W 1h 设备运行方式
这个位控制操作模式。
0:连续转换模式
1:单次模式或掉电状态(默认)
7:5 DR[2:0] R/W 4h 数据速率
这些位控制数据速率设置。
000 : 8 SPS
001 : 16 SPS
010 : 32 SPS
011 : 64 SPS
100 : 128 SPS (default)
101 : 250 SPS
110 : 475 SPS
111 : 860 SPS
4 COMP_MODE R/W 0h 比较器模式
该位控制比较器工作
0:传统比较器(默认)
1:窗口比较器
3 COMP_POL R/W 0h 比较器极性
该位控制ALERT / RDY引脚的极性
0:低电平有效(默认)
1:高电平有效
2 COMP_LAT R/W 0h 锁存比较器
该位控制ALERT / RDY引脚在被置为有效后锁存,还是在转换后处于上限和下限阈值范围之内清零。
0:非锁存比较器。 置位后ALERT / RDY引脚不锁存(默认)
1:锁存比较器。 置为有效的ALERT / RDY引脚保持锁存状态,直到转换数据由主服务器或适当的SMBus警报响应读取由主机发送。 设备以其地址响应,它是最低的当前声明ALERT / RDY总线的地址。
1:0 COMP_QUE[1:0] R/W 3h 比较器置位和禁用
这些位执行两个功能。 设置为11时,比较器被禁用,ALERT / RDY引脚被设置为高阻抗状态。 当设置为任何其他值时,将启用ALERT / RDY引脚和比较器功能,并且该设置值确定连续的转换次数超过在声明ALERT / RDY引脚之前所需的上限或下限阈值
00:一次转换后断言
01:两次转换后置位
10:四次转换后置位
11:禁用比较器并将ALERT / RDY引脚设置为高阻抗(默认)

四、IIC时序

1.写寄存器

在这里插入图片描述

2.读寄存器

在这里插入图片描述

五、程序

ADS1015.h
#ifndef __ADS1015_H
#define __ADS1015_H

/*IIC 地址--------------------------------------------------------------------------*/
#define ADS1015_W 0x90
#define ADS1015_R 0x91
/*寄存器地址----------------------------------------------------------------------------*/
#define REG_Conversion 0x00
#define REG_config		 0x01
#define REG_L_thresh 	 0x02
#define REG_H_thresh 	 0x03
/* REG_config Bit15-4 ------------------------------------------------------------------*/
#define OS 				     1 		  //操作状态或单发转换启动  (1位)
#define MUX 			     0x04 	  //输入多路配置  通道0  (3位)
#define PGA 			     0x00	  //可编程增益放大器配置  量程 ±6.144  V  (3位)
#define MODE		         0x00	  //设备运行方式  连续转换模式  (1位)
#define DR				     0x03     //转换速率920SPS  (3位)
#define	COMP_MODE	         0 		  //比较器模式  传统比较器  (默认)(1位)
#define COMP_POL 	         0		  //比较器极性  低电平有效  (默认)(1位)
#define COMP_LAT	         0 		  //锁存比较器  非锁存比较器, 置位后ALERT / RDY引脚不锁存  (默认)(1位)
#define COMP_QUE	         0x03 	  //比较器置位和禁用  禁用 (默认)(2位)
#define config_MSB (OS << 7)|(MUX << 4)|(PGA << 1)|(MODE)
#define config_LSB (DR << 5)|(COMP_MODE << 4)|(COMP_POL << 3)|(COMP_LAT << 2)|(COMP_QUE)

uint32_t ADS1015_ReadReg(uint8_t RegAddress);
void ADS1015_WriteReg(uint8_t RegAddress, uint8_t Data_H, uint8_t Data_L);
void ADS1015_Init(void);
int32_t ADS1015_GetVoltage(void);

#endif
ADS1015.C
#include "stm32f10x.h"                   // Device header
#include "MyI2C.h"
#include "ADS1015.h"

void ADS1015_WriteReg(uint8_t RegAddress, uint8_t Data_H, uint8_t Data_L)
{
	MyI2C_Start();						  //I2C起始
	MyI2C_SendByte(ADS1015_W);	          //发送从机地址,读写位为0,表示即将写入
    MyI2C_ReceiveAck();					  //接收应答
	MyI2C_SendByte(RegAddress);		      //发送寄存器地址
	MyI2C_ReceiveAck();					  //接收应答
	MyI2C_SendByte(Data_H);			      //发送要写入寄存器的数据高位
	MyI2C_ReceiveAck();					  //接收应答
	MyI2C_SendByte(Data_L);			      //发送要写入寄存器的数据低位
	MyI2C_ReceiveAck();					  //接收应答
	MyI2C_Stop();						  //I2C终止
}

uint32_t ADS1015_ReadReg(uint8_t RegAddress)
{
	uint32_t Data=0;
	
	MyI2C_Start();						  //I2C起始
	MyI2C_SendByte(ADS1015_W);	          //发送从机地址
	MyI2C_ReceiveAck();					  //接收应答
	MyI2C_SendByte(RegAddress);	          //发送寄存器地址
	MyI2C_ReceiveAck();					  //接收应答
	
	MyI2C_Start();					   	  //I2C重复起始
	MyI2C_SendByte(ADS1015_R);	          //发送从机地址
	MyI2C_ReceiveAck();					  //接收应答
	Data = MyI2C_ReceiveByte();	          //接收指定寄存器的高位数据
	MyI2C_SendAck(0);				  	  //发送应答
	Data = (Data << 4) | ((MyI2C_ReceiveByte())>>4);//接收指定寄存器的低位数据
	MyI2C_SendAck(1);                     //发送非应答
	MyI2C_Stop();						  //I2C终止
	
	return Data;
}

int32_t ADS1015_GetVoltage(void)//获取电压
{
	uint32_t AD=0;
	int32_t Voltage=0;
	
	AD = ADS1015_ReadReg(REG_Conversion);    //获取 AD 值
	
	if(AD > 0x7FF)                           //如果是负压
	{
		Voltage = 0-((0xFFF-AD)*(6144/2048));//分辨率:6.144V÷2^11=6144mV÷2048   电压=AD值*分辨率
	}else                                    //正压
	{
		Voltage = AD*(6144/2048);
	}
	
	return Voltage;
}

void ADS1015_Init(void)
{
 	ADS1015_WriteReg(REG_config,config_MSB,config_LSB);
}
main.C
#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "ADS1015.h"
#include "MyI2C.h"

int32_t Channel_0_voltage,Channel_1_voltage,Channel_2_voltage,Channel_3_voltage;//定义用于存放各个通道的电压数据

void SingleVoltage_Show(void);
void MultipleChannels_Show(void);

int main(void)
{
	Delay_ms(1000);//上电延时
	MyI2C_Init();
	ADS1015_Init();//配置寄存器初始化
	OLED_Init();
	Delay_ms(1000);
	
	SingleVoltage_Show();//单端模式
	//MultipleChannels_Show();//伪多通道模式
}

void SingleVoltage_Show(void)//单端模式 IN0 输入模拟电压,需使用其它通道修改 ADS1015.h 头文件中的 MUX 字段
{
	while(1)
	{
		Channel_0_voltage = ADS1015_GetVoltage();
		OLED_ShowString(1,1,"Channel0:");OLED_ShowSignedNum(1,10,Channel_0_voltage,4);OLED_ShowString(1,15,"mV");
		Delay_ms(1000);
	}
}

//差分模式在单端模式基础上改一下 ADS1015.h 头文件中的 MUX 字段,修改输入通道模式即可

void MultipleChannels_Show(void)//伪多通道模式,ADS1015只有一个ADC,不能真正同时多通道输入,采用时分复用方法,配置多个通道快速分时采集
{
	while(1)
	{
		#define MUX 0x04 	    //使用通道0
		#define config_MSB (OS << 7)|(MUX << 4)|(PGA << 1)|(MODE)
		ADS1015_WriteReg(REG_config,config_MSB,config_LSB);Delay_ms(100);
		Channel_0_voltage = ADS1015_GetVoltage();
		
		#define MUX 0x05 	    //使用通道1
		#define config_MSB (OS << 7)|(MUX << 4)|(PGA << 1)|(MODE)
		ADS1015_WriteReg(REG_config,config_MSB,config_LSB);Delay_ms(100);
		Channel_1_voltage = ADS1015_GetVoltage();
		
		#define MUX 0x06 	    //使用通道2
		#define config_MSB (OS << 7)|(MUX << 4)|(PGA << 1)|(MODE)
		ADS1015_WriteReg(REG_config,config_MSB,config_LSB);Delay_ms(100);
		Channel_2_voltage = ADS1015_GetVoltage();
		
		#define MUX 0x07      //使用通道3
		#define config_MSB (OS << 7)|(MUX << 4)|(PGA << 1)|(MODE)
		ADS1015_WriteReg(REG_config,config_MSB,config_LSB);Delay_ms(100);
		Channel_3_voltage = ADS1015_GetVoltage();

		OLED_ShowString(1,1,"Channel0:");OLED_ShowSignedNum(1,10,Channel_0_voltage,4);OLED_ShowString(1,15,"mV");
		OLED_ShowString(2,1,"Channel1:");OLED_ShowSignedNum(2,10,Channel_1_voltage,4);OLED_ShowString(2,15,"mV");
		OLED_ShowString(3,1,"Channel2:");OLED_ShowSignedNum(3,10,Channel_2_voltage,4);OLED_ShowString(3,15,"mV");
		OLED_ShowString(4,1,"Channel3:");OLED_ShowSignedNum(4,10,Channel_3_voltage,4);OLED_ShowString(4,15,"mV");

		Delay_ms(500);
	}
}

六、实验现象

----------------------------------------------------OLED接线------------------------------------------------------
SCL-----PB8
SDA-----PB9
--------------------------------------------------ADS1015接线--------------------------------------------------
SCL-----PB10
SDA-----PB11

1.单端模式

main 里调用 SingleVoltage_Show(); 函数
AIN0 分别输入 1.8V 3.3V 5V

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

2.差分模式

差分模式在单端模式基础改一下 ADS1015.h 头文件中的 MUX 字段,修改输入通道模式即可
#define MUX 0x00 // AINP = AIN0 and AINN = AIN1 通道 0 1 差分输入

AIN 0 与 AIN 1 通道分别输入 1.8V 或者 3.3V ,显示压差 ± 1490

在这里插入图片描述
在这里插入图片描述

3.伪多通道模式

ADS1015只有一个ADC,不能真正同时多通道输入,采用时分复用方法,配置多个通道快速分时采集

main 里调用 MultipleChannels_Show(); 函数 ,注意 SingleVoltage_Show(); 需注释掉
四个通道 AIN 01234 分别输入 0V 1.8V 3.3V 5V

在这里插入图片描述

以上内容个人理解,如有不正欢迎指正,需要资料及工程可留言邮箱