STM32F103RCT6实验代码之ADS1115的使用

自己写的ads1115代码
重点是对于ADS1115的配置,IIC只是粗略的介绍

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)
				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[i]=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上时所测得的数据
代码放在了文章开头

  • 8
    点赞
  • 54
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值