很多时候我们需要检测被控对象的绝对压力,而且在我们的多款产品中也有这样的需求。当然检测绝对压力的传感器有很多,我们经常使用ms5803来实现压力检测。本篇中我们将设计并实现ms5803系列压力传感器的驱动。
1 、功能概述ms5803系列产品包含压阻传感器和传感器接口ic。ms5803系列压力传感器的主要功能是将未补偿的压阻压力传感器的模拟输出电压24位数字值,以及提供一个24位数字值的温度传感器。
1.1 、硬件描述ms5803系列压力传感器是新一代高分辨率高度计传感器,它是为高度计和高度分辨率为20厘米的变压计优化。能够同时获得压力值和温度值,其中压力测量范围为10-1100mbar,温度的测量范围是-40-85摄氏度。ms5803系列压力传感器各引脚功能如下:
ms5803系列压力传感器具有spi和i2c总线接口。ms5803系列压力传感器模块包括一个高线性压力传感器和一个超低功率24位δσadc与内部工厂校准系数。它提供一个精确的数字24位压力和温度值和不同的操作模式。传感器内部结构图如下:
我们使用ms5803系列压力传感器时,需要做的就是选择不同的通讯接口与其实现数字通讯的过程。
1.2 、通讯接口ms5803系列压力传感器支持spi和i2c总线通讯,通过协议选择引脚ps来决定采用什么接口。将协议选择引脚ps拉低,选择spi协议,将ps拉高,激活i2c总线协议。在不同协议下相关引脚的定义如下:
在不同协议下各引脚所支持的参数是有些许差异的。在spi接口模式下时钟引脚最大可达20mhz;在i2c接口模式下时钟引脚最大可达200khz。具体的参数如下图:
在spi模式下,sclk作为外部输入时钟,sdi作为串行数据输入,支持mode0和mode3的时钟极性和相位。传感器的响应数据输出为sdo引脚,片选信号为csb引脚。spi模式下接线示意图如下:
在i2c模式下,sclk为外部串行时钟输入,sda为串行数据通讯。csb引脚作为地址选择,可以链接到vdd或者gnd,这也意味着ms5803可以在一条i2c总线接两个设备。在csp接高电平时,地址为0x76(1110110 b),而csb接低电平时,地址为0x77 (1110111 b)这个地址是高七位,最后以为有读写命令来决定。实现写命令时,最后一位为0,实现读命令时,最后一位为1。i2c模式下接线图如下:
1.3 、数据访问无论是在spi模式还是在i2c模式,ms5803系列压力传感器都是通过5类命令实现的。这些命令包括:复位、读取出厂校准值、数据1转换(压力值数据)、数据2转换(温度值数据)和读取adc的转换结果。具体命令定义如下:
从上图,我们知道每个命令的大小为1字节(8位)。需要说明的是,adc读取指令后,设备将返回24位结果,prom读取则是16位结果。prom的地址使用ad2、ad1和ad0位嵌入到prom读命令中。关于这128bit prom的地址分配如下图所示:
ms5803系列压力传感器每个模块都是在两个温度和两个压力下单独校准的。这6个必要的系数来补偿工艺变化和温度变化,就存储在每个模块的128bit prom中。这些6个系数必须由软件读取,并在程序中使用,将d1和d2转换成补偿的压力和温度值。
2 、驱动设计与实现我们已经了解了ms5803压力传感器基本操作。在此基础上,我们将设计并实现ms5803压力传感器的驱动程序。
2.1 、对象定义在使用一个对象之前我们需要获得一个对象。同样的我们想要ms5803压力传感器就需要先定义ms5803压力传感器的对象。
2.1.1 、对象的抽象我们要得到ms5803压力传感器对象,需要先分析其基本特性。一般来说,一个对象至少包含两方面的特性:属性与操作。接下来我们就来从这两个方面思考一下ms5803压力传感器的对象。
先来考虑属性,作为属性肯定是用于标识或记录对象特征的东西。我们来考虑ms5803压力传感器对象属性。首先ms5803有一系列的产品,不同产品线的补偿计算方式有很大差异,所以我们将产品类型作为属性以区别不同的产品。ms5803拥有spi和i2c两种通讯方式可供选择,为了确定具体设备所采用的接口,我们将其作为对象的属性以记录其使用的接口方式。在采用i2c接口模式时,每台设备都有一个设备地址,这个地址用于区分同一总线上不同的设备,所以我们将地址作为对象的属性。而对于ms5803每台都有6个校准参数,这些参数在测量是需要用到,所以我们需要保存这些参数,所以我们将其作为属性。
接着我们还需要考虑ms5803压力传感器对象的操作问题。无论是使用spi接口还是使用i2c接口我们都需要向ms5803写命令和从ms5803读数据,而读写行为都与所处的硬件平台相关,所以我们将读和写数据作为对象的操作。为控制时序,我们需要延时操作,但延时操作也与具体的软硬件平台相关,所以我们将其作为对象的操作。在使用spi接口方式时,若使用软件控制片选信号,则会依赖于硬件,我们将针对片选信号的操作作为对象的操作。
根据上述我们对ms5803压力传感器的分析,我们可以定义ms5803压力传感器的对象类型如下:
1 typedef struct ms5803object { 2 uint8_t devaddress; //设备地址 3 ms5803porttype port; //通讯端口协议 4 ms5803modeltype model; //设备的类型 5 uint16_t calidata[6]; //校准数据 6 float temperature; 7 float pressure; 8 void (*write)(struct ms5803object *ms,uint8_t command);//向ms5803写信息 9 void (*read)(struct ms5803object *ms,uint8_t *rdata,uint16_t rsize);//从ms5803读数据10 void (*chipselcet)(ms5803cstype en); //片选信号,用于spi接口11 void (*delayms)(volatile uint32_t ntime); //毫秒秒延时函数12 }ms5803objecttype;2.1.2 、对象初始化我们知道,一个对象仅作声明是不能使用的,我们需要先对其进行初始化,所以这里我们来考虑ms5803压力传感器对象的初始化函数。一般来说,初始化函数需要处理几个方面的问题。一是检查输入参数是否合理;二是为对象的属性赋初值;三是对对象作必要的初始化配置。据此我们设计ms5803压力传感器对象的初始化函数如下:
1 /* ms5803对象初始化 */ 2 void ms5803initialization(ms5803objecttype *ms, //ms5803对象 3 ms5803modeltype model, //类型 4 ms5803porttype port, //通讯端口 5 uint8_t address, //i2c设备地址 6 ms5803write write, //写数据函数 7 ms5803read read, //读数据函数 8 ms5803chipselcet cs, //spi片选信号 9 ms5803delayms delayms //毫秒延时10 )11 {12 if((ms==null)||(write==null)||(read==null)||(delayms==null))13 {14 return;15 }16 ms->write=write;17 ms->read=read;18 ms->delayms=delayms;19 20 ms->model=model;21 ms->port=port;22 23 if(port==i2c)24 {25 if((address==0x76)||(address==0x77))26 {27 ms->devaddress=(address
devaddress=0x00;36 }37 38 ms->chipselcet=cs;39 }40 else41 {42 ms->devaddress=0xff;43 44 if(cs==null)45 {46 ms->chipselcet=ms5803chipselect;47 }48 else49 {50 ms->chipselcet=cs;51 }52 }53 54 ms->pressure=0.0;55 ms->temperature=0.0;56 57 resetforms5803(ms);58 59 getms5803calibrationdata(ms);60 }2.2 、对象操作我们已经完成了ms5803压力传感器对象类型的定义和对象初始化函数的设计。但我们的主要目标是获取对象的信息,接下来我们还要实现面向ms5803压力传感器的各类操作。
对ms5803压力传感器的其实就是基于前面我们所说的命令来实现的。根据这些命令的作用,我们可以大致分为三个方面:设备复位、adc转换配置及数据获取、校准系数的获取。下面我么五年就从这三个方面来看一看ms5803压力传感器的操作。
2.2.1 、复位操作复位操作可以在电源供电后的任意时刻发送,但一般要求在开机后首先发送复位程序。这样可以确保校准prom加载到内部寄存器。当然复位操作也可以用来重置设备rom以便从我们未知的情况中恢复。
在使用spi通讯接口时,无论是模式0还是模式3其操作是一样的,spi方式下的时序图如下:
在i2c通讯接口时,有时候通讯可能会出现sda被未定义的状态阻塞的时候,可以通过复位操作来恢复通讯。i2c方式下的时序图如下:
1 /*复位ms5803操作*/2 void resetforms5803(ms5803objecttype *ms)3 {4 uint8_t command=command_reset;5 /*下发复位命令*/6 ms->write(ms,command);7 8 ms->delayms(3);9 }2.2.2 、读取校准值校准值是出厂时厂家校准的各种系数,每台设备都有差异,但每台设备是固定不变的,只需要一次读取就可以了,共有6个系数,均为16为整数。
用户复位后,执行一次prom的read命令,读取校准prom的内容,计算校准系数。关于prom我们前面已经描述过了,总共有8个地址,地址0包含工厂数据和设置,地址1-6校准系数,地址7包含串行代码和crc。
在spi接口通讯模式下,我们发送都对应地址的命令,等待接收数据即可。命令为8位,返回数据为16位,时序图如下:
在i2c接口通讯模式下,prom读命令由两部分组成。第一个命令将系统设置为prom读模式。第二部分从系统中获取数据。首先发送读系数的命令,然后读取就可以了,每次读取1个,分6次读取。i2c模式下的时序图如下所示:
1 /*读取ms5803内存寄存器的数据*/ 2 static uint16_t readpromfromms5803(ms5803objecttype *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=(resultdelayms(10); 8 9 /*下发读取adc的命令*/10 ms->write(ms,command_adc_read);11 12 if(ms->port==i2c)13 { 14 ms->delayms(10);15 }16 17 /*接收读取的adc转换结果*/18 uint8_t adcvalue[3];19 ms->read(ms,adcvalue,3);20 21 uint32_t result=(uint32_t)adcvalue[0];22 result=(result<<8)+(uint32_t)adcvalue[1];23 result=(resultdevaddress,rdata,rsize,1000);11 }对于延时函数我们可以采用各种方法实现。我们采用的stm32平台和hal库则可以直接使用hal_delay()函数。于是我们可以调用初始化函数如下:
ms5803initialization(&ms5803,ms580302ba,i2c,0xec,sendcommandtoms5803,getdatasfromms5803,null,hal_delay);
这里我们使用的型号是ms580302ba,采用i2c接口,地址为0xec。因为使用的是i2c接口所以片选输入null。
3.2 、基于对象进行操作我们定义了对象变量并使用初始化函数给其作了初始化。接着我们就来考虑操作这一对象获取我们想要的数据。我们在驱动中已经将获取数据并转换为转换值的比例值,接下来我们使用这一驱动开发我们的应用实例。
1 /*获取压力变送器数据*/ 2 void getpressuresenserdata(void) 3 { 4 float pressure=0.0; 5 float temperature=0.0; 6 7 getms5803conversionvalue(&ms5803,ms5803_osr4096,ms5803_osr4096); 8 9 pressure=ms5803.pressure;10 temperature=ms5803.temperature;11 }4 、应用总结在本篇中,我们实现了ms5803压力传感器的驱动程序,并基于驱动程序开发了简单的验证应用。我们也多次在项目中使用ms5803压力传感器,使用的就是这一套驱动程序,应用的效果非常不错。
在使用i2c接口时,引脚csb应连接到vdd或gnd。因为ms5803的地址位仅有1位是可以通过csb设定的,所以一条i2c总线最多只能挂2个ms5803模块。当csb接vdd时地址最低位为1;当csb接gnd时地址最低位为0。
在使用驱动时需注意,采用spi接口的器件需要考虑片选操作的问题。如果片选信号是通过硬件电路来实现的,我们在初始化时给其传递null值。如果是软件操作片选则传递我们编写的片选操作函数。
源码下载:https://github.com/foxclever/experiphdriver
微软欲发可折叠机,Surface Phone能否挽回一局
英伟达发表AI新研究:人类只需演示一次,机器人即可完美复制
AI人形分析视频报警系统怎么样
鸿蒙系统将至?华为方舟编译器8月开源
坐标机器人码垛机袋装腻子粉包装码垛生产线
MS5803系列压力传感器的驱动设计与实现
us52调速器电路原理图
利用GPGPU的高性能嵌入式系统
物联网时代来临,要首先关注安全问题
人工智能正在深刻改变这个时代
cob显示屏的防护能力比SMD封装的led显示屏更加优秀
SWE.2软件架构设计
TD-SCDMA射频前置分频器的设计
新华三依托数字化解决方案助力海南数字经济发展
新思科技与GlobalFoundries加强合作,以光电统一芯片设计解决方案支持GF Fotonix™新平台
瞄准工业物联网 高通发布骁龙600E和410E处理器
嵌入式Web服务器可以解决物联网问题吗
Xilinx与生态伙伴启动All Programmable抽象化计划 助力更多设计人员并将生产力提升
基于一种典型的LED应用电路设计
锌-空气电池