CubeMX的IIC配置
时钟串口见之前文章;IIC配置只需修改IIC时钟频率,ADS115频率范围如下。
.h文件
#ifndef __ADS1115_H__
#define __ADS1115_H__
#include "main.h"
//#ifdef ADS1115
extern I2C_HandleTypeDef hi2c1;
//#define ADS1115_MAX_CHANNEL 4
#define Accuracy 32768 //ADC单端输入15位精度
//#define ADS1115_ADDRESS_GND 0x90 //ADDR PIN ->GND SLAVE ADDRESS 01001000 发送时要左移1
//#define ADS1115_ADDRESS_VDD 0x92 //ADDR PIN ->VDD
//#define ADS1115_ADDRESS_SDA 0x94 //ADDR PIN ->SDA
//#define ADS1115_ADDRESS_SCL 0x96 //ADDR PIN ->SCL
//*************ADDR Initial********************/
//#define ADS1115_ADDRESS ADS1115_ADDRESS_GND //ADDR PIN ->GND
#define ADS1115_ADDRESS_W ADS1115_ADDRESS|0x00 //write address
#define ADS1115_ADDRESS_R ADS1115_ADDRESS|0x01 //read address
/************POINTER REGISTER*****************/
#define ADS1115_Pointer_ConverReg 0x00 //Convertion register
#define ADS1115_Pointer_ConfigReg 0x01 //Config register
#define ADS1115_Pointer_LoThreshReg 0x02 //Lo_thresh register
#define ADS1115_Pointer_HiThreshReg 0x03 //Hi_thresh register
/************CONFIG REGISTER*****************/
//Bit[15]
#define ADS1115_OS_OperationalStatus 0x0000 //No Effect
#define ADS1115_OS_SingleConverStart 0x8000 //Begin a single conversion
//Bits[14:12]
#define ADS1115_MUX_Differ_01 0x0000 //AINp=AIN0, AINn=AIN1(default)
#define ADS1115_MUX_Differ_03 0x1000 //AINp=AIN0, AINn=AIN3
#define ADS1115_MUX_Differ_13 0x2000 //AINp=AIN1, AINn=AIN3
#define ADS1115_MUX_Differ_23 0x3000 //AINp=AIN2, AINn=AIN3
#define ADS1115_MUX_Channel_0 0x4000 //AINp=AIN0, AINn=GND
#define ADS1115_MUX_Channel_1 0x5000 //AINp=AIN1, AINn=GND
#define ADS1115_MUX_Channel_2 0x6000 //AINp=AIN2, AINn=GND
#define ADS1115_MUX_Channel_3 0x7000 //AINp=AIN3, AINn=GND
//Bits[11:9]
#define ADS1115_PGA_6144 0x0000 //FS=6.144V
#define ADS1115_PGA_4096 0x0200 //FS=4.096V
#define ADS1115_PGA_2048 0x0400 //FS=2.048V(default)
#define ADS1115_PGA_1024 0x0600 //FS=1.024V
#define ADS1115_PGA_0512 0x0800 //FS=0.512V
#define ADS1115_PGA_0256 0x0A00 //FS=0.256V
//Bit[8]
#define ADS1115_MODE_ContinuConver 0x0000 //Continuous conversion mode
#define ADS1115_MODE_SingleConver 0x0100 //Power-down single-shot mode(default)
//Bits[7:5]
#define ADS1115_DataRate_8 0x0000 //Data Rate = 8
#define ADS1115_DataRate_16 0x0020 //Data Rate = 16
#define ADS1115_DataRate_32 0x0040 //Data Rate = 32
#define ADS1115_DataRate_64 0x0060 //Data Rate = 64
#define ADS1115_DataRate_128 0x0080 //Data Rate = 128(default)
#define ADS1115_DataRate_250 0x00A0 //Data Rate = 250
#define ADS1115_DataRate_475 0x00C0 //Data Rate = 475
#define ADS1115_DataRate_860 0x00E0 //Data Rate = 860
//Bit[4]
#define ADS1115_COMP_MODE_0 0x0000 //Traditional comparator with hysteresis
#define ADS1115_COMP_MODE_1 0x0010 //Window comparator
//Bit[3]
#define ADS1115_COMP_POL_0 0x0000 //Active low
#define ADS1115_COMP_POL_1 0x0008 //Active high
//Bit[2]
#define ADS1115_COMP_LAT_0 0x0000 //Non-latching comparator
#define ADS1115_COMP_LAT_1 0x0004 //Latching comparator
//Bits[1:0]
#define ADS1115_COMP_QUE_0 0x0000 //Assert after one conversion
#define ADS1115_COMP_QUE_1 0x0001 //Assert after two conversion
#define ADS1115_COMP_QUE_2 0x0002 //Assert after four conversion
#define ADS1115_COMP_QUE_3 0x0003 //Disable Comparator
typedef enum
{
ADS1115_ADDRESS_GND = 0x90, //LAVE ADDRESS 01001000 发送时要左移1
ADS1115_ADDRESS_VDD = 0x92, //ADDR PIN ->VDD
ADS1115_ADDRESS_SDA = 0x94, //ADDR PIN ->SDA
ADS1115_ADDRESS_SCL = 0x96 //ADDR PIN ->SCL
}ADS1115_ADDRESS;
typedef enum
{
ADS1115_CHANNEL0 = 0U, //ADC通道0 rank 1
ADS1115_CHANNEL1, //通道 1
ADS1115_CHANNEL2, //通道 2
ADS1115_CHANNEL3, //通道 3
ADS1115_MAX_CHANNEL
}ADS1115_CHANNEL;
typedef struct
{
//芯片寄存器设置
uint16_t OS;
uint16_t MUX;
uint16_t PGA;
uint16_t MODE;
uint16_t DataRate;
uint16_t COMP_MODE;
uint16_t COMP_POL;
uint16_t COMP_LAT;
uint16_t COMP_QUE;
//
//编程用
ADS1115_CHANNEL CHANNEL;
ADS1115_ADDRESS ADDRESS;
int16_t ADS1115_RawData[4];
float ADS1115_Vol[4];
} ADS1115_InitTypeDefine;
//extern int16_t ADS1115_RawData[4];
//extern float ADS1115_CHn_Vol[4];
void ADS1115_Init(void);
void ADS1115_UserConfig_SingleConver(ADS1115_InitTypeDefine* hADS1115 , ADS1115_ADDRESS ADDRESS);
void ADS1115_UserConfig_ContinuConver(ADS1115_InitTypeDefine* ADS1115_InitStruct,ADS1115_ADDRESS ADDRESS);
void ADS1115_Config(ADS1115_InitTypeDefine* ADS1115_InitStruct);
void ADS1115_ReadRawData(ADS1115_InitTypeDefine *ADS1115_InitStruct);
void ADS1115_ScanChannel(ADS1115_InitTypeDefine *ADS1115_InitStruct);
void ADS1115_RawDataToVoltage(ADS1115_InitTypeDefine *ADS1115_InitStruct);
void ADS1115_GetVoltage(ADS1115_InitTypeDefine *ADS1115_InitStruct);
void ADS1115_GetAverageVoltage(ADS1115_InitTypeDefine *ADS1115_InitStruct);
void ADS1115_RefreshAllChannel(ADS1115_InitTypeDefine *ADS1115_InitStruct);
extern ADS1115_InitTypeDefine ADS1115_ADDR_VDD;
extern ADS1115_InitTypeDefine ADS1115_ADDR_GND;
#endif
.c文件
#include "ads1115.h"
//#ifdef ADS1115
ADS1115_InitTypeDefine ADS1115_ADDR_GND;
ADS1115_InitTypeDefine ADS1115_ADDR_VDD;
float ADS1115_CHn_Vol[4];
/**
* 可供外部调用的全局变量,记录了ADS1115采样的原始16位数据。调用void ADS1115_RefreshAllChannel( )函数可以刷新这个变量。
* 通过定义宏ADS1115_USE_FILTER,可以将ADS1115的轮询采样数据经过滑动滤波后,保存到ADS1115_RawData[]中。
* 通过float ADS1115_RawDataToVoltage(int16_t rawData)函数可以将ADS1115_RawData[]换算成对应的电压值。
*/
int16_t ADS1115_RawData[4] = {0};
/**
* @brief 完成芯片控制端口初始化,并设置初始状态
*/
void ADS1115_Init()
{
}
/**
* @brief Configuration of ADS1115, single-shot
*/
void ADS1115_UserConfig_SingleConver(ADS1115_InitTypeDefine* ADS1115_InitStruct,ADS1115_ADDRESS ADDRESS)
{
ADS1115_InitStruct->COMP_LAT = ADS1115_COMP_LAT_0;
ADS1115_InitStruct->COMP_MODE = ADS1115_COMP_MODE_0;
ADS1115_InitStruct->COMP_POL = ADS1115_COMP_POL_0;
ADS1115_InitStruct->DataRate = ADS1115_DataRate_475;
ADS1115_InitStruct->MODE = ADS1115_MODE_SingleConver;
ADS1115_InitStruct->MUX = ADS1115_MUX_Channel_0;
ADS1115_InitStruct->OS = ADS1115_OS_SingleConverStart;
ADS1115_InitStruct->PGA = ADS1115_PGA_4096;
ADS1115_InitStruct->ADDRESS = ADDRESS;
ADS1115_InitStruct->CHANNEL = ADS1115_CHANNEL0;
ADS1115_Config(ADS1115_InitStruct);
}
/**
* @brief Configuration of ADS1115, continuous conversion
*/
void ADS1115_UserConfig_ContinuConver(ADS1115_InitTypeDefine* ADS1115_InitStruct,ADS1115_ADDRESS ADDRESS)
{
ADS1115_InitStruct->COMP_LAT = ADS1115_COMP_LAT_0;
ADS1115_InitStruct->COMP_MODE = ADS1115_COMP_MODE_0;
ADS1115_InitStruct->COMP_POL = ADS1115_COMP_POL_0;
ADS1115_InitStruct->DataRate = ADS1115_DataRate_475;
ADS1115_InitStruct->MODE = ADS1115_MODE_ContinuConver;
ADS1115_InitStruct->MUX = ADS1115_MUX_Channel_0;
ADS1115_InitStruct->OS = ADS1115_OS_OperationalStatus;
ADS1115_InitStruct->PGA = ADS1115_PGA_4096;
ADS1115_Config(ADS1115_InitStruct);
}
/**
* @brief 配置ADS1115
* @param ADS1115_InitStruct: 用来配置ADS1115的结构体变量指针
* @return 配置结果
* @arg: fail
* @arg: success
*/
void ADS1115_Config(ADS1115_InitTypeDefine *ADS1115_InitStruct)
{
uint16_t Config;
uint8_t Writebuff[3];
Config = ADS1115_InitStruct->OS + ADS1115_InitStruct->MUX + ADS1115_InitStruct->PGA + ADS1115_InitStruct->MODE
+ ADS1115_InitStruct->DataRate + ADS1115_InitStruct->COMP_MODE + ADS1115_InitStruct->COMP_POL
+ ADS1115_InitStruct->COMP_LAT + ADS1115_InitStruct->COMP_QUE;
Writebuff[0] = ADS1115_Pointer_ConfigReg;
Writebuff[1] = (unsigned char) ((Config >> 8) & 0xFF);
Writebuff[2] = (unsigned char) (Config & 0xFF);
HAL_I2C_Master_Transmit(&hi2c1, ADS1115_InitStruct->ADDRESS, Writebuff, 3, 100);
}
/**
* @brief 读取ADS1115当前通道下的原始数据
* @param rawData: 传入一个int16_t整型变量的指针,ADS1115的原始数据将保存在这个变量中
* @return 读取结果
* @arg 0: fail
* @arg 1: success
*/
void ADS1115_ReadRawData(ADS1115_InitTypeDefine *ADS1115_InitStruct)
{
unsigned char Result[2];
uint8_t Writebuff[1];
Writebuff[0] = ADS1115_Pointer_ConverReg;
HAL_I2C_Master_Transmit(&hi2c1, ADS1115_InitStruct->ADDRESS, Writebuff, 3, 100);
HAL_I2C_Master_Receive(&hi2c1, ADS1115_InitStruct->ADDRESS , Result, 2, 100);
ADS1115_InitStruct->ADS1115_RawData[ADS1115_InitStruct->CHANNEL] = (int16_t) (((Result[0] << 8) & 0xFF00) | (Result[1] & 0xFF));
}
/**
* @brief Switch the channel of ADS1115
* @param channel
*/
void ADS1115_ScanChannel(ADS1115_InitTypeDefine *ADS1115_InitStruct)
{
switch (ADS1115_InitStruct->CHANNEL)
{
case ADS1115_CHANNEL0:
ADS1115_InitStruct->MUX = ADS1115_MUX_Channel_0;
break;
case ADS1115_CHANNEL1:
ADS1115_InitStruct->MUX = ADS1115_MUX_Channel_1;
break;
case ADS1115_CHANNEL2:
ADS1115_InitStruct->MUX = ADS1115_MUX_Channel_2;
break;
case ADS1115_CHANNEL3:
ADS1115_InitStruct->MUX = ADS1115_MUX_Channel_3;
break;
default:
break;
}
ADS1115_Config(ADS1115_InitStruct);
}
/**
* @brief 将传感器的原始采样数据转化为电压数据,
* 根据ADS1115_InitType结构体中包含的增益信息计算
* @param rawData: 待转换的原始数据
* @retval 返回经过计算的电压值
*/
void ADS1115_RawDataToVoltage(ADS1115_InitTypeDefine *ADS1115_InitStruct)
{
switch (ADS1115_InitStruct->PGA)
{
case ADS1115_PGA_0256:
//voltage = rawData * 0.0078125;
ADS1115_InitStruct->ADS1115_Vol[ADS1115_InitStruct->CHANNEL] = ADS1115_InitStruct->ADS1115_RawData[ADS1115_InitStruct->CHANNEL]* 0.0078125;
break;
case ADS1115_PGA_0512:
// voltage = rawData * 0.015625;
ADS1115_InitStruct->ADS1115_Vol[ADS1115_InitStruct->CHANNEL] = ADS1115_InitStruct->ADS1115_RawData[ADS1115_InitStruct->CHANNEL]* 0.015625;
break;
case ADS1115_PGA_1024:
//voltage = rawData * 0.03125;
ADS1115_InitStruct->ADS1115_Vol[ADS1115_InitStruct->CHANNEL] = ADS1115_InitStruct->ADS1115_RawData[ADS1115_InitStruct->CHANNEL]* 0.03125;
break;
case ADS1115_PGA_2048:
// voltage = rawData * 0.0625;
ADS1115_InitStruct->ADS1115_Vol[ADS1115_InitStruct->CHANNEL] = ADS1115_InitStruct->ADS1115_RawData[ADS1115_InitStruct->CHANNEL]* 0.0625;
break;
case ADS1115_PGA_4096:
//voltage = rawData * 0.125;
ADS1115_InitStruct->ADS1115_Vol[ADS1115_InitStruct->CHANNEL] = ADS1115_InitStruct->ADS1115_RawData[ADS1115_InitStruct->CHANNEL]* 0.125;
break;
case ADS1115_PGA_6144:
// voltage = rawData * 0.1875;
ADS1115_InitStruct->ADS1115_Vol[ADS1115_InitStruct->CHANNEL] = ADS1115_InitStruct->ADS1115_RawData[ADS1115_InitStruct->CHANNEL]* 0.1875;
break;
default:
//voltage = 0;
ADS1115_InitStruct->ADS1115_Vol[ADS1115_InitStruct->CHANNEL] = 0;
break;
}
}
/**
* @brief 直接获取ADS1115当前通道的电压采样值
* @return 电压采样值
*/
void ADS1115_GetVoltage(ADS1115_InitTypeDefine *ADS1115_InitStruct)
{
ADS1115_ReadRawData(ADS1115_InitStruct);
ADS1115_RawDataToVoltage(ADS1115_InitStruct);
}
/**
* @brief 获取并计算ADC采样的平均电压值
* @param num: 计算平均值的数量
* @retval 电压采样的平均值
*/
void ADS1115_GetAverageVoltage(ADS1115_InitTypeDefine *ADS1115_InitStruct)
{
// ADS1115_ReadRawData(&ADS1115_InitType);
//
// ADS1115_GetVoltage(&ADS1115_InitType);
// ADS1115_RefreshAllChannel(&ADS1115_InitType);
// return ADS1115_RawDataToVoltage(sum/num);
}
/**
* @brief 刷新ADS1115全部通道的采样数据
* 由于ADS1115通道切换后需要等待较长时间数据才能够稳定,
* 在进行多路数据采集的时候,切换通道后延时阻塞等待切换完成会占用过多的系统时间,
* 因此需要在一个定时器中轮询采集ADS1115数据,每次采集完成后,切换到下一个通道
* 大幅度提高了系统工作的效率。
*
* 调用此函数可以刷新全局变量ADS1115_RawData[4]的值。
*
* 应当在一个定时器更新中断服务函数中周期性的调用此函数,更新周期最好小于200Hz
*/
void ADS1115_RefreshAllChannel(ADS1115_InitTypeDefine *ADS1115_InitStruct)
{
//通道切换时可能有不确定的数据读出,因此需要将前1~2次读出的数据舍弃
ADS1115_ReadRawData(ADS1115_InitStruct);
ADS1115_ReadRawData(ADS1115_InitStruct);
ADS1115_ReadRawData(ADS1115_InitStruct);
//ADS1115总共4个通道
ADS1115_InitStruct->CHANNEL++;
if(ADS1115_InitStruct->CHANNEL > ADS1115_MAX_CHANNEL-1)
ADS1115_InitStruct->CHANNEL = ADS1115_CHANNEL0;
//结束采样后切换至下一通道
ADS1115_ScanChannel(ADS1115_InitStruct);
}
main.c
ADS1115_UserConfig_SingleConver(&ADS1115_ADDR_GND,ADS1115_ADDRESS_GND);//ADDR连接GND 的ADS1115 单次转换模式
ADS1115_UserConfig_SingleConver(&ADS1115_ADDR_VDD,ADS1115_ADDRESS_VDD);//ADDR连接VDD的ADS1115 单次转换模式
for(;;)
{
ADS1115_GetVoltage(&ADS1115_ADDR_GND);
ADS1115_RefreshAllChannel(&ADS1115_ADDR_GND);
printf("ADS1115 GND CH %d vol = %.3f \n\n",ADS1115_ADDR_GND.CHANNEL,ADS1115_ADDR_GND.ADS1115_Vol[ADS1115_ADDR_GND.CHANNEL]);
ADS1115_GetVoltage(&ADS1115_ADDR_VDD);
ADS1115_RefreshAllChannel(&ADS1115_ADDR_VDD);
printf("ADS1115 VDD CH %d vol = %.3f \n\n",ADS1115_ADDR_VDD.CHANNEL,ADS1115_ADDR_VDD.ADS1115_Vol[ADS1115_ADDR_VDD.CHANNEL]);
osDelay(100);
}