ADS1015使用指南及STM32驱动程序
ADS1015使用指南及驱动程序
- ADS1015使用指南
- 简介
- ADS1015的引脚介绍
- 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 valuesADS1015_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 rangeADS1015_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' bitADS1015_CONFIG |= ADS1015_REG_CONFIG_OS_SINGLE;// Write config register to the ADCADS1015_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-3u16 ADS1015_Read(u8 channel){int temp;// Start with default valuesADS1015_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 rangeADS1015_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' bitADS1015_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"//初始化IICvoid 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 highdelay_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;elseIIC_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();//发送nACKelseIIC_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毫秒。