日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

外设驱动库开发笔记18:MS5837压力变送器驱动

發布時間:2024/7/23 编程问答 70 豆豆
生活随笔 收集整理的這篇文章主要介紹了 外设驱动库开发笔记18:MS5837压力变送器驱动 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

絕對壓力的檢測是常見的需求。在我們的系統中也常常會遇到。而MS5837壓力傳感器也是我們進場會采用的方案。在這篇里我們將討論并實現MS5837壓力傳感器的驅動。

1、功能概述

MS5837壓力傳感器是一種可用于電路板上,適用于檢測10-1200mbar壓力范圍的傳感器,靈敏度非常高,理論上能夠檢測到0.01mbar的壓力變化,實際使用過程中測試并無明顯的變化。

MS5837壓力傳感器采用I2C總線通訊,與MCU可以實現I2C通訊。硬件連接方式如下:

MS5837壓力傳感器擁有5類基本命令:復位、讀取出廠校準值、數據1轉換(壓力值數據)、數據2轉換(溫度值數據)和讀取ADC的轉換結果。具體分配如下:

因為MS5837的地址是固定的,所以一個I2C總線只能掛1MS5837模塊。其設備地址固定為:0xEC

2、驅動設計與實現

我們已經了解了MS5837的基本功能和操作方式。接下來我們就根據前面的分析實現MS5837的驅動。

2.1、對象定義

在使用該對象之前,我們需要定義對象,我們根據MS5837的屬性和操作來定義對象。

2.1.1、對象類型抽象

為了方便操作與復用,我們使用基于對象的操作。這里我們先來抽象MS5837壓力傳感器對象的類型,該類型包含了MS5837的必要屬性和對MS5837基本操作。

我們先來分析MS5837壓力傳感器對象的屬性。MS5837壓力傳感器使用的是I2C通訊接口,需要一個地址分辨總線上的不同設備,所以我們將I2C設備地址作為MS5837壓力傳感器對象的一個屬性。此外,在計算MS5837壓力傳感器測量的壓力、溫度值時需要使用6個校準參數,而且這些參數每臺設備都是不一樣的,所以我們將這些參數作為屬性來保存其值。

接下來我們再來分析MS5837壓力傳感器對象的操作。我們使用MS5837壓力傳感器時,需要向其寫命令和從其讀數據,而讀寫操作都依賴于具體的硬件平臺,所以我們將寫數據和讀數據作為對象的操作。此外,為控制時序,我們需要延時操作,而延時行為的實現亦依賴于具體的軟硬件平臺,所以我們將延時也作為對象的操作。

根據上述我們對MS5837壓力傳感器對象的分析,我們可以抽象MS5837壓力傳感器的對象類型為:

/* 定義MS5837對象類型 */ typedef struct MS5837Object {uint8_t devAddress;???????????????? //設備地址uint16_t caliData[6];??????? //校準數據float temperature;float pressure;void (*Write)(struct MS5837Object *ms,uint8_t command);/*向MS5837下發指令,指令格式均為1個字節*/void (*Read)(struct MS5837Object *ms,uint8_t *rData,uint16_t rSize);/*從MS5837讀取多個字節數據的值*/void (*Delayms)(volatile uint32_t nTime);???? //毫秒秒延時函數 }MS5837ObjectType;

2.1.2、對象初始化

在使用之前,我們先要使用對象類型聲明對象,但聲明的對象只是一個變量,該對象變量在使用前必須初始化,所以我們定義了對象初始化函數。

/* 初始化MS5837對象 */ void MS5837Initialization(MS5837ObjectType *ms,MS5837Write write,MS5837Read read,MS5837Delayms delay) {if((ms==NULL)||(write==NULL)||(read==NULL)||(delay==NULL)){return;??}ms->Write=write;ms->Read=read;ms->Delayms=delay;ms->devAddress=0b11101100;ms->pressure=0.0;ms->temperature=0.0;ResetForMs5837(ms);GetCalibrationData(ms); }

2.2、對象操作

完成了對象的聲明與初始化之后,我們就可以使用對象變量來操作對象了。關于MS5837的操作主要有:設備復位、校準值獲取、轉換值的讀取。下面將一一實現。

2.2.1、復位操作

復位操作在MS5837壓力傳感器有電時就可執行,但一般會在上電之后需要復位一下,以保持內存中的校準參數值是正確的。此外,當I2CSDA引腳因未知原因出現阻塞時,復位能消除這種不確定性。復位操作只需要發送一條命令,其時序圖如下:

/*復位MS5837操作*/ void ResetForMs5837(MS5837ObjectType *ms) {uint8_t command=COMMAND_RESET;/*下發復位命令*/ms->SendCommand(ms,command); }

2.2.2、讀取校準值

校準值是出廠時廠家校準的各種系數,每臺設備都有差異,是固定不變的,只需要一次讀取就可以了,共有6個系數,均為16為整數。首先發送讀系數的命令,然后讀取就可以了,每次讀取1個,分6次讀取。過程數據流如下圖所示:

/*讀取MS5837內存寄存器的數據*/ static uint16_t ReadPromFromMs5837(MS5837ObjectType *ms,uint8_t command) {/*下發讀取指定內存單元的命令*/ms->Write(ms,command);/*接收讀取的指定內存單元的值*/uint8_t promValue[2];ms->Read(ms,promValue,2);uint16_t result=(uint16_t)promValue[0];result=(result<<8)+(uint16_t)promValue[1];return result; }

2.2.3、讀取轉換值

讀取轉換結果值是我們的目的,可以讀取溫度和壓力兩個量,不過一次只能讀一個。首先發送命令設定采集壓力還是溫度,并設定精度。然后發送讀取的命令,最后讀取對應的值。再使用校準系數計算出最終的物理值。

/*讀取MS5837ADC的轉換值*/ static uint32_t ReadConversionFromMs5837(MS5837ObjectType *ms,uint8_t command) {/*下發轉化對象及精度配置命令*/ms->Write(ms,command);ms->Delayms(10);/*下發讀取ADC的命令*/ms->Write(ms,COMMAND_ADC_READ);ms->Delayms(10);/*接收讀取的ADC轉換結果*/uint8_t adcValue[3];ms->Read(ms,adcValue,3);uint32_t result=(uint32_t)adcValue[0];result=(result<<8)+(uint32_t)adcValue[1];result=(result<<8)+(uint32_t)adcValue[2];return result; }

這里獲取的只是ADC的數字碼值。我們想要得到溫度和壓力的物理量值還需要使用校準值,通過廠家提供的公式計算得到。

3、驅動的使用

在前面我們描述了MS5837壓力傳感器的基本情況,在此基礎上設計并實現了MS5837壓力傳感器對象的驅動程序。這一節我們將設計一個簡單的應用來驗證驅動設計是否符合要求。

3.1、聲明并初始化對象

使用基于對象的操作我們需要先得到這個對象,所以我們先要使用前面定義的MS5837壓力傳感器對象類型聲明一個MS5837壓力傳感器對象變量,具體操作格式如下:

MS5837ObjectType ms5837;

聲明了這個對象變量并不能立即使用,我們還需要使用驅動中定義的初始化函數對這個變量進行初始化。這個初始化函數所需要的輸入參數如下:

MS5837ObjectType *msMS5837對象

MS5837Write write,向MS5837寫數據函數指針

MS5837Read read,從MS5837讀數據函數指針

MS5837Delayms delayms,毫秒延時函數指針

對于這些參數,對象變量我們已經定義了。我們需要重點關注幾個函數指針,首先要定義這幾個函數,并將函數指針作為參數。這幾個函數的類型如下:

/*向MS5837下發指令,指令格式均為1個字節*/ typedef void (*MS5837Write)(struct MS5837Object *ms,uint8_t command);/*從MS5837讀取多個字節數據的值*/ typedef void (*MS5837Read)(struct MS5837Object *ms,uint8_t *rData,uint16_t rSize);/*毫秒秒延時函數*/ typedef void (*MS5837Delayms)(volatile uint32_t nTime);

對于這幾個函數我們根據樣式定義就可以了,具體的操作可能與使用的硬件平臺有關系。片選操作函數用于多設備需要軟件操作時,如采用硬件片選可以傳入NULL即可。具體函數定義如下:

/*通過I2C1接口下發命令*/ static void SendCommandToMS5837(MS5837ObjectType *ms,uint8_t command) {HAL_I2C_Master_Transmit(&ms5837hi2c,ms->devAddress,&command,1,1000); }/*通過I2C1接口讀取數據*/ static void GetDatasFromMS5837(MS5837ObjectType *ms,uint8_t *rData,uint16_t rSize) {HAL_I2C_Master_Receive(&ms5837hi2c,ms->devAddress,rData,rSize,1000); }

對于延時函數我們可以采用各種方法實現。我們采用的STM32平臺和HAL庫則可以直接使用HAL_Delay()函數。于是我們可以調用初始化函數如下:

MS5837Initialization(&ms5837,SendCommandToMS5837,GetDatasFromMS5837,HAL_Delay);

3.2、基于對象進行操作

我們定義了對象變量并使用初始化函數給其作了初始化。接著我們就來考慮操作這一對象獲取我們想要的數據。我們在驅動中已經將獲取數據并轉換為轉換值的比例值,接下來我們使用這一驅動開發我們的應用實例。

/*獲取壓力變送器數據*/ void MS5837GetMeasureData(void) {float pressure=0.0;float temperature=0.0;GetMS5837ConversionValue(&ms5837,MS5837_OSR8192,MS5837_OSR8192);pressure=ms5837.pressure;temperature=ms5837.temperature;}

4、應用總結

我們已經實現了MS5837壓力傳感器的驅動程序,也設計了一個簡單的應用來驗證這一驅動程序。驗證的結果與我們預期一樣,得到了我們需要的數據。我們也曾將這一驅動應用于實際項目,效果也是令人滿意的。

使用驅動是需要注意,MS5837壓力傳感器雖然采用了I2C接口,但它的地址是固定的,所以一條總線上只能有一臺MS5837壓力傳感器。所以在驅動中地址是固化在驅動程序中不可修改的。

源碼下載:https://github.com/foxclever/ExPeriphDriver

歡迎關注:

?

總結

以上是生活随笔為你收集整理的外设驱动库开发笔记18:MS5837压力变送器驱动的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。