绝对压力的检测是常见的需求。在我们的系统中也常常会遇到。而ms5837压力传感器也是我们进场会采用的方案。在这篇里我们将讨论并实现ms5837压力传感器的驱动。
1 、功能概述ms5837压力传感器是一种可用于电路板上,适用于检测10-1200mbar压力范围的传感器,灵敏度非常高,理论上能够检测到0.01mbar的压力变化,实际使用过程中测试并无明显的变化。
ms5837压力传感器采用i2c总线通讯,与mcu可以实现i2c通讯。硬件连接方式如下:
ms5837压力传感器拥有5类基本命令:复位、读取出厂校准值、数据1转换(压力值数据)、数据2转换(温度值数据)和读取adc的转换结果。具体分配如下:
因为ms5837的地址是固定的,所以一个i2c总线只能挂1个ms5837模块。其设备地址固定为:0xec。
2 、驱动设计与实现我们已经了解了ms5837的基本功能和操作方式。接下来我们就根据前面的分析实现ms5837的驱动。
2.1 、对象定义
在使用该对象之前,我们需要定义对象,我们根据ms5837的属性和操作来定义对象。
2.1.1 、对象类型抽象为了方便操作与复用,我们使用基于对象的操作。这里我们先来抽象ms5837压力传感器对象的类型,该类型包含了ms5837的必要属性和对ms5837基本操作。
我们先来分析ms5837压力传感器对象的属性。ms5837压力传感器使用的是i2c通讯接口,需要一个地址分辨总线上的不同设备,所以我们将i2c设备地址作为ms5837压力传感器对象的一个属性。此外,在计算ms5837压力传感器测量的压力、温度值时需要使用6个校准参数,而且这些参数每台设备都是不一样的,所以我们将这些参数作为属性来保存其值。
接下来我们再来分析ms5837压力传感器对象的操作。我们使用ms5837压力传感器时,需要向其写命令和从其读数据,而读写操作都依赖于具体的硬件平台,所以我们将写数据和读数据作为对象的操作。此外,为控制时序,我们需要延时操作,而延时行为的实现亦依赖于具体的软硬件平台,所以我们将延时也作为对象的操作。
根据上述我们对ms5837压力传感器对象的分析,我们可以抽象ms5837压力传感器的对象类型为:
1 /* 定义ms5837对象类型 */ 2 typedef struct ms5837object { 3 uint8_t devaddress; //设备地址 4 uint16_t calidata[6]; //校准数据 5 float temperature; 6 float pressure; 7 void (*write)(struct ms5837object *ms,uint8_t command);/*向ms5837下发指令,指令格式均为1个字节*/ 8 void (*read)(struct ms5837object *ms,uint8_t *rdata,uint16_t rsize);/*从ms5837读取多个字节数据的值*/ 9 void (*delayms)(volatile uint32_t ntime); //毫秒秒延时函数10 }ms5837objecttype;2.1.2 、对象初始化在使用之前,我们先要使用对象类型声明对象,但声明的对象只是一个变量,该对象变量在使用前必须初始化,所以我们定义了对象初始化函数。
1 /* 初始化ms5837对象 */ 2 void ms5837initialization(ms5837objecttype *ms,ms5837write write,ms5837read read,ms5837delayms delay) 3 { 4 if((ms==null)||(write==null)||(read==null)||(delay==null)) 5 { 6 return; 7 } 8 9 ms->write=write;10 ms->read=read;11 ms->delayms=delay;12 13 ms->devaddress=0b11101100;14 ms->pressure=0.0;15 ms->temperature=0.0;16 17 resetforms5837(ms);18 19 getcalibrationdata(ms);20 }2.2 、对象操作完成了对象的声明与初始化之后,我们就可以使用对象变量来操作对象了。关于ms5837的操作主要有:设备复位、校准值获取、转换值的读取。下面将一一实现。
2.2.1 、复位操作复位操作在ms5837压力传感器有电时就可执行,但一般会在上电之后需要复位一下,以保持内存中的校准参数值是正确的。此外,当i2c的sda引脚因未知原因出现阻塞时,复位能消除这种不确定性。复位操作只需要发送一条命令,其时序图如下:
1 /*复位ms5837操作*/2 void resetforms5837(ms5837objecttype *ms)3 {4 uint8_t command=command_reset;5 6 /*下发复位命令*/7 ms->sendcommand(ms,command);8 }2.2.2 、读取校准值校准值是出厂时厂家校准的各种系数,每台设备都有差异,是固定不变的,只需要一次读取就可以了,共有6个系数,均为16为整数。首先发送读系数的命令,然后读取就可以了,每次读取1个,分6次读取。过程数据流如下图所示:
1 /*读取ms5837内存寄存器的数据*/ 2 static uint16_t readpromfromms5837(ms5837objecttype *ms,uint8_t command) 3 { 4 /*下发读取指定内存单元的命令*/ 5 ms->write(ms,command); 6 7 /*接收读取的指定内存单元的值*/ 8 uint8_t promvalue[2]; 9 ms->read(ms,promvalue,2);10 11 uint16_t result=(uint16_t)promvalue[0];12 result=(result
delayms(10); 9 10 /*下发读取adc的命令*/11 ms->write(ms,command_adc_read);12 13 ms->delayms(10);14 15 /*接收读取的adc转换结果*/16 uint8_t adcvalue[3];17 ms->read(ms,adcvalue,3);18 19 uint32_t result=(uint32_t)adcvalue[0];20 result=(result<<8)+(uint32_t)adcvalue[1];21 result=(resultdevaddress,rdata,rsize,1000);11 }对于延时函数我们可以采用各种方法实现。我们采用的stm32平台和hal库则可以直接使用hal_delay()函数。于是我们可以调用初始化函数如下:
ms5837initialization(&ms5837,sendcommandtoms5837,getdatasfromms5837,hal_delay);
3.2 、基于对象进行操作我们定义了对象变量并使用初始化函数给其作了初始化。接着我们就来考虑操作这一对象获取我们想要的数据。我们在驱动中已经将获取数据并转换为转换值的比例值,接下来我们使用这一驱动开发我们的应用实例。
1 /*获取压力变送器数据*/ 2 void ms5837getmeasuredata(void) 3 { 4 float pressure=0.0; 5 float temperature=0.0; 6 7 getms5837conversionvalue(&ms5837,ms5837_osr8192,ms5837_osr8192); 8 9 pressure=ms5837.pressure;10 temperature=ms5837.temperature;11 }4 、应用总结我们已经实现了ms5837压力传感器的驱动程序,也设计了一个简单的应用来验证这一驱动程序。验证的结果与我们预期一样,得到了我们需要的数据。我们也曾将这一驱动应用于实际项目,效果也是令人满意的。
使用驱动是需要注意,ms5837压力传感器虽然采用了i2c接口,但它的地址是固定的,所以一条总线上只能有一台ms5837压力传感器。所以在驱动中地址是固化在驱动程序中不可修改的。
源码下载: https://github.com/foxclever/experiphdriver
RX65T125HS1B功率晶体管的原理与应用
国网信通公司将从哪些方面支撑泛在电力物联网建设
2020年上半年中国电信实现经营收入为人民币1938.03亿元
今日传感财经:仪电仪表概念报涨;物联网设备概念报跌;红外传感概念报跌
基于Wi-Fi模块/MCU的智能建筑物联网应用设计
MS5837压力传感器的驱动设计与实现
高续航高音质的蓝牙耳机,高性价比的蓝牙耳机推荐
晶体振荡器(晶振)的缩写说明
安森美半导体推出业界首款3:1高速USB开关-NCN1188
道康宁TC-4015替代品GLPOLY导热胶XK-S12不同
想学激光切割必须掌握的基础知识!
康普推出全新Propel平台,驱动数据中心迈向未来
腾讯看好英国外卖行业准备进军英国外卖行业
人工智能驱动的绩效改进策略
马自达将推中国特供电动车:续航400公里
SIC MOSFET在电路中的作用是什么?
低压电容补偿柜加装电抗器的作用
直链淀粉分析仪的使用方法是怎样的
15个锂电材料项目简介
FPGA可以提供更好的波束赋形性能