ADS1015使用指南及STM32-M0驱动程序
一、ADS1015简介
ADS1015是TI公司生产的一款AD转换芯片,采用IIC串口协议通信,4个转换通道,12位转换精度,最大转换速度为3.3kSPS,内置增益放大器,用户可以根据自己所需设置增益。与ADS1015同一系列的还有ADS1016,16位转换精度,在这篇博客里面我只介绍ADS1015,因为类芯片差不多。因为TI芯片官方给的驱动列程,不适合STM32等单片机,所以在这篇博客上面我会提供驱动程序和相应介绍。
二、本案例使用软硬件
- STM32CubeIDE
- STM32L0xx_HAL_Driver
- NUCLEO-L073RZTx (STM32L073RZ)
三、重要参数介绍(I/O以及配置模式)
3.0 I/O简单介绍
-
ADDR 地址引脚(接不同的引脚可以设置不同的地址,接GND引脚地址为0x48)
-
ALERT中断引脚,芯片里面可以配置电压比较,可作为数值比较器输出或转换就绪引脚
-
GND 地线
-
AIN0 AD转换通道0
-
AIN1 AD转换通道1
-
AIN2 AD转换通道2
-
AIN3 AD转换通道3
-
VDD接2.0-5.5V
-
SDA IIC数据线
-
SCL IIC时钟线
3.1 PGA(增益放大器)
在ADS1014和ADS1015的ADC之前实现一个可编程增益放大器(PGA)。满量程由Config寄存器中的位**PGA[2:0]**配置,可设置为6.144 V、4.096 V、2.048 V、1.024 V、0.512 V、0.256 V。
3.2 ALERT/RDY 引脚
ADS1014和ADS1015上可用,中断引脚,芯片里面可以配置电压比较,可作为数值比较器输出或转换就绪引脚。本文重点关注转换就绪功能。
ALERT/RDY引脚也可以配置为一个转换准备引脚。将Hi_thresh寄存器的最高有效位设置为1,将Lo_thresh寄存器的最高有效位设置为0,以使引脚可以作为一个准备转换的引脚。COMP_POL位继续按照预期运行(ALERT/RDY引脚可以通过配置寄存器中的COMP_POL位配置为主动高电平或主动低电平)。设置COMP_QUE[1:0]位为11以外的任何2位值,以保持ALERT/RDY引脚启用,并允许转换准备信号出现在ALERT/RDY引脚输出。COMP_MODE和COMP_LAT位不再控制任何功能。当配置为一个转换准备引脚时,ALERT/RDY继续需要一个上拉电阻。在连续转换模式下,ADS101x在每次转换结束时都在ALERT/RDY引脚上提供一个大约8 us的转换准备脉冲。在单拍模式下,如果COMP_POL位设置为0,ALERT/RDY引脚在转换结束时断言低。(ADS1015 datasheet)
3.3 复位
ADS101x在上电时复位,并将Config寄存器中的所有位设置为各自的默认设置。完成复位后,ADS101x进入下电状态。设备接口和数字块是活动的,但不执行数据转换。ADS101x的初始掉电状态缓解了系统对电源供应的紧张需求,在上电时不会遇到浪涌。ADS101x响应I2C通用呼叫reset命令。当ADS101x接收到通用呼叫复位命令(06h)时,就像设备上电一样执行内部复位。
3.4 工作模式
3.4.1 Single-Shot Mode
当Config寄存器中的MODE位设置为1时,ADS101x进入下电状态,并在单次采样模式下运行。这种下电状态是ADS101x在第一次上电时的默认状态。尽管关闭了电源,这些设备仍然能响应命令。ADS101x保持这种下电状态,直到配置寄存器的操作状态(OS)位写入1。当OS位被断言时,设备在大约25
μs内启动,将OS位重置为0,并开始一次单一的转换。当转换数据准备好检索时,设备再次断电。在进行转换时将1写入OS位没有效果。要切换到连续转换模式,请在配置寄存器的mode位中写入一个0。
3.4.2 Continuous-Conversion Mode
在连续转换模式(模式位设置为0),ADS101x执行连续转换。当一个转换完成时,ADS101x将结果放入转换寄存器并立即开始另一个转换。当编写新的配置设置时,当前正在进行的转换将以以前的配置设置完成。之后,开始使用新的配置设置进行连续的转换。要切换到单次转换模式,向配置寄存器的mode位写入1或重置设备。
3.5 低功耗运行(Duty Cycling For Low Power)
ADC的噪声性能通常在降低输出数据率时得到改善,因为内部调制器的更多样本被平均以产生一个转换结果。在功耗非常重要的应用中,可能不需要在低数据速率下改善噪声性能。对于这些应用,ADS101x支持负载循环,通过周期性地以有效的低数据率请求高数据率读数,产生显著的功耗节省。例如,将数据速率设置为3300 SPS的断电状态ADS101x可以由微控制器操作,该微控制器每7.8 ms (128 SPS)指示一次转换。在3300 SPS的转换只需要大约0.3 ms,所以ADS101x进入下电状态,为剩余的7.5 ms。在这种配置下,ADS101x消耗的功率大约是连续转换模式下的1/25。占空比完全是任意的,由主控制器定义。ADS101x提供较低的数据速率,不实现负载循环,如果需要还提供改进的噪声性能。
四、寄存器介绍
4.0 简介(四大寄存器地址指针)
ADS101x有四个寄存器,可以使用地址指针寄存器通过I2C接口访问它们。Conversion寄存器包含最后一次转换的结果。Config寄存器用于修改ADS101x的工作模式和查询设备状态。另外两个寄存器Lo_thresh和Hi_thresh用于设置比较器函数的阈值,在ADS1013中不可用。
4.1 Config 寄存器介绍
-
BIT[15] OS位:此为来设置芯片数据读的模式,是单次读还是连续读。
-
BITS[10-11]:配置电压增益。
-
BITS[7-5]:配置转换速度。
4.2 Conversion寄存器
16位转换寄存器以二进制二的补码格式包含最后一次转换的结果。上电之后,Conversion寄存器被清除为0,并且一直保持为0,直到第一次转换完成。
4.3 Lo_thresh (P[1:0] = 2h) [reset = 8000h]寄存器和Hi_thresh (P[1:0] = 3h) [reset = 7FFFh]寄存器
比较器使用的上、下阈值以二补格式存储在两个16位寄存器中。该比较器实现为数字比较器;因此,当PGA设置更改时,这些寄存器中的值必须更新。
通过将Hi_thresh寄存器MSB设置为1和Lo_thresh寄存器MSB设置为0,ALERT/RDY引脚的就绪转换功能被启用。要使用ALERT/RDY引脚的比较器函数,Hi_thresh寄存器的值必须总是大于Lo_thresh寄存器的值。阈值寄存器格式如图22所示。当设置为RDY模式时,ALERT/RDY引脚在单拍模式下输出OS位,在连续转换模式下提供连续转换准备脉冲。
五、I2C接口介绍
5.0 简单连接示意图
5.1 I2C协议(Read-high & Write-low)
5.1.1 地址选择
ADS101x有一个地址针ADDR,用来配置设备的I2C地址。这个引脚可以连接到GND、VDD、SDA或SCL,允许用一个引脚选择四个不同的地址,如表2所示。地址针ADDR的状态连续采样。首先使用GND、VDD和SCL地址。如果使用SDA作为设备地址,在SCL线降低后保持SDA线低至少100ns,以确保设备在I2C通信期间正确解码地址。
5.1.2 I2C General Call
当第8位为0时,ADS101x响应I2C通用呼叫地址(0000000)。设备确认通用呼叫地址,并对第二字节中的命令作出响应。如果第二个字节是00000110 (06h), ADS101x将重置内部寄存器并进入下电状态。
5.1.3 I2C速度模式
I2C总线以三种速度运行。标准模式允许高达100 kHz的时钟频率;快速模式允许高达400khz的时钟频率;高速模式(也称为Hs模式)允许高达3.4 MHz的时钟频率。ADS101x完全兼容所有三种模式。
在标准或快速模式下使用ADS101x不需要特殊操作,但高速模式必须被激活。要激活高速模式,在START条件下发送一个特殊的地址字节00001xxx,其中xxx是支持hs的主机唯一的位。这个字节称为Hs主码,与普通地址字节不同;第8位不表示读写状态。ADS101x不承认这个字节;I2C规范禁止确认Hs主代码。在接收到主码后,ADS101x开启Hs模式滤波器,并以高达3.4 MHz的频率进行通信。ADS101x切换出Hs模式下一个停止条件。 有关高速模式的更多信息,请参阅I2C规范。
5.1.4 I2C接收规则
在从端接收模式下,从主端发送过来的第一个字节由7位设备地址和一个低R/W位组成。由主机传输的下一个字节是地址指针寄存器。然后ADS101x确认收到地址指针寄存器字节。接下来的两个字节被写入寄存器地址指针位P[1:0]给出的地址。ADS101x确认发送的每个字节。寄存器字节首先以最高有效字节发送,然后是最低有效字节。
5.1.5 I2C发送规则
在从发送模式下,从主端发送过来的第一个字节是7位的从地址,后面是高R/W位。这个字节将从服务器置于传输模式,并指示ADS101x正在被读取。由从端传送的下一个字节是由寄存器地址指针位P[1:0]指示的寄存器的最有效字节。这个字节后面跟着来自主机的确认信息。剩余的最低有效字节然后由从服务器发送,随后是来自主服务器的确认。主服务器可以在任何字节之后终止传输,不承认或不发出“开始”或“停止”条件。
5.1.6 通过I2C读写寄存器
为了从ADS101x访问一个特定的寄存器,主机必须首先在地址指针寄存器中写入一个适当的值来注册地址指针位P[1:0](见4.0)。在地址字节,低R/W位,和一个成功的从端确认之后,地址指针寄存器被直接写入。写入地址指针寄存器和从端确认之后,主服务器发出STOP或重复START条件。
当从ADS101x读取时,先前写入P[1:0]位的值决定了所读取的寄存器。要改变读哪个寄存器,必须向P[1:0]写入一个新值。为了向P[1:0]写入一个新值,主服务器发出一个R/W位低的从地址字节,然后是地址指针寄存器字节。不需要传输额外的数据,并且可以由主机发出停止条件。master现在可以发出START条件并发送带R/W位为高的从地址字节来开始读。图22详细说明了这个序列。如果需要从同一个寄存器重复读,则不需要不断发送地址指针寄存器,因为ADS101x存储P[1:0]的值,直到它被写操作修改。但是,对于每个写操作,地址指针寄存器都必须用适当的值写入。
读时序操作步骤:
1.发送写地址给ADS1015;
2.向地址指针寄存器写数据,后两位有效,只能写0x00,0x01,0x02,0x03;
3.发送读地址给ADS1115;
4.读取ADS1115的数据(两个字节,MSB先行);
写时序操作步骤:
1.发送写地址给ADS1115;
2.向地址指针寄存器写数据,后两位有效,只能写0x00,0x01,0x02,0x03;
3.发送数据给ADS1115(高位在前)
六、基于STM32CubeIDE的ADS1015驱动
6.1 Header文件
/*
* ADS1015.h
*
* Created on: Jul 28, 2021
* Author: 17293
*/
#ifndef USER_INC_ADS1015_H_
#define USER_INC_ADS1015_H_
#include "main.h"
/*=========================================================================
* Auxiliary Definition
*/
#define ADS1015_DUAL_END (0)
#define ADS1015_SINGLE_END (1)
/*========================================================================= */
/*=========================================================================
I2C ADDRESS/BITS
-----------------------------------------------------------------------*/
#define ADS1015_ADDRESS (0x90) // 1001 0000 (ADDR = GND)
#define ADS1015_WRITE_MODE (0x00)
#define ADS1015_READ_MODE (0x01)
/*=========================================================================*/
/*=========================================================================
CONVERSION DELAY (in mS)
-----------------------------------------------------------------------*/
#define ADS1015_CONVERSIONDELAY (1)
/*=========================================================================*/
/*=========================================================================
POINTER REGISTER
-----------------------------------------------------------------------*/
#define ADS1015_REG_POINTER_MASK (0x03)
#define ADS1015_REG_POINTER_CONVERT (0x00)
#define ADS1015_REG_POINTER_CONFIG (0x01)
#define ADS1015_REG_POINTER_LOWTHRESH (0x02)
#define ADS1015_REG_POINTER_HITHRESH (0x03)
/*=========================================================================*/
/*=========================================================================
CONFIG REGISTER
-----------------------------------------------------------------------*/
#define ADS1015_REG_CONFIG_OS_MASK (0x8000)
#define ADS1015_REG_CONFIG_OS_SINGLE (0x8000) // Write: Set to start a single-conversion
#define ADS1015_REG_CONFIG_OS_BUSY (0x0000) // Read: Bit = 0 when conversion is in progress
#define ADS1015_REG_CONFIG_OS_NOTBUSY (0x8000) // Read: Bit = 1 when device is not performing a conversion
#define ADS1015_REG_CONFIG_MUX_MASK (0x7000)
#define ADS1015_REG_CONFIG_MUX_DIFF_0_1 (0x0000) // Differential P = AIN0, N = AIN1 (default)
#define ADS1015_REG_CONFIG_MUX_DIFF_0_3 (0x1000) // Differential P = AIN0, N = AIN3
#define ADS1015_REG_CONFIG_MUX_DIFF_1_3 (0x2000) // Differential P = AIN1, N = AIN3
#define ADS1015_REG_CONFIG_MUX_DIFF_2_3 (0x3000) // Differential P = AIN2, N = AIN3
#define ADS1015_REG_CONFIG_MUX_SINGLE_0 (0x4000) // Single-ended AIN0
#define ADS1015_REG_CONFIG_MUX_SINGLE_1 (0x5000) // Single-ended AIN1
#define ADS1015_REG_CONFIG_MUX_SINGLE_2 (0x6000) // Single-ended AIN2
#define ADS1015_REG_CONFIG_MUX_SINGLE_3 (0x7000) // Single-ended AIN3
#define ADS1015_REG_CONFIG_PGA_MASK (0x0E00)
#define ADS1015_REG_CONFIG_PGA_6_144V (0x0000) // +/-6.144V range = Gain 2/3
#define ADS1015_REG_CONFIG_PGA_4_096V (0x0200) // +/-4.096V range = Gain 1
#define ADS1015_REG_CONFIG_PGA_2_048V (0x0400) // +/-2.048V range = Gain 2 (default)
#define ADS1015_REG_CONFIG_PGA_1_024V (0x0600) // +/-1.024V range = Gain 4
#define ADS1015_REG_CONFIG_PGA_0_512V (0x0800) // +/-0.512V range = Gain 8
#define ADS1015_REG_CONFIG_PGA_0_256V (0x0A00) // +/-0.256V range = Gain 16
#define ADS1015_REG_CONFIG_MODE_MASK (0x0100)
#define ADS1015_REG_CONFIG_MODE_CONTIN (0x0000) // Continuous conversion mode
#define ADS1015_REG_CONFIG_MODE_SINGLE (0x0100) // Power-down single-shot mode (default)
#define ADS1015_REG_CONFIG_DR_MASK (0x00E0)
#define ADS1015_REG_CONFIG_DR_128SPS (0x0000) // 128 samples per second
#define ADS1015_REG_CONFIG_DR_250SPS (0x0020) // 250 samples per second
#define ADS1015_REG_CONFIG_DR_490SPS (0x0040) // 490 samples per second
#define ADS1015_REG_CONFIG_DR_920SPS (0x0060) // 920 samples per second
#define ADS1015_REG_CONFIG_DR_1600SPS (0x0080) // 1600 samples per second (default)
#define ADS1015_REG_CONFIG_DR_2400SPS (0x00A0) // 2400 samples per second
#define ADS1015_REG_CONFIG_DR_3300SPS (0x00C0) // 3300 samples per second
#define ADS1015_REG_CONFIG_CMODE_MASK (0x0010)
#define ADS1015_REG_CONFIG_CMODE_TRAD (0x0000) // Traditional comparator with hysteresis (default)
#define ADS1015_REG_CONFIG_CMODE_WINDOW (0x0010) // Window comparator
#define ADS1015_REG_CONFIG_CPOL_MASK (0x0008)
#define ADS1015_REG_CONFIG_CPOL_ACTVLOW (0x0000) // ALERT/RDY pin is low when active (default)
#define ADS1015_REG_CONFIG_CPOL_ACTVHI (0x0008) // ALERT/RDY pin is high when active
#define ADS1015_REG_CONFIG_CLAT_MASK (0x0004) // Determines if ALERT/RDY pin latches once asserted
#define ADS1015_REG_CONFIG_CLAT_NONLAT (0x0000) // Non-latching comparator (default)
#define ADS1015_REG_CONFIG_CLAT_LATCH (0x0004) // Latching comparator
#define ADS1015_REG_CONFIG_CQUE_MASK (0x0003)
#define ADS1015_REG_CONFIG_CQUE_1CONV (0x0000) // Assert ALERT/RDY after one conversions
#define ADS1015_REG_CONFIG_CQUE_2CONV (0x0001) // Assert ALERT/RDY after two conversions
#define ADS1015_REG_CONFIG_CQUE_4CONV (0x0002) // Assert ALERT/RDY after four conversions
#define ADS1015_REG_CONFIG_CQUE_NONE (0x0003) // Disable the comparator and put ALERT/RDY in high state (default)
/*=========================================================================*/
typedef enum
{
GAIN_TWOTHIRDS = ADS1015_REG_CONFIG_PGA_6_144V,
GAIN_ONE = ADS1015_REG_CONFIG_PGA_4_096V,
GAIN_TWO = ADS1015_REG_CONFIG_PGA_2_048V,
GAIN_FOUR = ADS1015_REG_CONFIG_PGA_1_024V,
GAIN_EIGHT = ADS1015_REG_CONFIG_PGA_0_512V,
GAIN_SIXTEEN = ADS1015_REG_CONFIG_PGA_0_256V
} adsGain_t;
/***************Prototypes****************/
void ADS1015_Config(I2C_HandleTypeDef I2cHandle,uint8_t TnputMUX,uint8_t Channel);
int16_t ADS1015_Read_Data(I2C_HandleTypeDef I2cHandle,uint8_t FirADCRead);
void ADS1015_Config_Register(I2C_HandleTypeDef I2cHandle,uint16_t pointAddr,uint16_t configData);
uint8_t AD1015_Check(I2C_HandleTypeDef I2cHandle);
/* External Variable Declaration */
extern uint16_t ADS1015_CONFIG;//定义ADS1015配置变量
#endif /* USER_INC_ADS1015_H_ */
6.2 Source文件
/*
* ADS1015.c
*
* Created on: Jul 28, 2021
* Author: 17293
*/
#include "ADS1015.h"
uint16_t ADS1015_CONFIG;//定义ADS1015配置变量
//ADS1015配置函数
//channel:模数转换通道
void ADS1015_Config(I2C_HandleTypeDef I2cHandle,uint8_t TnputMUX,uint8_t Channel)
{
// Start with default values
ADS1015_CONFIG = ADS1015_REG_CONFIG_CQUE_NONE | // Disable the comparator (default val)
ADS1015_REG_CONFIG_CLAT_NONLAT | // Non-latching (default val)
ADS1015_REG_CONFIG_CPOL_ACTVLOW | // Alert/Rdy active low (default val)
ADS1015_REG_CONFIG_CMODE_TRAD | // Traditional comparator (default val)
ADS1015_REG_CONFIG_DR_3300SPS | // 3300 samples per second (default)
ADS1015_REG_CONFIG_MODE_SINGLE; // Single-shot mode (default)
// Set PGA/voltage range
ADS1015_CONFIG |= ADS1015_REG_CONFIG_PGA_4_096V;
if(TnputMUX == ADS1015_DUAL_END)
{
switch (Channel)
{
case (0):
ADS1015_CONFIG |= ADS1015_REG_CONFIG_MUX_DIFF_0_1;
break;
case (1):
ADS1015_CONFIG |= ADS1015_REG_CONFIG_MUX_DIFF_0_3;
break;
case (2):
ADS1015_CONFIG |= ADS1015_REG_CONFIG_MUX_DIFF_1_3;
break;
case (3):
ADS1015_CONFIG |= ADS1015_REG_CONFIG_MUX_DIFF_2_3;
break;
}
}
else if(TnputMUX == ADS1015_SINGLE_END)
{
switch (Channel)
{
case (0):
ADS1015_CONFIG |= ADS1015_REG_CONFIG_MUX_SINGLE_0;
break;
case (1):
ADS1015_CONFIG |= ADS1015_REG_CONFIG_MUX_SINGLE_1;
break;
case (2):
ADS1015_CONFIG |= ADS1015_REG_CONFIG_MUX_SINGLE_2;
break;
case (3):
ADS1015_CONFIG |= ADS1015_REG_CONFIG_MUX_SINGLE_3;
break;
}
}
// Set 'start single-conversion' bit
ADS1015_CONFIG |= ADS1015_REG_CONFIG_OS_SINGLE;
}
//AD1015读取ADC转换数据(即CONVERT寄存器)
//返回值:获取的12位ADC值
int16_t ADS1015_Read_Data(I2C_HandleTypeDef I2cHandle,uint8_t FirADCRead)
{
int16_t data;
uint8_t tx_data[1] = {(uint8_t)ADS1015_REG_POINTER_CONVERT};
uint8_t rx_data[2]={0};
if(FirADCRead == 1)
{
while(HAL_I2C_Master_Transmit(&I2cHandle, (uint16_t)(ADS1015_ADDRESS|ADS1015_WRITE_MODE), tx_data, 1, 1000) != HAL_OK)
{
if(HAL_I2C_GetError(&I2cHandle) != HAL_I2C_ERROR_AF)
{
printf("ADS1015 Convert Register Error!!!\r\n");
}
}
}
while(HAL_I2C_Master_Receive(&I2cHandle, (uint16_t)(ADS1015_ADDRESS|ADS1015_READ_MODE), rx_data, 2, 1000) != HAL_OK)
{
if(HAL_I2C_GetError(&I2cHandle) != HAL_I2C_ERROR_AF)
{
printf("ADS1015 Read Data Error!!!\r\n");
}
}
data=rx_data[0]*256U+rx_data[1];
return data;
}
//AD1015配置寄存器函数(寄存器指针和待配置值的高低比特)
void ADS1015_Config_Register(I2C_HandleTypeDef I2cHandle,uint16_t pointAddr,uint16_t configData)
{
uint8_t configH,configL;
configH = configData >> 8;
configL = configData & 0x0F;
uint8_t reg_data[3] = {pointAddr,configH,configL};
while(HAL_I2C_Master_Transmit(&I2cHandle, (uint16_t)(ADS1015_ADDRESS|ADS1015_WRITE_MODE), reg_data, 3, 1000) != HAL_OK)
{
if(HAL_I2C_GetError(&I2cHandle) != HAL_I2C_ERROR_AF)
{
printf("ADS1015 Config Register Error!!!\r\n");
}
}
}
//检测AD1015是否存在
//返回值:0存在 1不存在
//未找到DataSheet文字记录
uint8_t AD1015_Check(I2C_HandleTypeDef I2cHandle)
{
uint8_t rx_data[1]={22};
uint8_t tx_data[1] = {(uint8_t)(ADS1015_ADDRESS<<1)};
while(HAL_I2C_Master_Transmit(&I2cHandle, (uint16_t)(ADS1015_ADDRESS|ADS1015_WRITE_MODE), tx_data, 1, 1000) != HAL_OK)
{
if(HAL_I2C_GetError(&I2cHandle) != HAL_I2C_ERROR_AF)
{
printf("ADS1015 Convert Register Error!!!\r\n");
}
}
while(HAL_I2C_Master_Receive(&I2cHandle, (uint16_t)(ADS1015_ADDRESS|ADS1015_READ_MODE), rx_data, 1, 1000) != HAL_OK)
{
if(HAL_I2C_GetError(&I2cHandle) != HAL_I2C_ERROR_AF)
{
printf("ADS1015 Read Data Error!!!\r\n");
}
}
return rx_data[0];
}
6.3 使用案例
int main(void)
{
/* USER CODE BEGIN 1 */
int16_t adc_12bit_int;
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_USART2_UART_Init();
MX_TIM6_Init();
MX_I2C1_Init();
/* USER CODE BEGIN 2 */
ADS1015_Config(hi2c1,ADS1015_SINGLE_END,0);
/*Write config register to the ADC*/
ADS1015_Config_Register(hi2c1,ADS1015_REG_POINTER_CONFIG,ADS1015_CONFIG);
adc_12bit_int = ADS1015_Read_Data(hi2c1,1);
printf("hello world, now SystemCoreClock is %ld\r\n",SystemCoreClock);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
HAL_Delay(1000-1);
HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin);
ADS1015_Config_Register(hi2c1,ADS1015_REG_POINTER_CONFIG,ADS1015_CONFIG);
adc_12bit_int = ADS1015_Read_Data(hi2c1,1);//due to ADS1015_Config_Register, FirADCRead must be set to 1 in single-shot mode
printf("now adc_12bit_int is %d\r\n",adc_12bit_int);
}
/* USER CODE END 3 */
}
七、答疑和避坑
- 关于I2C配置问题,ADS1XXX系列ADC使用的I2C属于标准I2C协议,因此只需开启STM32的IIC(直接默认基础配置,改一下主机地址即可),因此ADS1015数据手册中的I2C通信协议只需记住,每写入一个字节的P[1:0]和N字节即可配置好一个寄存器(N取决于寄存器长度),
- 而且每次读写(不中断的一次读写)只需要不需要重新送入地址,这个就是标准I2C的协议。
- 此外,P[1:0]中的地址工作时仅会因为写入而改变,不写入则保留原值,因此视需求决定是否写入P[1:0]。
References
1. ADS1015使用指南及STM32驱动程序
2. TI官网-ADS1015
STM32学习笔记之IIC(1) ADS1115
STM32L0+STM32CubeIDE避坑指南