MS5837压力传感器是一种可用于电路板上,适用于检测10-1200mbar压力范围的传感器,灵敏度非常高,理论上能够检测到0.01mbar的压力变化,实际使用过程中测试并无明显的变化。

MS5837采用I2C总线通讯,与STM32的MCU可以实现I2C通讯。硬件连接方式如下:

MS5837只有5个基本命令:复位、读取出厂校准值、数据1转换(压力值数据)、数据2转换(温度值数据)和读取ADC的转换结果。具体分配如下:

因为MS5837的地址是固定的,所以一个I2C总线只能挂1个MS5837模块。为了让程序具有较好的可移植性,我们在便写程序时不使用对硬件的直接操作,而采用函数指针来操作,所以我们定义了:

/*向MS5837下发指令,指令格式均为1个字节*/

typedef void (*WriteCommandToMs5837Type)(uint8_t deviceAddress,uint8_t command);

/*从MS5837读取多个字节数据的值*/

typedef void (*ReadBytesFromMs5837Type)(uint8_t deviceAddress,uint8_t *pData,uint16_t bytesNum);

以上两个函数指针来实现针对硬件的读写操作。接下来我们开始编写代码。

1)复位操作

复位操作的数据流如下图所示,只需要发送一条命令就可完成:

/*复位MS5837操作*/void ResetForMs5837(uint8_t deviceAddress,WriteCommandToMs5837Type WriteCommandToMs5837){uint8_t command=COMMAND_RESET;/*下发复位命令*/WriteCommandToMs5837(deviceAddress,command);}

2)读取校准值

校准值是出厂时厂家校准的各种系数,每台设备都有差异,是固定不变的,只需要一次读取就可以了,共有6个系数,均为16为整数。首先发送读系数的命令,然后读取就可以了,每次读取1个,分6次读取。过程数据流如下图所示:

/*从MS5837的PROM中读取校准数据*/void GetCalibrationData(uint8_t deviceAddress,uint16_t *caliPara,WriteCommandToMs5837Type WriteCommandToMs5837,ReadBytesFromMs5837Type ReadBytesFromMs5837){/*C1压力灵敏度*/caliPara[0]=ReadPromFromMs5837(deviceAddress,COMMAND_PROM_READ_C1,WriteCommandToMs5837,ReadBytesFromMs5837);/*C2压力补偿值*/caliPara[1]=ReadPromFromMs5837(deviceAddress,COMMAND_PROM_READ_C2,WriteCommandToMs5837,ReadBytesFromMs5837);/*C3压力灵敏度温度系数*/caliPara[2]=ReadPromFromMs5837(deviceAddress,COMMAND_PROM_READ_C3,WriteCommandToMs5837,ReadBytesFromMs5837);/*C4压力补偿温度系数*/caliPara[3]=ReadPromFromMs5837(deviceAddress,COMMAND_PROM_READ_C4,WriteCommandToMs5837,ReadBytesFromMs5837);/*C5参考温度*/caliPara[4]=ReadPromFromMs5837(deviceAddress,COMMAND_PROM_READ_C5,WriteCommandToMs5837,ReadBytesFromMs5837);/*C6温度传感器温度系数*/caliPara[5]=ReadPromFromMs5837(deviceAddress,COMMAND_PROM_READ_C6,WriteCommandToMs5837,ReadBytesFromMs5837);}

3)读取转换值

读取转换结果值是我们的目的,可以读取温度和压力两个量,不过一次只能读一个。首先发送命令设定采集压力还是温度,并设定精度。然后发送读取的命令,最后读取对应的值。再使用校准系数计算出最终的物理值。

/*获取转换值,包括温度和压力*/void GetConversionValue(uint8_t deviceAddress,float *pPres,float *pTemp,uint16_t *caliPara,uint16_t *semaphore,WriteCommandToMs5837Type WriteCommandToMs5837,ReadBytesFromMs5837Type ReadBytesFromMs5837){uint16_t senst1;        //C1压力灵敏度
uint16_t offt1;         //C2压力补偿值
uint16_t tcs;           //C3压力灵敏度温度系数
uint16_t tco;           //C4压力补偿温度系数
uint16_t tref;          //C5参考温度
uint16_t tempsens;      //C6温度传感器温度系数/*从MS5837的PROM中读取校准数据*/if(*semaphore>0){GetCalibrationData(deviceAddress,caliPara,WriteCommandToMs5837,ReadBytesFromMs5837);*semaphore=*semaphore-1;}senst1=caliPara[0];offt1=caliPara[1];tcs=caliPara[2];tco=caliPara[3];tref=caliPara[4];tempsens=caliPara[5];uint32_t digitalPressureValue;uint32_t digitalTemperatureValue;/*读取压力数据*/digitalPressureValue=ReadConversionFromMs5837(deviceAddress,COMMAND_CONVERTD1OSR4096,WriteCommandToMs5837,ReadBytesFromMs5837);Delayms(20);/*读取温度数据*/digitalTemperatureValue=ReadConversionFromMs5837(deviceAddress,COMMAND_CONVERTD2OSR4096,WriteCommandToMs5837,ReadBytesFromMs5837);/*对温度进行一阶修正*/int32_t dT;int32_t temp;dT=digitalTemperatureValue-tref*256;temp=(int32_t)(2000+dT*tempsens/pow(2,23));/*对压力进行一阶修正*/int64_t off;int64_t sens;int32_t pres;off=(int64_t)(offt1*pow(2,17)+(tco*dT)/pow(2,6));sens=(int64_t)(senst1*pow(2,16)+(tcs*dT)/pow(2,7));pres=(int32_t)((digitalPressureValue*sens/pow(2,21)-off)/pow(2,15));/*对温度和压力进行二阶修正*/int64_t ti=0;int64_t offi=0;int64_t sensi=0;int64_t off2=0;int64_t sens2=0; if(temp<2000){ti=(int64_t)(11*dT*dT/pow(2,35));offi=(int64_t)(31*(temp-2000)*(temp-2000)/pow(2,3));sensi=(int64_t)(63*(temp-2000)*(temp-2000)/pow(2,5));off2=off-offi;sens2=sens-sensi;temp=temp-(int32_t)ti;pres=(int32_t)((digitalPressureValue*sens2/pow(2,21)-off2)/pow(2,15));}if((-4000<=temp)&&(temp<=8500)){*pTemp=(float)temp/100.0;}if((1000<=pres)&&(pres<=120000)){*pPres=(float)pres/100.0;}}

最终在STM32的I2C接口实现通讯时,实现2个WriteCommandToMs5837Type(uint8_t deviceAddress,uint8_t command);和ReadBytesFromMs5837Type(uint8_t deviceAddress,uint8_t *pData,uint16_t bytesNum);函数并调用就可以了,换做其他的平台也只需要重写这两个函数就能实现通讯了。

转载于:https://www.cnblogs.com/foxclever/p/6533907.html

STM32应用实例六:与MS5837压力传感器的I2C通讯相关推荐

  1. STM32与MS5837压力传感器的I2C通讯

    MS5837压力传感器是一种可用于电路板上,适用于检测10-1200mbar压力范围的传感器,灵敏度非常高,理论上能够检测到0.01mbar的压力变化,实际使用过程中测试并无明显的变化. MS5837 ...

  2. C语言库函数大全及应用实例六

    C语言库函数大全及应用实例六 原文:C语言库函数大全及应用实例六                                              [编程资料]C语言库函数大全及应用实例六 函 ...

  3. STM32项目(六)—— 中文电子捡货标签

    STM32项目(六)-- 中文电子捡货标签 宗旨:技术的分享是有限的,分享的精神是无限的. 传统物流行业仓储拣货采用纸单作业,拣货完成后再进行验货.出货,容易造成拣货错误.拣货速度与效率低.新员工培训 ...

  4. python程序题斐波那契数列通项公式,Python斐波那契数列应用,编程练习题实例六...

    python斐波那契数列,本文是关于Python编程练习题和答案实例六,斐波那契数列应用的示例.引用百度关于斐波那契数列的介绍,大家先简单来的了解下,什么是斐波那契数列? 斐波那契数列(Fibonac ...

  5. 实例六 自动售饮料机

    实例六 自动售饮料机 3.2.1. 本章导读 了解自动售货机的工作流程以及各个工作状态,以及其testbench,最后在Robei可视化仿真软件经行功能实现和仿真验证. 设计原理 自动售货机的信号定义 ...

  6. Docker系列(二十四)——Docker实例六Docker安装Redis实例

    < Docker实例三Docker安装Redis实例 > 前言 在前面一篇文章种,完成了 < Docker安装MongoDB实例 >,本篇将继续镜像安装教程,并完成Docker ...

  7. 【科普贴】I2C通讯协议详解——偏软件分析和逻辑分析仪实例分析

    一. I2C标准协议流程 1. I2C协议--规定命令 开始:当SCL为高电平时,SDA从高电平向低电平切换 停止:当SCL为高电平时,SDA从低电平向高电平切换 应答(ACK):发送侧发送完8bit ...

  8. c# iot .net6 树莓派 i2c通讯 读取温湿传感器 芯片sht30代码实例

    这里用c# .net 6 树莓派 i2c通讯 读取温湿传感器 芯片sht30 实例 设备: 1.温湿度传感器sht30 2.树莓派 设备在某宝上可以选购得到 nuget下载引用: Iot.Device ...

  9. linux IIC子系统分析(九)——实例分析通过设备节点访问I2c设备

    在< linux IIC子系统分析(四)--I2c bus初始化> 中我们创建了I2C 总线驱动,I2C adapter device 和adapter drivers也在这时创建 在&l ...

最新文章

  1. vue与php通过axios进行数据交互
  2. jquery动态加载问题
  3. VisualStudio代码样式-我最喜欢的一种风格
  4. 15 JS应用-todolist任务
  5. 使用canvas绘制楼梯(canvas直线绘制练习)
  6. 第5篇:Flowable快速工作流脚手架Jsite_请假实战_部署流程和发起流程
  7. html层次选择器例题,详解强大的jQuery选择器之基本选择器、层次选择器
  8. 台式计算机光标时不时跳动,解决方案:如何解决联想笔记本触摸板上的光标跳动?...
  9. Android开发笔记(三十八)列表类视图
  10. python 将多张大小不同的图依次放入较大的黑色背景_用户消费行为分析(Python)...
  11. java日常日志打印模板
  12. smart原则_OKR 文化:用 SMART 原则量化目标
  13. android usb 摄像头 驱动开发,自制USB摄像头硬件的驱动编写_修改UVC
  14. win10系统架设魔兽服务器,win10系统局域网魔兽争霸无法联机的步骤
  15. avformat_seek_file使用
  16. Tegra3 1080p高清播放时电源管理方式和功耗分析
  17. 【RNN】基于RNN的动态系统参数辨识matlab仿真
  18. 关联查询(多表查询)
  19. Java SE(排序)
  20. 计算机应用中兴5G通讯是什么,中兴通讯自曝5G成绩单:承建全国三成以上5G网络...

热门文章

  1. 深究AngularJS——ui-router详解
  2. 第八届蓝桥杯决赛 平方十位数(枚举)
  3. 数论基础之快速幂(详细教程)
  4. eclipse打包项目为aar_Eclipse中使用AAR
  5. python类方法是什么_python类方法和普通方法区别是什么
  6. 【实操】配置Telnet与SSH
  7. 收益 or 挑战?Serverless 究竟给前端带来了什么
  8. java 连接linux失败,Jenkins连接Linux失败
  9. 由于超出容量限制_限制特高压系统中的过电压措施
  10. linux u盘内容乱码,Linux挂载U盘,中文显示为乱码