ADS1015使用指南及驱动程序
ADS1015使用指南
由于网上关于TI公司的ADS1015数模转换芯片的资料比较少,而且官方给的驱动不适合STM32这种单片机,在本博客中主要介绍了ADS1015的一些基本信息以及STM32的驱动程序。
简介
ADS1015是TI公司生产的一款AD转换芯片,采用IIC串口协议通信,4个转换通道,12位转换精度,最大转换速度为3.3ksps,内置增益放大器,用户可以根据自己所需设置增益。与ADS1015同一系列的还有ADS1016,16位转换精度,在这篇博客里面我只介绍ADS1015,因为类芯片差不多。因为TI芯片官方给的驱动列程,不适合STM32等单片机,所以在这篇博客上面我会提供驱动程序和相应介绍。
这篇博客的大致介绍顺序为:
ADS1015的引脚 介绍-> 寄存器介绍 ->寄存器相关配置
->驱动程序
ADS1015的引脚介绍
1.ADDR 地址引脚(接不同的引脚可以设置不同的地址,接GND引脚地址为0x48)
2.ALERT中断引脚,芯片里面可以配置电压比较,可作为数值比较器输出或转换就绪引脚
3.GND 地线
4.AIN0 AD转换通道0
5.AIN1 AD转换通道1
6.AIN2 AD转换通道2
7.AIN3 AD转换通道3
8. VDD接2.0-5.5V
9. SDA IIC数据线
10.SCL IIC时钟线
对于ADDR引脚我需要介绍一下:
引脚可以根据接GND VDD SDA SCL四个引脚来设置不同地址,如下表:
由表可知,当ADDR引脚接GND时,地址为0x48,接VDD时地址0x49,接SDA引脚0x4a,接SCL引脚0x4b。
ADS1015的寄存器介绍
ADS1015有四个寄存器,如下图所示,BIT1和BIT0表示寄存器的地址,分别对应转换寄存器、配置寄存器、低阈值寄存器和高阈值寄存器。其中转换寄存器中存储AD转换后的结果,由于转换结果为12位,所以读取时应把数据左移4位,配置寄存器来配置芯片参数,高阈值和低阈值寄存器用作电压比较功能。
寄存器相关配置
配置ADS1015芯片需要用到配置寄存器,如下表所示:
在此我只介绍几个比较重要的寄存器配置:
(1)BIT[15] OS位:此为来设置芯片数据读的模式,是单次读还是连续读。
(2)BITS[10-11]:配置电压增益。
(3)BITS[7-5]:配置转换速度。
具体的一些细节大家可以参考数据手册,我会在下面上传资料
驱动程序
ADS1015.h
#ifndef _ADS1015_H_
#define _ADS1015_H_
#include "sys.h"
/*=========================================================================
I2C ADDRESS/BITS
-----------------------------------------------------------------------*/
#define ADS1015_ADDRESS (0x48) // 1001 000 (ADDR = GND)
/*=========================================================================*/
/*=========================================================================
CONVERSION DELAY (in mS)
-----------------------------------------------------------------------*/
#define ADS1015_CONVERSIONDELAY (1)
#define ADS1115_CONVERSIONDELAY (8)
/*=========================================================================*/
/*=========================================================================
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;
/***************外部函数声明****************/
extern void ADS1015_Init(void);
extern u16 ADS1015_ReadOneByte(u8 i2cAddress,u16 ReadAddr);
extern void ADS1015_WriteOneByte(u8 i2cAddress,u16 WriteAddr,u16 DataToWrite);
extern void AD1015_Test(void);
extern u8 AD1015_Check(u8 i2cAddress);
extern void ADS1015_Config(u8 i2cAddress,u8 channel);
extern u16 ADS1015_Read(u8 channel);
#endif
ADS1015.c
#include "ADS1015.h"
#include "myiic.h"
u16 ADS1015_CONFIG;//定义ADS1015配置变量
//ADS1015配置函数
//channel:模数转换通道
void ADS1015_Config(u8 i2cAddress,u8 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 | // 1600 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;
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;
// Write config register to the ADC
ADS1015_WriteOneByte(i2cAddress, ADS1015_REG_POINTER_CONFIG, ADS1015_CONFIG);
}
//ADS1015初始化函数
void ADS1015_Init()
{
IIC_Init();
ADS1015_Config(ADS1015_ADDRESS,0);
}
//ADS1015从寄存器读两字节数据
u16 ADS1015_ReadOneByte(u8 i2cAddress,u16 ReadAddr)
{
u16 temp=0;
IIC_Start();
IIC_Send_Byte(i2cAddress<<1);
IIC_Wait_Ack();
IIC_Send_Byte(ReadAddr);
IIC_Wait_Ack();
IIC_Stop();
IIC_Start();
IIC_Send_Byte((i2cAddress<<1)+1);
IIC_Wait_Ack();
temp=IIC_Read_Byte(1);
temp=temp<<8;
temp+=IIC_Read_Byte(1);
IIC_Stop();
return temp;
}
//ADS1015写两字节数据
void ADS1015_WriteOneByte(u8 i2cAddress,u16 WriteAddr,u16 DataToWrite)
{
IIC_Start();
IIC_Send_Byte(i2cAddress<<1);
IIC_Wait_Ack();
IIC_Send_Byte(WriteAddr);
IIC_Wait_Ack();
IIC_Send_Byte(DataToWrite>>8);
IIC_Wait_Ack();
IIC_Send_Byte(DataToWrite&0xff);
IIC_Wait_Ack();
IIC_Stop();
}
//ADS1015读数据
//返回值:获取的AD值
//Channel:通道数,范围0-3
u16 ADS1015_Read(u8 channel)
{
int temp;
// 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 | // 1600 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(channel<3)
{
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;
ADS1015_WriteOneByte(ADS1015_ADDRESS,ADS1015_REG_POINTER_CONFIG, ADS1015_CONFIG);
//delay_us(500);
delay_ms(1);
temp=ADS1015_ReadOneByte(ADS1015_ADDRESS,ADS1015_REG_POINTER_CONVERT);
temp=temp>>4;
return temp;
}
return 0;
}
//检测AD1015是否存在
//参数:
//i2cAddress:芯片地址
//返回值:0存在 1不存在
u8 AD1015_Check(u8 i2cAddress)
{
u8 x=22;
IIC_Start();
IIC_Send_Byte(i2cAddress<<1);
x=IIC_Wait_Ack();
return x;
}
myiic.h
#ifndef __MYIIC_H
#define __MYIIC_H
#include "sys.h"
//IO方向设置
#define SDA_IN() {GPIOB->CRH&=0XFFFFF0FF;GPIOB->CRH|=(u32)8<<8;}
#define SDA_OUT() {GPIOB->CRH&=0XFFFFF0FF;GPIOB->CRH|=(u32)3<<8;}
//IO操作函数
#define IIC_SCL PBout(11) //SCL
#define IIC_SDA PBout(10) //SDA
#define READ_SDA PBin(10) //输入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 IIC_Write_One_Byte(u8 daddr,u8 addr,u8 data);
u8 IIC_Read_One_Byte(u8 daddr,u8 addr);
#endif
myiic.c
#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_10|GPIO_Pin_11;
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_10|GPIO_Pin_11); //PB6,PB7 输出高
}
//产生IIC起始信号
void IIC_Start(void)
{
SDA_OUT(); //sda线输出
IIC_SDA=1;
IIC_SCL=1;
delay_us(4);
IIC_SDA=0;//START:when CLK is high,DATA change form high to low
delay_us(4);
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(4);
IIC_SCL=1;
IIC_SDA=1;//发送I2C总线结束信号
delay_us(4);
}
//等待应答信号到来
//返回值:1,接收应答失败
// 0,接收应答成功
u8 IIC_Wait_Ack(void)
{
u8 ucErrTime=0;
SDA_IN(); //SDA设置为输入
IIC_SDA=1;delay_us(1);
IIC_SCL=1;delay_us(1);
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(2);
IIC_SCL=1;
delay_us(2);
IIC_SCL=0;
}
//不产生ACK应答
void IIC_NAck(void)
{
IIC_SCL=0;
SDA_OUT();
IIC_SDA=1;
delay_us(2);
IIC_SCL=1;
delay_us(2);
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(2); //对TEA5767这三个延时都是必须的
IIC_SCL=1;
delay_us(2);
IIC_SCL=0;
delay_us(2);
}
}
//读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(2);
IIC_SCL=1;
receive<<=1;
if(READ_SDA)receive++;
delay_us(1);
}
if (!ack)
IIC_NAck();//发送nACK
else
IIC_Ack(); //发送ACK
return receive;
}
程序包括普通引脚模拟IIC驱动和ADS1015驱动,单片机使用的引脚为PA10和PA11,我是根据官方程序和结合收据手册改的,大概改了一天。我会把驱动程序上传,在这里我直接说几个ADS1015里面几个比较重要的函数。
ADS1015_Init(void);//ADS初始化函数
ADS1015_Read(u8 channel);//ADS1015读数据函数,参数channel
AD1015_Check(u8 i2cAddress);//检查芯片是够存在函数,这个函数可以让我们知道 是否单片机与芯片通信成功,成功返回0否者返回1。
关于STM32F103C8T6的驱动例程已上传,大家可以自行下载。
需要注意的是ADS1015_Read(u8 channel)函数读不同通道时至少要延时1毫秒。