ADS1115是16位ADC,基准源内部可选,PGA 可提供从 ±256mV 到 ±6.144V 的输入范围。
地址可由ADDR引脚决定,一般接地,地址为0x90
写寄存器地址为0x90,读寄存器地址为0x91
ADS1115有4个控制寄存器,0x00,0x01,0x02
0x00
0x01:配置通道、增益、基准源等
0x02
读数据流程:
(1)发送地址0x90
(2)发送0x01寄存器地址( 配置通道等)
(3)发送0x01地址中高位数据
(4)发送0x01地址中低位数据
(5)发送地址0x90
(6)发送0x00寄存器地址
(7)发送地址0x91(表示读数据)
(8)读该通道数据
模拟IIC代码
#include <STC15F2K60S2.h>
#include <stdio.h>
#define uchar unsigned char
#define uint unsigned int
sbit SDA = P1^5; // I2C数据线
sbit SCL = P1^4; // I2C时钟线
sbit ADDR = P1^6;
sbit ALRT = P1^7;
//延时替换掉,我用的是12T IAP15F2K60S2是1T
void delay5us(uint x) //延时5us
{
uint y;
uchar a;
for(y=0;y<x;y++)
for(a=1;a>0;a--);
}
void delay_ms(uint x) //延时1ms
{
uint y;
unsigned char a,b;
for(y=0;y<x;y++)
for(b=199;b>0;b--)
for(a=1;a>0;a--);
}
//延时替换掉,我用的是12T IAP15F2K60S2是1T
/**
* 函数功能: CPU发起I2C总线启动信号
* 输入参数: 无
* 返 回 值: 无
* 说 明:无
*/
void I2C_Start(void)
{
/* 当SCL高电平时,SDA出现一个下跳沿表示I2C总线启动信号 */
SDA = 1;
SCL = 1;
delay5us(1);
SDA = 0;
delay5us(1);
SCL = 0;
delay5us(1);
}
/**
* 函数功能: CPU发起I2C总线停止信号
* 输入参数: 无
* 返 回 值: 无
* 说 明:无
*/
void I2C_Stop(void)
{
/* 当SCL高电平时,SDA出现一个上跳沿表示I2C总线停止信号 */
SDA = 0;
SCL = 1;
delay5us(1);
SDA = 1;
}
/**
* 函数功能: CPU向I2C总线设备发送8bit数据
* 输入参数: Byte : 等待发送的字节
* 返 回 值: 无
* 说 明:无
*/
void I2C_SendByte(uchar Byte)
{
uchar i;
/* 先发送字节的高位bit7 */
for (i = 0; i < 8; i++)
{
if (Byte & 0x80)
{
SDA = 1;
}
else
{
SDA = 0;
}
delay5us(1);
SCL = 1;
delay5us(1);
SCL = 0;
if (i == 7)
{
SDA = 1; // 释放总线
}
Byte <<= 1; /* 左移一个bit */
delay5us(1);
}
}
/**
* 函数功能: CPU从I2C总线设备读取8bit数据
* 输入参数: 无
* 返 回 值: 读到的数据
* 说 明:无
*/
uchar I2C_ReadByte(uchar ack)
{
uchar i;
uchar value;
/* 读到第1个bit为数据的bit7 */
value = 0;
for (i = 0; i < 8; i++)
{
value <<= 1;
SCL = 1;
delay5us(1);
if (SDA)
{
value++;
}
SCL = 0;
delay5us(1);
}
if(ack==0)
I2C_NAck();
else
I2C_Ack();
return value;
}
/**
* 函数功能: CPU产生一个时钟,并读取器件的ACK应答信号
* 输入参数: 无
* 返 回 值: 返回0表示正确应答,1表示无器件响应
* 说 明:无
*/
uchar I2C_WaitAck(void)
{
uchar re;
SDA = 1; /* CPU释放SDA总线 */
delay5us(1);
SCL = 1; /* CPU驱动SCL = 1, 此时器件会返回ACK应答 */
delay5us(1);
if (SDA) /* CPU读取SDA口线状态 */
{
re = 1;
}
else
{
re = 0;
}
SCL = 0;
delay5us(1);
return re;
}
/**
* 函数功能: CPU产生一个ACK信号
* 输入参数: 无
* 返 回 值: 无
* 说 明:无
*/
void I2C_Ack(void)
{
SDA = 0; /* CPU驱动SDA = 0 */
delay5us(1);
SCL = 1; /* CPU产生1个时钟 */
delay5us(1);
SCL = 0;
delay5us(1);
SDA = 1; /* CPU释放SDA总线 */
}
/**
* 函数功能: CPU产生1个NACK信号
* 输入参数: 无
* 返 回 值: 无
* 说 明:无
*/
void I2C_NAck(void)
{
SDA = 1; /* CPU驱动SDA = 1 */
delay5us(1);
SCL = 1; /* CPU产生1个时钟 */
delay5us(1);
SCL = 0;
delay5us(1);
}
uchar Read_Reg1(uchar dev_add,uchar RegIndex)
{
uchar receive=0;
I2C_Start();
I2C_SendByte(dev_add);
I2C_WaitAck();
I2C_SendByte(RegIndex);
I2C_WaitAck();
I2C_Start();
I2C_SendByte(dev_add+1);
I2C_WaitAck();
receive=I2C_ReadByte(0);
I2C_Stop();
return receive;
}
void IIC_Write_Reg(uchar dev_add,uchar RegIndex,uchar data1)
{
I2C_Start();
I2C_SendByte(dev_add);
I2C_WaitAck();
I2C_SendByte(RegIndex);
I2C_WaitAck();
I2C_SendByte(data1);
I2C_WaitAck();
I2C_Stop();
}
ADS1115代码
/*****************Pointer Register*************/
#define REG_Conversion 0x00
#define REG_config 0x01
#define REG_L_thresh 0x02
#define REG_H_thresh 0x03
/*****************Conversion Register**********/
//存放着16位结果
/*****************Config Register**********/
#define OS 1 //Operational status or single-shot conversion start操作状态或单发转换启动
#define MUX 0x04 //[2:0]Input multiplexer configuration输入多路配置
#define PGA 0x01 //Programmable gain amplifier configuration可编程增益放大器配置
#define MODE 0x00 //Device operating mode设备运行方式
#define DR 0x04//Data rate/数据速率
#define COMP_MODE 0 // Comparator mode比较器模式
#define COMP_POL 0 //Comparator polarity/比较器极性
#define COMP_LAT 0 //Latching comparator
#define COMP_QUE 0x3 //Comparator queue and disable
#define config_MSB (OS << 7)|(MUX << 4)|(PGA << 1)|(MODE)//0xC2
#define config_LSB (DR << 5)|(COMP_MODE << 4)|(COMP_POL << 3)|(COMP_LAT << 2)|(COMP_QUE)
/*****************Lo_thresh Register**********/
#define Lo_thresh 0x8000 // Low threshold value
#define Hi_thresh 0x7FFF // High threshold value
void ADS1115_Write(uchar Reg , uchar reg_MSB , uchar reg_LSB)
{
I2C_Start(); // 起始信号
I2C_SendByte(0x90+0); // 0x90地址+0写位
while(I2C_WaitAck()); // 等待应答信号,低电平有效
I2C_SendByte(Reg); // 发送0x01寄存器地址( 配置通道等)
while(I2C_WaitAck()); // 等待应答信号,低电平有效
I2C_SendByte(reg_MSB); // 发送0x01地址中高位数据
while(I2C_WaitAck()); // 等待应答信号,低电平有效
I2C_SendByte(reg_LSB); // 发送0x01地址中低位数据
while(I2C_WaitAck()); // 等待应答信号,低电平有效
I2C_Stop(); // 停止信号
}
float ADS1115_ReadAD()
{
float ret;
uint data1;
I2C_Start(); // 起始信号
I2C_SendByte(0x90+0); // 0x90地址+0写位
while(I2C_WaitAck()); // 等待应答信号,低电平有效
I2C_SendByte(REG_Conversion); // 发送0x00寄存器地址
while(I2C_WaitAck()); // 等待应答信号,低电平有效
I2C_Stop(); // 停止信号
delay5us(1);
I2C_Start(); // 起始信号
I2C_SendByte(0x90+1); // 0x90地址+1读位
while(I2C_WaitAck()); // 等待应答信号,低电平有效
data1 = I2C_ReadByte(1); // 读前8位
data1 = (data1 << 8)&0xff00; // 前8位
data1+= I2C_ReadByte(1); // 读后8位
I2C_Stop(); // 停止信号
//数值计算取决于PGA配置 PGA:FSR = ±4.096 V(1)
if(data1>0x8000)
ret=((float)(0xffff-data1)/32768.0)*4.096;
else
ret=((float)data1/32768.0)*4.096;
return ret;
}
void ADS115_config(uchar channel)//channel表示通道 0-3
{
ADS1115_Write(REG_config, config_MSB|(channel<<4) ,config_LSB);
}
串口代码
void UartInit() // 9600bps@11.0592MHz
{
PCON &= 0x7F; // 波特率不倍速
SCON = 0x40; // 8位数据,仅用于发送
TMOD &= 0x0F; // 清除定时器1模式位
TMOD |= 0x20; // 设定定时器1为8位自动重装方式
TL1 = 0xFD; // 设定定时初值
TH1 = 0xFD; // 设定定时初值
ET1 = 0; // 禁止定时器1中断
TR1 = 1; // 启动定时器1
}
void UART_SendByte(unsigned char Byte)//串口发送一个字节数据
{
SBUF=Byte;
//检测是否完成
while(TI==0);
TI=0;//TI复位
}
void UART_String(unsigned char *str)//串口发送一个字符串
{
while(*str!='\0')
{
UART_SendByte(*str++);
}
}
主函数代码
void main()
{
uint Vol;// 电压值
uint x; // 通道累加,0-3
ADDR = 0;
ALRT = 0;
UartInit();//换成自己的串口
while(1)
{
x=3;
ADS115_config(x); //选通道,0-3
Vol=ADS1115_ReadAD()*1000;
UART_String("Vol");
UART_SendByte(x+48);
UART_String(":");
UART_SendByte(Vol/1000+48);
UART_SendByte(Vol%1000/100+48);
UART_SendByte(Vol%1000%100/10+48);
UART_SendByte(Vol%1000%100%10+48);
UART_String("mv\r\n");
delay_ms(1000);
}
}