STM32 软件IIC ADS1115 的使用

在嵌入式数据采集领域,精准的模拟信号转换是核心需求之一。无论是物联网设备的环境监测、工业控制系统的参数采集,还是医疗仪器的生理信号检测,都需要一款性能可靠、易于集成的模数转换器(ADC)。德州仪器(TI)推出的ADS1115,凭借16位高精度、低功耗、多通道灵活配置等优势,成为中小规模数据采集项目的首选方案。

一、ADS1115核心特性概览

ADS1115是一款基于I²C接口的高精度低功耗ADC,相较于传统8位、10位ADC,它在性能和灵活性上实现了显著提升,关键特性如下:

  • 高精度分辨率:16位转换精度,相较于常见的12位ADC,数据采集精度提升4倍,可捕捉微弱电压变化,最小量化单位低至0.1875mV(对应±6.144V量程)。

  • 灵活输入配置:提供4个模拟输入通道(AIN0-AIN3),支持单端输入和差分输入两种模式,差分模式可有效抑制共模噪声,适配复杂场景测量。

  • 可编程增益放大器(PGA):内置PGA,增益范围可在±2/3倍至±16倍之间调节,对应输入量程为±6.144V至±0.256V,能根据信号幅度匹配最佳量程,提升信噪比。

  • 低功耗设计:单次转换模式下功耗仅20μA,待机电流极低,非常适合电池供电的便携式设备和物联网终端。

  • 多工作模式与速率:支持连续转换和单次转换模式,采样速率可在8SPS至860SPS之间编程配置,平衡采集速度与功耗需求。

  • I²C接口与地址扩展:通过ADDR引脚可配置4个不同的I²C从机地址(0x48-0x4B),支持多模块级联,满足多通道扩展需求。

  • 内置比较器:配备可编程数字比较器,可通过ALERT/RDY引脚输出中断信号,实现阈值触发功能,减少主机轮询开销。

二丶原理图

引脚名称 类型 功能描述
VDD 电源 供电电压2.0V-5.5V,建议接3.3V或5V(与控制器一致)
GND 与控制器共地,确保电位一致
SCL I²C时钟 PB8 使用软件IIC
SDA I²C数据 PB9 使用软件IIC
ADDR 地址选择 默认接GND
ALERT/RDY 中断输出 转换完成或阈值触发时输出信号,可悬空(不使用中断功能)
AIN0-AIN3 模拟输入 连接模拟信号源,单端模式接传感器输出,差分模式接两信号端

三.代码实现

myiic.h

cpp 复制代码
#ifndef __MYIIC_H
#define __MYIIC_H
#include "sys.h"

//IO方向设置
// 
//#define SDA_IN()  {GPIOL->CRH&=0XFF0FFFFF;GPIOA->CRL|=(u32)8<<12;}    //PA5
//#define SDA_OUT() {GPIOL->CRH&=0XFF0FFFFF;GPIOA->CRL|=(u32)3<<12;}
 

//IO操作函数	 
#define IIC_SCL    PBout(8) //SCL
#define IIC_SDA    PBout(9) //SDA	 
#define READ_SDA   PBin(9)  //输入SDA 

//IIC所有操作函数
void IIC_Init(void);                //初始化IIC的IO口				 
void IIC_Start(void);				//发送IIC开始信号
void IIC_Stop(void);	  			//发送IIC停止信号
void IIC_Send_Byte(u8 txd);			//IIC发送一个字节
u8 IIC_Read_Byte(unsigned char ack);//IIC读取一个字节
u8 IIC_Wait_Ack(void); 				//IIC等待ACK信号
void IIC_Ack(void);			        //IIC发送ACK信号
void IIC_NAck(void);				//IIC不发送ACK信号

void SDA_IN(void);
void SDA_OUT(void);

void IIC_Write_One_Byte(u8 daddr,u8 addr,u8 data);
u8 IIC_Read_One_Byte(u8 daddr,u8 addr);	  
#endif

myiic.c

cpp 复制代码
#include "myiic.h"
#include "delay.h"

//初始化IIC
void IIC_Init(void)
{					     
	GPIO_InitTypeDef GPIO_InitStructure;
	RCC_APB2PeriphClockCmd(	RCC_APB2Periph_GPIOB, ENABLE );	//使能GPIOB时钟
	   
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_9;         //PB8 ->SCL;  PB9->SDA
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ;   //推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
	GPIO_SetBits(GPIOB,GPIO_Pin_8|GPIO_Pin_9); 	//PB8,PB9 输出高,因为IIC空闲状态都是高电平
}

//SDA设置为输入
void SDA_IN (void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    RCC_APB2PeriphClockCmd(	RCC_APB2Periph_GPIOB, ENABLE );	
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; 
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; 
    GPIO_Init(GPIOB, &GPIO_InitStructure);
}

//SDA设置为输出
void SDA_OUT(void)
{ 
	GPIO_InitTypeDef GPIO_InitStructure;
    RCC_APB2PeriphClockCmd(	RCC_APB2Periph_GPIOB, ENABLE );	
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; 
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ; 
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
}
//产生IIC起始信号
void IIC_Start(void)
{
	SDA_OUT();     //sda线设置为输出
	IIC_SDA=1;	  	  
	IIC_SCL=1;
	delay_us(10);
 	IIC_SDA=0;     //START:when CLK is high,DATA change form high to low 
	delay_us(10);
	IIC_SCL=0;     //钳住I2C总线,准备发送或接收数据 
}	  
//产生IIC停止信号
void IIC_Stop(void)
{
	SDA_OUT();//sda线输出
	IIC_SCL=0;
	IIC_SDA=0;//STOP:when CLK is high DATA change form low to high
 	delay_us(10);
	IIC_SCL=1; 
	IIC_SDA=1;//发送I2C总线结束信号
	delay_us(10);							   	
}
//等待应答信号到来
//返回值:1,接收应答失败
//        0,接收应答成功
u8 IIC_Wait_Ack(void)
{
	u8 ucErrTime=0;
	SDA_IN();      //SDA设置为输入  
	IIC_SDA=1;delay_us(2);	   
	IIC_SCL=1;delay_us(2);	 
	while(READ_SDA)
	{
		ucErrTime++;
		if(ucErrTime>250)
		{
			IIC_Stop();
			return 1;
		}
	}
	IIC_SCL=0;//时钟输出0 	   
	return 0;  
} 
//产生ACK应答
void IIC_Ack(void)
{
	IIC_SCL=0;
	SDA_OUT();
	IIC_SDA=0;
	delay_us(5);
	IIC_SCL=1;
	delay_us(5);
	IIC_SCL=0;
}
//不产生ACK应答		    
void IIC_NAck(void)
{
	IIC_SCL=0;
	SDA_OUT();
	IIC_SDA=1;
	delay_us(5);
	IIC_SCL=1;
	delay_us(5);
	IIC_SCL=0;
}					 				     
//IIC发送一个字节
//返回从机有无应答
//1,有应答
//0,无应答			  
void IIC_Send_Byte(u8 txd)
{                        
    u8 t;   
	SDA_OUT(); 	    
    IIC_SCL=0;//拉低时钟开始数据传输
    for(t=0;t<8;t++)    //开始准备信号线
    {              
        //IIC_SDA=(txd&0x80)>>7;
		if((txd&0x80)>>7)
			IIC_SDA=1;
		else
			IIC_SDA=0;
		txd<<=1; 	  
		delay_us(5);   //对TEA5767这三个延时都是必须的
		IIC_SCL=1;
		delay_us(5); 
		IIC_SCL=0;	
		delay_us(5);
    }	 
} 	    
//读1个字节,ack=1时,发送ACK,ack=0,发送nACK   
u8 IIC_Read_Byte(unsigned char ack)
{
	unsigned char i,receive=0;
	SDA_IN();//SDA设置为输入
    for(i=0;i<8;i++ )
	{
        IIC_SCL=0; 
        delay_us(5);
		IIC_SCL=1;
        receive<<=1;
        if(READ_SDA)receive++;   
		delay_us(4); 
    }					 
    if (!ack)
        IIC_NAck();//发送nACK
    else
        IIC_Ack(); //发送ACK   
    return receive;
}

ADS1115.H

cpp 复制代码
#ifndef __ADS1115_H
#define __ADS1115_H

#include "myiic.h"
#include "sys.h"

//ADS1115 I2C地址定义
#define ADS1115_ADDR_WRITE  0x90  //写地址
#define ADS1115_ADDR_READ   0x91  //读地址

//寄存器地址定义
#define ADS1115_REG_CONVERSION  0x00  //转换寄存器
#define ADS1115_REG_CONFIG      0x01  //配置寄存器

//通道选择定义(MUX位配置)
#define ADS1115_MUX_AIN0_AIN1   0x00  //AIN0和AIN1差分输入
#define ADS1115_MUX_AIN0_AIN3   0x10  //AIN0和AIN3差分输入
#define ADS1115_MUX_AIN1_AIN3   0x20  //AIN1和AIN3差分输入
#define ADS1115_MUX_AIN2_AIN3   0x30  //AIN2和AIN3差分输入
#define ADS1115_MUX_AIN0_GND    0x40  //AIN0单端输入(相对于GND)
#define ADS1115_MUX_AIN1_GND    0x50  //AIN1单端输入(相对于GND)
#define ADS1115_MUX_AIN2_GND    0x60  //AIN2单端输入(相对于GND)
#define ADS1115_MUX_AIN3_GND    0x70  //AIN3单端输入(相对于GND)

//PGA增益定义
#define ADS1115_PGA_6144        0x00  //±6.144V
#define ADS1115_PGA_4096        0x02  //±4.096V
#define ADS1115_PGA_2048        0x04  //±2.048V
#define ADS1115_PGA_1024        0x06  //±1.024V
#define ADS1115_PGA_0512        0x08  //±0.512V
#define ADS1115_PGA_0256        0x0A  //±0.256V

//函数声明
void ADS1115_GPIO_Init(void);
uint8_t WriteADS1115(uint8_t add, uint8_t dat_H, uint8_t dat_L);
float ReadADS1115(unsigned char add);  //读取ADC值并转换为电压(自动读取配置寄存器获取PGA)
float ReadADS1115_WithPGA(unsigned char add, u8 pga);  //读取ADC值并转换为电压(指定PGA)
u8 ADS1115_ReadConfig(void);  //读取配置寄存器,返回高字节
u8 ADS1115_GetPGA(void);  //从配置寄存器获取当前PGA设置
u8 ADS1115_Check(void);  //检测ADS1115是否初始化成功,返回1表示成功,0表示失败

//通道电压读取函数
void ADS1115_SetChannel(u8 channel, u8 pga);  //设置采集通道和PGA增益
float ADS1115_ReadChannel_A0(u8 pga);  //读取A0通道电压(相对于GND),pga-PGA增益选择(使用ADS1115_PGA_xxx宏定义)
float ADS1115_ReadChannel_A1(u8 pga);  //读取A1通道电压(相对于GND),pga-PGA增益选择(使用ADS1115_PGA_xxx宏定义)

//校准功能
void ADS1115_SetCalibration(float cal_factor);  //设置校准系数,cal_factor=实际值/测量值,例如:5.0/4.971=1.0058
float ADS1115_GetCalibration(void);  //获取当前校准系数

//电压和电流测量函数
float ADS1115_ReadVoltage(u8 channel, u8 pga);  //读取电压,channel:通道(ADS1115_MUX_AIN0_GND等),pga:PGA设置
float ADS1115_ReadCurrent_Shunt(float voltage, float shunt_resistor);  //通过分流电阻计算电流(I=V/R)
float ADS1115_ReadCurrent_Ratio(float voltage, float voltage_ratio);  //通过电压比例计算电流(I=V/ratio),适用于霍尔传感器

#endif

ADS1115.C

cpp 复制代码
#include "ads1115.h"
#include "delay.h"

/******************************************************************
 * 函 数 名 称:ADS1115_GPIO_Init
 * 函 数 说 明:对IIC引脚初始化(使用PB8/PB9,与MCP4725和OLED共用I2C总线)
 * 函 数 形 参:无
 * 函 数 返 回:无
 * 作       者:LC 
 * 备       注:配置参数 0x01寄存器写入0xC2,0x83
 *             配置说明:0xC2=1100_0010 (MUX=AIN0-AIN1, PGA=±2.048V, 连续转换模式)
 *                      0x83=1000_0011 (DR=128SPS, 传统比较器, 低电平有效, 非锁存)
******************************************************************/
void ADS1115_GPIO_Init(void)
{                                
	IIC_Init();  //初始化IIC接口(PB8/PB9)
	delay_ms(10);  //等待IIC稳定
	//写入配置参数            
	WriteADS1115(ADS1115_REG_CONFIG, 0xC2, 0x83);
	delay_ms(10);
}
 
/******************************************************************
 * 函 数 名 称:WriteADS1115
 * 函 数 说 明:向ADS1115的add地址写入dat数据
 * 函 数 形 参:add写入寄存器地址 dat_H写入的高8位数据  dat_L写入的低8位数据
 * 函 数 返 回:0写入成功 1写入器件地址无应答  2写入寄存器地址无应答 
 *              3写入高8位数据无应答  4写入低8位数据无应答
 * 作       者:LC
 * 备       注:器件地址=0X90 (写地址)
******************************************************************/
uint8_t WriteADS1115(uint8_t add, uint8_t dat_H, uint8_t dat_L)
{
	IIC_Start();
	IIC_Send_Byte(ADS1115_ADDR_WRITE);  //发送写地址
	if(IIC_Wait_Ack() == 1)
	{      
		return 1;  //器件地址无应答
	}
	
	IIC_Send_Byte(add);  //发送寄存器地址
	if(IIC_Wait_Ack() == 1) 
	{
		return 2;  //寄存器地址无应答
	}
	
	IIC_Send_Byte(dat_H);  //发送高8位数据
	if(IIC_Wait_Ack() == 1)
	{
		return 3;  //高8位数据无应答
	}
	
	IIC_Send_Byte(dat_L);  //发送低8位数据
	if(IIC_Wait_Ack() == 1)
	{
		return 4;  //低8位数据无应答
	}
	
	IIC_Stop();
	delay_ms(1);  //等待写入完成
	return 0;  //写入成功
}
 
/******************************************************************
 * 函 数 名 称:ADS1115_ReadConfig
 * 函 数 说 明:读取ADS1115的配置寄存器
 * 函 数 形 参:无
 * 函 数 返 回:配置寄存器高字节,-1表示读取失败
 * 作       者:LC
 * 备       注:用于获取当前的PGA设置
******************************************************************/
u8 ADS1115_ReadConfig(void)
{
	int i = 0;
	unsigned char dat[2] = {0};
	
	//发送起始信号和写地址
	IIC_Start();
	IIC_Send_Byte(ADS1115_ADDR_WRITE);  //器件地址+写
	if(IIC_Wait_Ack() == 1) 
		return 0xFF;  //器件地址无应答
	
	//发送配置寄存器地址
	IIC_Send_Byte(ADS1115_REG_CONFIG);  //寄存器地址
	if(IIC_Wait_Ack() == 1) 
		return 0xFF;  //寄存器地址无应答
	
	//重新发送起始信号,切换到读模式
	do{
		//超时判断
		i++;
		if(i > 20) 
			return 0xFF;  //超时
		delay_ms(1);
		IIC_Start();  //重新发送起始信号
		IIC_Send_Byte(ADS1115_ADDR_READ);  //器件地址+读
	}while(IIC_Wait_Ack() == 1);  //等待应答,如果失败则重试
    
	//读取高8位数据(ack=1表示发送ACK,继续读取)
	dat[0] = IIC_Read_Byte(1);  //读高8位数据,发送ACK
	
	//读取低8位数据(ack=0表示发送nACK,最后一个字节)
	dat[1] = IIC_Read_Byte(0);  //读低8位数据,发送nACK
	
	IIC_Stop();  //发送停止信号
	
	return dat[0];  //返回配置寄存器高字节
}

/******************************************************************
 * 函 数 名 称:ADS1115_GetPGA
 * 函 数 说 明:从配置寄存器获取当前PGA设置
 * 函 数 形 参:无
 * 函 数 返 回:PGA设置值(使用ADS1115_PGA_xxx宏定义),0xFF表示读取失败
 * 作       者:LC
 * 备       注:从配置寄存器高字节中提取PGA位(bit 11-9)
******************************************************************/
u8 ADS1115_GetPGA(void)
{
	u8 config_H;
	
	config_H = ADS1115_ReadConfig();
	if(config_H == 0xFF)
		return 0xFF;  //读取失败
	
	//提取PGA位(bit 11-9),PGA在bit 11-9位置
	//PGA位:bit 11-9,需要与0x0E进行与操作,然后右移1位
	return (config_H & 0x0E);  //返回PGA设置值
}

/******************************************************************
 * 函 数 名 称:ReadADS1115_WithPGA
 * 函 数 说 明:读取ADS1115的数据并转换为电压(指定PGA)
 * 函 数 形 参:add-读取的寄存器地址,pga-PGA增益选择(使用ADS1115_PGA_xxx宏定义)
 * 函 数 返 回:-1-读取失败  其他-读取成功(电压值,单位V)
 * 作       者:LC
 * 备       注:根据指定的PGA计算正确的电压值
 *             不同PGA对应的量程和分辨率:
 *             PGA_6144: ±6.144V, 分辨率=0.0001875V
 *             PGA_4096: ±4.096V, 分辨率=0.000125V
 *             PGA_2048: ±2.048V, 分辨率=0.0000625V
 *             PGA_1024: ±1.024V, 分辨率=0.00003125V
 *             PGA_0512: ±0.512V, 分辨率=0.000015625V
 *             PGA_0256: ±0.256V, 分辨率=0.0000078125V
******************************************************************/
float ReadADS1115_WithPGA(unsigned char add, u8 pga)
{
	int i = 0;
	unsigned char dat[2] = {0};
	unsigned int num = 0;
	float ret = 0;
	float resolution = 0;  //分辨率(V/LSB)
	
	//发送起始信号和写地址
	IIC_Start();
	IIC_Send_Byte(ADS1115_ADDR_WRITE);  //器件地址+写
	if(IIC_Wait_Ack() == 1) 
		return -1;  //器件地址无应答
	
	//发送寄存器地址
	IIC_Send_Byte(add);  //寄存器地址
	if(IIC_Wait_Ack() == 1) 
		return -1;  //寄存器地址无应答
	
	//重新发送起始信号,切换到读模式
	do{
		//超时判断
		i++;
		if(i > 20) 
			return -1;  //超时
		delay_ms(1);
		IIC_Start();  //重新发送起始信号
		IIC_Send_Byte(ADS1115_ADDR_READ);  //器件地址+读
	}while(IIC_Wait_Ack() == 1);  //等待应答,如果失败则重试
    
	//读取高8位数据(ack=1表示发送ACK,继续读取)
	dat[0] = IIC_Read_Byte(1);  //读高8位数据,发送ACK
	
	//读取低8位数据(ack=0表示发送nACK,最后一个字节)
	dat[1] = IIC_Read_Byte(0);  //读低8位数据,发送nACK
	
	IIC_Stop();  //发送停止信号
	
	//数据整合:高8位左移8位后与低8位合并
	num = ((dat[0] << 8) | (dat[1])); 
	
	//根据PGA设置计算分辨率
	switch(pga)
	{
		case ADS1115_PGA_6144:  //±6.144V
			resolution = 6.144f / 32768.0f;  //0.0001875V
			break;
		case ADS1115_PGA_4096:  //±4.096V
			resolution = 4.096f / 32768.0f;  //0.000125V
			break;
		case ADS1115_PGA_2048:  //±2.048V
			resolution = 2.048f / 32768.0f;  //0.0000625V
			break;
		case ADS1115_PGA_1024:  //±1.024V
			resolution = 1.024f / 32768.0f;  //0.00003125V
			break;
		case ADS1115_PGA_0512:  //±0.512V
			resolution = 0.512f / 32768.0f;  //0.000015625V
			break;
		case ADS1115_PGA_0256:  //±0.256V
			resolution = 0.256f / 32768.0f;  //0.0000078125V
			break;
		default:
			resolution = 2.048f / 32768.0f;  //默认使用±2.048V
			break;
	}
	
	//数值计算:根据分辨率计算电压
	//如果数值大于32768,说明是负数(补码表示)
	if(num > 32768)
		ret = (65535 - num) * resolution;  //负数处理
	else
		ret = num * resolution;  //正数处理
   
	return ret;  //返回电压值(单位:V)
}

/******************************************************************
 * 函 数 名 称:ReadADS1115
 * 函 数 说 明:读取ADS1115的数据并转换为电压(自动读取配置寄存器获取PGA)
 * 函 数 形 参:add读取的寄存器地址
 * 函 数 返 回:-1-读取失败  其他-读取成功(电压值,单位V)
 * 作       者:LC
 * 备       注:自动从配置寄存器读取当前PGA设置,然后计算正确的电压值
******************************************************************/
float ReadADS1115(unsigned char add)
{
	u8 pga;
	
	//获取当前PGA设置
	pga = ADS1115_GetPGA();
	if(pga == 0xFF)
		return -1;  //读取配置寄存器失败
	
	//使用带PGA参数的函数读取电压
	return ReadADS1115_WithPGA(add, pga);
}

/******************************************************************
 * 函 数 名 称:ADS1115_Check
 * 函 数 说 明:检测ADS1115是否初始化成功
 * 函 数 形 参:无
 * 函 数 返 回:1表示成功,0表示失败
 * 作       者:LC
 * 备       注:通过发送器件地址检测设备是否存在
******************************************************************/
u8 ADS1115_Check(void)
{
	u8 ack_status;
	IIC_Start();
	IIC_Send_Byte(ADS1115_ADDR_WRITE);  //发送ADS1115写地址
	ack_status = IIC_Wait_Ack();  //等待应答,返回0表示成功,1表示失败
	IIC_Stop();
	delay_ms(1);
	
	if(ack_status == 0)  //收到ACK,设备存在
		return 1;
	else  //未收到ACK,设备不存在或通信失败
		return 0;
}

/******************************************************************
 * 函 数 名 称:ADS1115_SetChannel
 * 函 数 说 明:设置ADS1115的采集通道和PGA增益
 * 函 数 形 参:channel-通道选择(使用ADS1115_MUX_xxx宏定义)
 *            pga-PGA增益选择(使用ADS1115_PGA_xxx宏定义)
 * 函 数 返 回:无
 * 作       者:LC
 * 备       注:配置寄存器格式:高字节=OS(1位) + MUX(3位) + PGA(3位) + MODE(1位)
 *             低字节=DR(3位) + COMP_MODE(1位) + COMP_POL(1位) + COMP_LAT(1位) + COMP_QUE(2位)
******************************************************************/
void ADS1115_SetChannel(u8 channel, u8 pga)
{
	u8 config_H, config_L;
	
	//配置高字节:OS=1(单次转换) + MUX + PGA + MODE=0(单次转换模式)
	config_H = 0x80 | channel | pga;
	
	//配置低字节:DR=100(128SPS) + COMP_MODE=0 + COMP_POL=0 + COMP_LAT=0 + COMP_QUE=11(禁用比较器)
	config_L = 0x83;
	
	WriteADS1115(ADS1115_REG_CONFIG, config_H, config_L);
	delay_ms(10);  //等待转换完成
}

/******************************************************************
 * 函 数 名 称:ADS1115_ReadChannel_A0
 * 函 数 说 明:读取A0通道的电压(相对于GND)
 * 函 数 形 参:pga-PGA增益选择(使用ADS1115_PGA_xxx宏定义)
 * 函 数 返 回:电压值(单位:V),-1表示读取失败
 * 作       者:LC
 * 备       注:单端输入模式,根据传入的PGA设置量程
******************************************************************/
float ADS1115_ReadChannel_A0(u8 pga)
{
	//设置A0单端输入,使用传入的PGA设置
	ADS1115_SetChannel(ADS1115_MUX_AIN0_GND, pga); 
	delay_ms(10);  //等待转换完成
	//使用指定的PGA计算电压,确保精度
	return ReadADS1115_WithPGA(ADS1115_REG_CONVERSION, pga);
}

/******************************************************************
 * 函 数 名 称:ADS1115_ReadChannel_A1
 * 函 数 说 明:读取A1通道的电压(相对于GND)
 * 函 数 形 参:pga-PGA增益选择(使用ADS1115_PGA_xxx宏定义)
 * 函 数 返 回:电压值(单位:V),-1表示读取失败
 * 作       者:LC
 * 备       注:单端输入模式,根据传入的PGA设置量程
******************************************************************/
float ADS1115_ReadChannel_A1(u8 pga)
{
	//设置A1单端输入,使用传入的PGA设置
	ADS1115_SetChannel(ADS1115_MUX_AIN1_GND, pga);
	delay_ms(10);  //等待转换完成
	//使用指定的PGA计算电压,确保精度
	return ReadADS1115_WithPGA(ADS1115_REG_CONVERSION, pga);
}

/******************************************************************
 * 函 数 名 称:ADS1115_ReadVoltage
 * 函 数 说 明:读取指定通道的电压
 * 函 数 形 参:channel-通道选择(使用ADS1115_MUX_AIN0_GND等),pga-PGA增益选择
 * 函 数 返 回:电压值(单位:V),-1表示读取失败
 * 作       者:LC
 * 备       注:通用电压读取函数
******************************************************************/
float ADS1115_ReadVoltage(u8 channel, u8 pga)
{
	//设置指定通道,使用传入的PGA设置
	ADS1115_SetChannel(channel, pga);
	delay_ms(10);  //等待转换完成
	//使用指定的PGA计算电压,确保精度
	return ReadADS1115_WithPGA(ADS1115_REG_CONVERSION, pga);
}

/******************************************************************
 * 函 数 名 称:ADS1115_ReadCurrent_Shunt
 * 函 数 说 明:通过分流电阻计算电流(欧姆定律:I = V / R)
 * 函 数 形 参:voltage-测量的电压值(单位:V),shunt_resistor-分流电阻值(单位:欧姆)
 * 函 数 返 回:电流值(单位:A),-1表示参数无效
 * 作       者:LC
 * 备       注:适用于使用分流电阻测量电流的场景
******************************************************************/
float ADS1115_ReadCurrent_Shunt(float voltage, float shunt_resistor)
{
	if(voltage < 0)  //电压值无效
		return -1;
	
	if(shunt_resistor <= 0)  //分流电阻值无效
		return -1;
	
	//根据欧姆定律计算电流:I = V / R
	return voltage / shunt_resistor;
}

/******************************************************************
 * 函 数 名 称:ADS1115_ReadCurrent_Ratio
 * 函 数 说 明:通过电压比例计算电流(适用于霍尔电流传感器等)
 * 函 数 形 参:voltage-测量的电压值(单位:V),voltage_ratio-电压与电流的转换比例(单位:V/A)
 * 函 数 返 回:电流值(单位:A),-1表示参数无效
 * 作       者:LC
 * 备       注:适用于霍尔电流传感器,通常有固定的转换比例
******************************************************************/
float ADS1115_ReadCurrent_Ratio(float voltage, float voltage_ratio)
{
	if(voltage < 0)  //电压值无效
		return -1;
	
	if(voltage_ratio <= 0)  //转换比例无效
		return -1;
	
	//根据转换比例计算电流:I = V / ratio
	return voltage / voltage_ratio;
}

main.C

cpp 复制代码
//初始化
ADS1115_GPIO_Init();  //初始化ADS1115
delay_ms(10);  //等待IIC稳定
ads1115_status = ADS1115_Check();  //检测ADS1115初始化状态


//获取数据 PGA 使用对应的宏定义
//#define ADS1115_PGA_6144        0x00  //±6.144V
//#define ADS1115_PGA_4096        0x02  //±4.096V
//#define ADS1115_PGA_2048        0x04  //±2.048V
//#define ADS1115_PGA_1024        0x06  //±1.024V
//#define ADS1115_PGA_0512        0x08  //±0.512V
//#define ADS1115_PGA_0256        0x0A  //±0.256V
ads1115_voltage_A0 = ADS1115_ReadChannel_A0(PGA);
delay_ms(20);  //等待转换完成
ads1115_voltage_A1 = ADS1115_ReadChannel_A1(PGA);
delay_ms(20);  //等待转换完成

OLED_ShowCH(0,2,"A0V:");
OLED_Showdecimal(64, 2, ads1115_voltage_A0, 2, 3, 16);
OLED_ShowCH(112, 2, "V");
OLED_ShowCH(0,4,"A1V:");
OLED_Showdecimal(64, 4, ads1115_voltage_A1, 2, 3, 16);
OLED_ShowCH(112, 4, "V");
相关推荐
Y1rong17 小时前
STM32之中断
stm32·单片机·嵌入式硬件
三佛科技-1341638421217 小时前
PL3327CE/PL3327CD/CS/CF原边调节恒流/恒压控制离线反激式开关电源芯片 典型应用电路
单片机·嵌入式硬件·物联网·智能家居
brave and determined17 小时前
工程设计类学习(DAY4):硬件可靠性测试全攻略:标准到实战
人工智能·嵌入式硬件·测试·硬件设计·可靠性测试·嵌入式设计·可靠性方法
先知后行。18 小时前
STM32F103的启动过程
stm32·单片机·嵌入式硬件
无畏jh18 小时前
TLE5012B磁阻芯片解读
嵌入式硬件·汽车嵌入式·磁阻芯片
培林将军18 小时前
Altium Designer 22的安装与汉化
嵌入式硬件·ad工具安装
idcardwang18 小时前
xl9555-IO拓展芯片
stm32·单片机·嵌入式硬件
Y1rong19 小时前
STM32之EXTI
stm32·单片机·嵌入式硬件
兆龙电子单片机设计19 小时前
【STM32项目开源】STM32单片机智能语音家居控制系统
stm32·单片机·嵌入式硬件·物联网·开源·自动化