STM32
直播中

恐龙之家

8年用户 788经验值
私信 关注
[问答]

ADS1115是什么?怎样去使用ADS1115呢

ADS1115是什么?ADS1115有哪些特性?怎样去使用ADS1115呢?



回帖(2)

李捷

2021-12-14 11:41:40
ADS1115的使用

ADS1115概况

ads1115是一款低功耗16位的ADC
四路的输入,分别是:A0,A1,A2,A3
供电引脚:VDD
地:GND
与其他设备通信:SCL,SDA
地址:ADDR
比较器的结果输出:ALERT(简单应用一般用不到)
一般VDD与GND的压差为2-5.5V
ADDR接在不同的位置上时的地址是不同的

ADS1115与单片机的连线:
VDD——>单片机的3.3/5V
GND——>单片机的GND
ADDR——>一般与地相连
A0-3——>与输入的电压线相连
SCL,SDA——>单片机的SCL,SDA
ALERT——>悬空
IIC介绍

IIC是一种半双工通信协议,同一时间内只能收或者发。
一般有四种信号:开始信号,结束信号,nck信号,nack信号。
开始信号

开始信号为时钟线为高时拉低SDA线





表示IIC开始
正点原子代码:

void IIC_Start(void)
{
        PB10OUT();     //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总线,准备发送或接收数据
}          
   

结束信号

结束信号为时钟线为高是拉高SDA





表示IIC通信结束
正点原子代码:

//产生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);                                                                  
}


ack信号

ack信号是产生一个应答信号,在接收到设备的信号后产生ack信号给发出的设备,让发出设备知道已经被接受了
正点原子代码:

//产生ACK应答
void IIC_Ack(void)
{
        IIC_SCL=0;
        PB10OUT();
        IIC_SDA=0;
        delay_us(2);
        IIC_SCL=1;
        delay_us(2);
        IIC_SCL=0;
}


nack信号

nack信号是不产生应答信号
正点原子代码:

//不产生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;
}                                                                           
读数据

读数据步骤
1.产生IIC开始信号
2.发送地址
3.发送读操作命令(2.3合在一起为8位)
4.等待接受应答
5.读数据
6.产生结束信号
写数据

1.产生IIC开始信号
2.发送地址
3.发送写操作命令(2.3合在一起为8位)
4.等待接受应答
5.写数据
6.产生结束信号
以上是IIC的大概介绍,只是让大家对下面的代码好理解

代码讲解


  ADS1115的配置大概分为四步
一.对Lo_thresh 和 Hi_thresh 寄存器的配置
这个寄存器应该是配置读取的电压正负,如果读取正电压的话一般不用配置,我这里就没有对这个寄存器进行配置。
二.对config寄存器进行配置
对config寄存器配置需要几步
1.写入地址
2.通过操作pointer寄存器来指向config寄存器
3.写入config寄存器的高位
4.写入config寄存器的低位

void ads_init()
{
        delay_init();


        address_ads=address_gnd+write;
        config=Pointer_1;
        config_H=os_1+mux_7+fs_0+mode_0;//配置ads1115的模式(高位)
        config_L=dr_7+comp_mode_0+comp_pol_0+comp_lat_0+comp_que_3;//配置ads1115的模式(低位)


        IIC_Init();
        IIC_Start();
        /*写地址ads1115*/
        IIC_Send_Byte(address_ads);
        IIC_Wait_Ack();
        delay_ms(20);
        /*写ADS1115数据,用pointer寄存器来配置config寄存器*/
        IIC_Send_Byte(config);
        IIC_Wait_Ack();
        delay_ms(20);
        /*写ADS1115数据,写config寄存器高位*/
        IIC_Send_Byte(config_H);
        IIC_Wait_Ack();
        delay_ms(20);
        /*写ADS1115数据,写config寄存器低位*/
        IIC_Send_Byte(config_L);
        IIC_Wait_Ack();
        delay_ms(20);
        IIC_Stop();


}
对于config寄存器,ti官网的数据手册里有










一般着重配置mux,pga,dr这几个寄存器
三.配置Conversion寄存器
这一步主要是用pointer指向conversion寄存器

void ads_read()
{
        address_ads=address_gnd+write;
        config_1=Pointer_0;
        delay_init();
       
        IIC_Init();
        IIC_Start();
/*写地址ads1115*/
        IIC_Send_Byte(address_ads);
        IIC_Wait_Ack();
        delay_ms(20);
        /*写ADS1115 配置寄存器*/
        IIC_Send_Byte(config_1);
        IIC_Wait_Ack();
        delay_ms(20);
        IIC_Stop();




}
这是pointer寄存器





四.开始读数据
这一步开始对ads1115里采样到的数据开始处理

float ads_write()
{
        uart_init(9600);
        delay_init();
        address_ads_r=address_gnd+read;
        IIC_Init();
        IIC_Start();
        /*写地址ads1115*/
        IIC_Send_Byte(address_ads_r);
        delay_ms(20);
        IIC_Wait_Ack();
/*读取ADS1115的第一个字节*/       
        result_0=IIC_Read_Byte(1);
        delay_ms(20);
/*读取ADS1115的第二个字节*/               
        result_1=IIC_Read_Byte(1);
       
        IIC_Stop();
        res_0=result_0;
        res_1=result_1;
        result=res_0*256+res_1;
/*返回读取到的数据*/
        return result;
       
}
因为数据一共有16位所以分两次来读写。
数据处理:为了数据稳定我采用了滤波的方法,其实滤波与否影响不大。我采用了中位值平均滤波,这也是学长所建议的。

/*寻找数据最大值*/
float max_find(float a[10])
{
       
        int j;
float        max=-999;
        for(j=0;j<10;j++)
                {
                        if(a[j]>max)
                                max=a[j];
                        else
                                max=max;
                }
                return max;
}
/*寻找数据最小值*/


float min_find(float a[10])
{
       
        int j;
        float min=99999;
        for(j=0;j<10;j++)
                {
                        if(a[j]                                 min=a[j];
                        else
                                min=min;
                }
                return min;
}


/*中位值平均滤波算法*/
/*去除最高数,去除最低数取平均*/
float adv()
{
        delay_init();
float        value[10];
        int i,max,min,count;
        float sum;
        for(i=0;i<10;i++)
                {
                        delay_us(15);
                        value=ads_write();
                }


                max=max_find(value);
                min=min_find(value);
               
                for(count=0;count<10;count++)
                {
                        sum+=value[count];
                }
                sum=sum-max-min;
                sum=sum/8;
                return sum;
}
我定义了两个函数,一个是寻最大值,一个是寻最小值,最后删去这两个数取平均。
下面的函数是最终要调用到main主函数里的函数

/*最终返回到主函数的函数,在main函数里调用*/
float ads1115()
{
                float tem,dianya;
                        tem=adv();
                if(tem>=0x8000)  
                        dianya=((float)(0xffff-tem)/32768.0)*6.144;
                else
                        dianya=((float)tem/32768.0)*6.144;
                        delay_ms(10);


                return dianya;
}
这就是整体代码的思路,其中IIC通信的部分我用了正点原子的库。
下面是我的.h文件

#ifndef _1115_H_
#define _1115_H_


#define address_gnd 0x90


#define read 0x01
#define write 0x00




#define Pointer_0  0x00   
#define Pointer_1  0x01   


#define os_1 0x80
#define os_0 0x00




#define mux_0 0x00    //AINp=AIN0, AINn=AIN1
#define mux_1 0x10    //AINp=AIN0, AINn=AIN3
#define mux_2 0x20    //AINp=AIN1, AINn=AIN3
#define mux_3 0x30    //AINp=AIN2, AINn=AIN3
#define mux_4 0x40    //AINp=AIN0 , AINn=GND
#define mux_5 0x50    //AINp=AIN1, AINn=GND
#define mux_6 0x60    //AINp=AIN2, AINn=GND
#define mux_7 0x70    //AINp=AIN3, AINn=GND  更改通道需要更改mux的值




#define fs_0 0x00                         //FS=6.144V
#define fs_1 0x20      //FS=4.096V
#define fs_2 0x40     //FS=2.048V
#define fs_3 0x60     //FS=1.024V
#define fs_4 0x80     //FS=0.512V
#define fs_5 0xA0     //FS=0.256V
#define fs_6 0xC0     //FS=0.256V
#define fs_7 0xE0     //FS=0.256V




#define mode_0 0x00
#define mode_1 0x01




#define dr_0   0x00   //Data Rate = 8
#define dr_1   0x20   //Data Rate = 16
#define dr_2   0x40   //Data Rate = 32
#define dr_3   0x60   //Data Rate = 64
#define dr_4   0x80   //Data Rate = 128
#define dr_5   0xA0   //Data Rate = 250
#define dr_6   0xC0   //Data Rate = 475
#define dr_7   0xE0   //Data Rate = 860


#define comp_mode_0  0x00
#define comp_mode_1  0x10
                               
#define comp_pol_0   0x00
#define comp_pol_1   0x08
                               
#define comp_lat_0   0x00
#define comp_lat_1   0x40
                               
#define comp_que_0   0x00
#define comp_que_1   0x01
#define comp_que_2   0x02
#define comp_que_3   0x03
                                                 


float ads_write(void);
void ads_read(void);
void ads_init(void);
float adv(void);
float min_find(float value[10]);
float max_find(float value[10]);
float ads1115(void);


#endif
如果需要更改输入的端口的话可以选择更改MUX的部分
config_H=os_1+mux_7+fs_0+mode_0;//配置ads1115的模式(高位)

PS:ADDR接地时,地址数据是0x90

通过上面的配置就可以正常使用ADS1115了





这是我把输入接到3.3V上时所测得的数据。
举报

sgzj

2024-5-11 22:03:30
有编译的ads1115代码吗,51单片机的
举报

更多回帖

×
20
完善资料,
赚取积分