完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
2个回答
|
|
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的配置大概分为四步 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] 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上时所测得的数据。 |
|
|
|
有编译的ads1115代码吗,51单片机的
|
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1820 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1634 浏览 1 评论
1104 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
740 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1692 浏览 2 评论
1951浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
756浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
587浏览 3评论
606浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
571浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-31 06:11 , Processed in 0.916673 second(s), Total 80, Slave 64 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号