MS5803压力传感器支持SPI和I2C总线通讯,拥有24位AD转换。能够同时获得压力值和温度值,其中压力测量范围为10-1100mbar,温度的测量范围是-40-85摄氏度。各引脚功能及参数如下:

传感器内部结构图如下:

通讯协议的选择通过PS引脚来设置:

PS引脚电位

通讯模式

使用的引脚

高电平

I2C

SDA, SCL, CSB

低电平

SPI

SDI, SDO, SCLK, CSB

在SPI模式下,SCLK作为外部输入时钟,SDI作为串行数据输入,支持Mode0和Mode3的时钟极性和相位。传感器的响应数据输出为SDO引脚,片选信号为CSB引脚。界限示意图如下:

在I2C模式下,SCLK为外部串行时钟输入,SDA位串行数据通讯。CSB引脚作为地只选择,可以链接到VDD或者GND,这也意味着MS5803可以在一条I2C总线接两个设备。在CSP接高电平时,地址为0x76(1110110 b),而CSB接低电平时,地址为0x77 (1110111 b)这个地址是高七位,最后以为有读写命令来决定。实现写命令时,最后一位为0,实现读命令时,最后一位为1。

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

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

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

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

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

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

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

1)复位操作

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

  1. /*复位MS5803操作*/
  2.  
  3. void ResetForMS5803(uint8_t deviceAddress,WriteCommandToMS5803Type WriteCommandToMS5803)
  4.  
  5. {
  6.  
  7. uint8_t command=COMMAND_RESET;
  8.  
  9. /*下发复位命令*/
  10.  
  11. WriteCommandToMS5803(deviceAddress,command);
  12.  
  13. }

2)读取校准值

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

  1. /*从MS5803的PROM中读取校准数据*/
  2.  
  3. void GetCalibrationData(uint8_t deviceAddress,uint16_t *caliPara,WriteCommandToMS5803Type WriteCommandToMS5803,ReadBytesFromMS5803Type ReadBytesFromMS5803)
  4.  
  5. {
  6.  
  7. /*C1压力灵敏度*/
  8.  
  9. caliPara[]=ReadPromFromMS5803(deviceAddress,COMMAND_PROM_READ_C1,WriteCommandToMS5803,ReadBytesFromMS5803);
  10.  
  11. /*C2压力补偿值*/
  12.  
  13. caliPara[]=ReadPromFromMS5803(deviceAddress,COMMAND_PROM_READ_C2,WriteCommandToMS5803,ReadBytesFromMS5803);
  14.  
  15. /*C3压力灵敏度温度系数*/
  16.  
  17. caliPara[]=ReadPromFromMS5803(deviceAddress,COMMAND_PROM_READ_C3,WriteCommandToMS5803,ReadBytesFromMS5803);
  18.  
  19. /*C4压力补偿温度系数*/
  20.  
  21. caliPara[]=ReadPromFromMS5803(deviceAddress,COMMAND_PROM_READ_C4,WriteCommandToMS5803,ReadBytesFromMS5803);
  22.  
  23. /*C5参考温度*/
  24.  
  25. caliPara[]=ReadPromFromMS5803(deviceAddress,COMMAND_PROM_READ_C5,WriteCommandToMS5803,ReadBytesFromMS5803);
  26.  
  27. /*C6温度传感器温度系数*/
  28.  
  29. caliPara[]=ReadPromFromMS5803(deviceAddress,COMMAND_PROM_READ_C6,WriteCommandToMS5803,ReadBytesFromMS5803);
  30.  
  31. }

3)读取转换值

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

  1. /*获取转换值,包括温度和压力*/
  2.  
  3. void GetConversionValue(uint8_t deviceAddress,float *pPres,float *pTemp,uint16_t *caliPara,uint16_t *semaphore,WriteCommandToMS5803Type WriteCommandToMS5803,ReadBytesFromMS5803Type ReadBytesFromMS5803)
  4.  
  5. {
  6.  
  7. uint16_t senst1; //C1压力灵敏度
  8.  
  9. uint16_t offt1; //C2压力补偿值
  10.  
  11. uint16_t tcs; //C3压力灵敏度温度系数
  12.  
  13. uint16_t tco; //C4压力补偿温度系数
  14.  
  15. uint16_t tref; //C5参考温度
  16.  
  17. uint16_t tempsens; //C6温度传感器温度系数
  18.  
  19. /*从MS5803的PROM中读取校准数据*/
  20.  
  21. if(*semaphore>)
  22.  
  23. {
  24.  
  25. GetCalibrationData(deviceAddress,caliPara,WriteCommandToMS5803,ReadBytesFromMS5803);
  26.  
  27. *semaphore=*semaphore-;
  28.  
  29. }
  30.  
  31. senst1=caliPara[];
  32.  
  33. offt1=caliPara[];
  34.  
  35. tcs=caliPara[];
  36.  
  37. tco=caliPara[];
  38.  
  39. tref=caliPara[];
  40.  
  41. tempsens=caliPara[];
  42.  
  43. uint32_t digitalPressureValue;
  44.  
  45. uint32_t digitalTemperatureValue;
  46.  
  47. /*读取压力数据*/
  48.  
  49. digitalPressureValue=ReadConversionFromMS5803(deviceAddress,COMMAND_CONVERTD1OSR4096,WriteCommandToMS5803,ReadBytesFromMS5803);
  50.  
  51. Delayms();
  52.  
  53. /*读取温度数据*/
  54.  
  55. digitalTemperatureValue=ReadConversionFromMS5803(deviceAddress,COMMAND_CONVERTD2OSR4096,WriteCommandToMS5803,ReadBytesFromMS5803);
  56.  
  57. /*对温度进行一阶修正*/
  58.  
  59. int32_t dT;
  60.  
  61. int32_t temp;
  62.  
  63. dT=digitalTemperatureValue-tref*;
  64.  
  65. temp=(int32_t)(+dT*tempsens/pow(,));
  66.  
  67. /*对压力进行一阶修正*/
  68.  
  69. int64_t off;
  70.  
  71. int64_t sens;
  72.  
  73. int32_t pres;
  74.  
  75. off=(int64_t)(offt1*pow(,)+(tco*dT)/pow(,));
  76.  
  77. sens=(int64_t)(senst1*pow(,)+(tcs*dT)/pow(,));
  78.  
  79. pres=(int32_t)((digitalPressureValue*sens/pow(,)-off)/pow(,));
  80.  
  81. /*对温度和压力进行二阶修正*/
  82.  
  83. int64_t ti=;
  84.  
  85. int64_t offi=;
  86.  
  87. int64_t sensi=;
  88.  
  89. int64_t off2=;
  90.  
  91. int64_t sens2=;
  92.  
  93. if(temp<)
  94.  
  95. {
  96.  
  97. ti=(int64_t)(*dT*dT/pow(,));
  98.  
  99. offi=(int64_t)(*(temp-)*(temp-)/pow(,));
  100.  
  101. sensi=(int64_t)(*(temp-)*(temp-)/pow(,));
  102.  
  103. off2=off-offi;
  104.  
  105. sens2=sens-sensi;
  106.  
  107. temp=temp-(int32_t)ti;
  108.  
  109. pres=(int32_t)((digitalPressureValue*sens2/pow(,)-off2)/pow(,));
  110.  
  111. }
  112.  
  113. if((-<=temp)&&(temp<=))
  114.  
  115. {
  116.  
  117. *pTemp=(float)temp/100.0;
  118.  
  119. }
  120.  
  121. if((<=pres)&&(pres<=))
  122.  
  123. {
  124.  
  125. *pPres=(float)pres/100.0;
  126.  
  127. }
  128.  
  129. }

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

STM32应用实例八:与多台MS5803压力传感器I2C通讯的更多相关文章

  1. STM32应用实例七:与宇电设备实现AI-BUS通讯

    宇电的设备使用基于RS-485的自定义协议,协议本身比较简单,只有2条指令: 读:地址代号+52H(82) +要读的参数代号+0+0+校验码 写:地址代号+43H(67)+要写的参数代号+写入数低字节 ...

  2. 【转载】stm32的GPIO八种工作模式

    一.推挽输出:可以输出高.低电平,连接数字器件:推挽结构一般是指两个三极管分别受两个互补信号的控制,总是在一个三极管导通的时候另一个截止.高低电平由IC的电源决定.         推挽电路是两个参数 ...

  3. C语言库函数大全及应用实例八

    原文:C语言库函数大全及应用实例八                                            [编程资料]C语言库函数大全及应用实例八 函数名: kbhit 功 能: 检查 ...

  4. STM32应用实例十:简析STM32 I2C通讯死锁问题

    I2C接口是一种使用非常普遍的MCU与外部设备的接口方式,在STM32中也集成了I2C接口,我们也常常使用它来与外围的传感器等设备通讯. 最近在我们使用STM32F1VET6读取压力和温湿度传感器数据 ...

  5. STM32应用实例六:与MS5837压力传感器的I2C通讯

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

  6. 两台电脑使用ROS通讯

    一.ROS分布式多机通讯简介 ROS是一种分布式软件框架,节点之间通过松耦合的方式组合,在很多应用场景下,节点可以运行在不同的计算平台上,通过Topic,Service通信. 但是各个节点只能共同拥有 ...

  7. stm32 IO口八种模式区别

    初学STM32,遇到I/O口八种模式的介绍,网上查了一下资料,下面简明写出这几种模式的区别,有不对的地方请大家多多指正! 上拉输入模式:区别在于没有输入信号的时候默认输入高电平(因为有弱上拉).下拉输 ...

  8. XAML实例教程系列 - XAML传递参数到值转换类实例 八

    Kevin Fan分享开发经验,记录开发点滴 XAML实例教程系列 - XAML传递参数到值转换类实例 2012-06-28 05:25 by jv9, 508 阅读, 0 评论, 收藏, 编辑 继上 ...

  9. eureka多实例,模拟多台机器

    本文只有一个eureka server项目,运行在不同的端口,模拟两台eureka服务.开发使用eclipse 4.8 先说pom.xml文件,如果出现问题,首先考虑springboot和其他包版本冲 ...

随机推荐

  1. CentOS/Linux下设置IP地址

    CentOS/Linux下设置IP地址 1:临时修改:1.1:修改IP地址# ifconfig eth0 192.168.100.100 1.2:修改网关地址# route add default g ...

  2. (lower_bound)find the nth digit hdu1597

    find the nth digit Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Other ...

  3. java 中方法重载

    方法的重载 * 在同一个类中,方法名相同,参数列表不同.与返回值类型无关. * 参数列表不同: * A:参数个数不同 * B:参数类型不同 * C:参数的顺序不同(不算重载 报错) ex: publi ...

  4. SQL记录-rowid去重

    select * from a where rowid=(select max(rowid) from a)

  5. mips体系堆栈回溯分析与实现

    转载:http://www.sohu.com/a/118385096_468740 mips栈帧原理 Call stack 是指存放某个程序的正在运行的函数的信息的栈.Call stack 由 sta ...

  6. Linux - sort 排序

    -t # 指定排序时所用的栏位分隔字符 -n # 依照数值的大小排序 -r # 以相反的顺序来排序 -f # 排序时,将小写字母视为大写字母 -d # 排序时,处理英文字母.数字及空格字符外,忽略其他 ...

  7. tensorflow神经网络拟合非线性函数与操作指南

    本实验通过建立一个含有两个隐含层的BP神经网络,拟合具有二次函数非线性关系的方程,并通过可视化展现学习到的拟合曲线,同时随机给定输入值,输出预测值,最后给出一些关键的提示. 源代码如下: # -*- ...

  8. C#中富文本编辑器Simditor带图片上传的全部过程(MVC架构的项目)

    描述:最近c#项目中使用富文本编辑器Simditor,记录一下以便以后查看. 注:此项目是MVC架构的. 1.引用文件 项目中引用相应的css和js文件,注意顺序不能打乱,否则富文本编辑器不会正常显示 ...

  9. linux 命令格式

    1.命令  选项   参数 选项——短选项: - 多个选项可以合在一起书写 ——长选项:-- 选项是一个word 参数:命令的作用对象   ls -la  /etc   /opt 2.su  swit ...

  10. SpringBoot整合MyBatis(XML)

    (1).添加依赖 <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId> ...