git网站开发,网站建设 概念股,WordPress自定义登录页面,网站服务费怎么做分录压力检测也是经常会遇到的需求#xff0c;比如环境压力或者低压气体等都会用到压力检测。这类检测压力都比较低#xff0c;一般不会超过大气压#xff0c;有时甚至是负压。这一篇我们要讨论的MS5536C就属于这类器件。接下来我们将设计并实现MS5536C的驱动。
1、功能概述
M…压力检测也是经常会遇到的需求比如环境压力或者低压气体等都会用到压力检测。这类检测压力都比较低一般不会超过大气压有时甚至是负压。这一篇我们要讨论的MS5536C就属于这类器件。接下来我们将设计并实现MS5536C的驱动。
1、功能概述
MS5536C是一个系列的高分辨率工厂校准压力传感器。该设备包括一个压阻式压力传感器和一个ADC采用三线SPI接口。该设备以16位数据字的形式提供数字压力和温度信息。其结构图如下 MS5536C包含压阻传感器和传感器接口IC。MS5536C的主要功能是将压阻压力传感器的模拟输出电压为一个16位数字的值以及提供一个16位数字值的温度传感器。MS5536C通过SPI接口与外界进行数字通讯其引脚定义如下 由于压力传感器的输出电压很大程度上取决于温度和工艺公差因此有必要对这些影响进行补偿。每个模块都是在两个温度和两个压力下单独校准的。因此计算了6个必要的系数来补偿工艺变化和温度变化并存储在每个模块的64位PROM中。4个字的位排序组合为6个有效系数具体如下 对于MS5536C表压传感器在MCU发送信号时使用时钟上升沿在MCU接收数据时采用时钟下降沿。
2、驱动设计与实现
我们已经了解了MS5536C压力传感器的基本情况。接下来我们将在此基础上设计并实现MS5536C压力传感器的驱动程序。
2.1、对象定义
在使用一个对象之前我们需要获得一个对象。同样的我们想要MS5536C压力传感器就需要先定义MS5536C压力传感器的对象。
2.1.1、对象的抽象
我们要得到MS5536C压力传感器对象需要先分析其基本特性。一般来说一个对象至少包含两方面的特性属性与操作。接下来我们就来从这两个方面思考一下MS5536C压力传感器的对象。
先来考虑属性作为属性肯定是用于标识或记录对象特征的东西。我们来考虑MS5536C压力传感器对象属性。首先每一台MS5536C设备都有6个校准系数每次测量都需要使用所以我们将其作为属性保存下来。另一个测量的温度压力数据指示了MS5536C的工作状态所以我们也将其作为属性。
接着我们还需要考虑MS5536C压力传感器对象的操作问题。我们要获取数据就要访问MS5536C的寄存器就需要向其发送数据和从其接收数据但读写操作通常依赖于具体硬件平台所以我们将读写行为作为对象的操作。访问MS5536C时发送数据和接收数据分别采用时钟的上升沿和下降沿这样我们必须修改SPI端口的模式这同样与硬件平台相关所以我们将其定义为对象的操作。此外控制时序需要处理延时而实现延时同样依赖于具体的软硬件平台所以我们将延时也作为对象的操作。
根据上述我们对MS5536C压力传感器的分析我们可以定义MS5536C压力传感器的对象类型如下
//定义MS5536C对象类型
typedef struct MS5536cObject {uint16_t coef1; //校准系数C1uint16_t coef2; //校准系数C2uint16_t coef3; //校准系数C3uint16_t coef4; //校准系数C4uint16_t coef5; //校准系数C5uint16_t coef6; //校准系数C6int32_t pressure; //压力100倍整数值int32_t temperature; //温度100倍整数值float fPressure; //压力浮点数值float fTemperature; //温度浮点数值void (*ReadWriteMS)(uint8_t *txDatauint8_t *rxDatauint16_t number);void (*Delayms)(volatile uint32_t Delay);void (*SetPhase)(MS5536cPhaseType phase);
}MS5536cObjectType;
2.1.2、对象初始化
我们知道一个对象仅作声明是不能使用的我们需要先对其进行初始化所以这里我们来考虑MS5536C压力传感器对象的初始化函数。一般来说初始化函数需要处理几个方面的问题。一是检查输入参数是否合理二是为对象的属性赋初值三是对对象作必要的初始化配置。据此我们设计MS5536C压力传感器对象的初始化函数如下
/* 对MS5536C对象进行初始化 */
void Ms5536cInitialization(MS5536cObjectType *msMS5536cReadWriteMS readwriteMS5536cSetPhase setPhaseMS5536cDelayms delayms)
{if((msNULL)||(readwriteNULL)||(setPhaseNULL)||(delaymsNULL)){return;}ms-ReadWriteMSreadwrite;ms-SetPhasesetPhase;ms-Delaymsdelayms;ms-coef10;ms-coef20;ms-coef30;ms-coef40;ms-coef50;ms-coef60;ms-pressure0;ms-fPressure0.0;ms-temperature0;ms-fTemperature0.0;//复位Ms5336cSoftwareReset(ms);ms-Delayms(10);//获取修正系数GetCoefficientForMs5536c(ms);
}
2.2、对象操作
我们已经完成了MS5536C压力传感器对象类型的定义和对象初始化函数的设计。但我们的主要目标是获取对象的信息接下来我们还要实现面向MS5536C压力传感器的各类操作。
2.2.1、测量数据读取
在MS5536C中压力数据、温度数据以及校准系数的获取器操作是类似的我们只需要操作响应的寄存器就好了所以我们一并考虑它们。
MS5536C中压力数据是一个16位的数据读取的时序需要在发送命令和接受数据时采用不同的时钟沿。 MS5536C中温度数据是一个16位的数据读取温度数据的时序与压力数据一样也需要在发送命令和接收数据时采用不同的时钟沿。 数据转换需要时间所以在发送命令后要等待33毫秒根据上述时序图我们可以分析并设计读取转换数据的操作如下
/* 读取测量数据 */
static uint16_t ReadMeasureData(MS5536cObjectType *ms,uint16_t command)
{uint8_t txData[2];uint8_t rxData[2];uint16_t result0;txData[0](uint8_t)(command8);txData[1](uint8_t)command;ms-ReadWriteMS(txData,rxData,2);ms-Delayms(23);ms-SetPhase(MS5536_SCLK_FALL);ms-Delayms(10);txData[0]0x00;txData[1]0x00;ms-ReadWriteMS(txData,rxData,2);result(rxData[0]8)rxData[1];ms-SetPhase(MS5536_SCLK_RISE);ms-Delayms(10);return result;
}
2.2.2、寄存器读取
MS5536C中修正系数是有4个字组成其实是6个系数前面已经介绍了它的格式读取这几个数据的时序也需要在发送命令和接受数据时采用不同的时钟沿。字1和字3的时序图如下 读取字2和字4的时序图如下 根据上述时序图我们可以分析并设计读取寄存器的操作如下
/* 读取寄存器值 */
static uint16_t ReadRegister(MS5536cObjectType *msuint16_t command)
{uint8_t txData[2];uint8_t rxData[2];uint16_t result0;txData[0](uint8_t)(command8);txData[1](uint8_t)command;ms-ReadWriteMS(txDatarxData2);ms-SetPhase(MS5536_SCLK_FALL);txData[0]0x00;txData[1]0x00;ms-ReadWriteMS(txDatarxData2);result(rxData[0]8)rxData[1];ms-SetPhase(MS5536_SCLK_RISE);ms-Delayms(1);return result;
}
2.2.3、系统复位
复位信号的序列是特殊的因为它的独特模式是由模块在任何状态下识别的。因此如果微控制器和MS5536C之间的同步丢失它可以用来重新启动。这个序列是21位长。DOUT信号可能在这一序列中发生变化。建议在第一次转换序列之前发送复位序列以避免在电气干扰情况下永久挂起协议。其时序图如下 /*对MS5336C进行软件复位*/
void Ms5336cSoftwareReset(MS5536cObjectType *ms)
{//命令为21位10101010 10101010 00000uint8_t command[3]{1701700};uint8_t rxDate[3];ms-ReadWriteMS(commandrxDate3);
}
3、驱动的使用
我们设计并实现了MS5536C压力传感器的驱动程序我们还要设计一个简单的应用来验证这个驱动程序设计是否正确。所以接下来我们就基于驱动设计一个应用。
3.1、声明并初始化对象
使用基于对象的操作我们需要先得到这个对象所以我们先要使用前面定义的MS5536C压力传感器对象类型声明一个MS5536C压力传感器对象变量具体操作格式如下
MS5536cObjectType ms5536;
声明了这个对象变量并不能立即使用我们还需要使用驱动中定义的初始化函数对这个变量进行初始化。这个初始化函数所需要的输入参数如下
MS5536cObjectType *msMS5536对象
MS5536cReadWriteMS readwrite读写操作
MS5536cSetPhase setPhase相位设置操作
MS5536cDelayms delayms延时操作
对于这些参数对象变量我们已经定义了。所需要考虑的主要是我们需要定义几个函数并将函数指针作为参数。这几个函数的类型如下
typedef void (*MS5536cReadWriteMS)(uint8_t *txData,uint8_t *rxData,uint16_t number);typedef void (*MS5536cDelayms)(volatile uint32_t Delay);typedef void (*MS5536cSetPhase)(MS5536cPhaseType phase);
对于这几个函数我们根据样式定义就可以了具体的操作可能与使用的硬件平台有关系。具体函数定义如下
/* 通过SPI端口发送数据 */
static void ReadWriteBySPI(uint8_t *txData,uint8_t *rxData,uint16_t number)
{HAL_SPI_TransmitReceive(ms5536hspi,txData,rxData,number,1000);
}/* SPI1 初始化配置 */
static void MS5536_SPI_Configuration(MS5536cPhaseType phase)
{/* SPI1 端口参数配置*/ms5536hspi.Instance SPI1;ms5536hspi.Init.Mode SPI_MODE_MASTER;ms5536hspi.Init.Direction SPI_DIRECTION_2LINES;ms5536hspi.Init.DataSize SPI_DATASIZE_8BIT;ms5536hspi.Init.CLKPolarity SPI_POLARITY_LOW;if(phaseMS5536_SCLK_RISE){ms5536hspi.Init.CLKPhase SPI_PHASE_1EDGE;}else{ms5536hspi.Init.CLKPhase SPI_PHASE_2EDGE;}ms5536hspi.Init.NSS SPI_NSS_SOFT;ms5536hspi.Init.BaudRatePrescaler SPI_BAUDRATEPRESCALER_256;ms5536hspi.Init.FirstBit SPI_FIRSTBIT_MSB;ms5536hspi.Init.TIMode SPI_TIMODE_DISABLE;ms5536hspi.Init.CRCCalculation SPI_CRCCALCULATION_DISABLE;ms5536hspi.Init.CRCPolynomial 7;if (HAL_SPI_Init(ms5536hspi) ! HAL_OK){}
}
对于延时函数我们可以采用各种方法实现。我们采用的STM32平台和HAL库则可以直接使用HAL_Delay()函数。于是我们可以调用初始化函数如下
Ms5536cInitialization(ms5536,ReadWriteBySPI,MS5536_SPI_Configuration,HAL_Delay);
3.2、基于对象进行操作
我们定义了对象变量并使用初始化函数给其作了初始化。接着我们就来考虑操作这一对象获取我们想要的数据。我们在驱动中已经将获取数据并转换为转换值的比例值接下来我们使用这一驱动开发我们的应用实例。
/*压力数据处理*/
void PresDataProcess(void)
{float pressure0.0;float temperature0.0;GetMeasureForMs5536c(ms5536);pressurems5536.fPressure;temperaturems5536.fTemperature;
}
4、应用总结
我们设计了MS5536C压力传感器的驱动程序并且设计了一个简单的应用来验证它。事实上在此之前我们已经在项目中使用过MS5536C压力传感器并且正确的得到了我们想要的数据。
使用时需要注意MS5536C压力传感器采用的是SPI接口但没有片选信号。在发送信号时以3为高电平起始。在MCU发送信号时使用时钟上升沿在MCU接收数据时采用时钟下降沿。关于上升沿和下降沿转换这一点需特别注意否则读取的数据不正确。
源码已发布https://github.com/foxclever/ExPeriphDriver
欢迎关注