標籤:包括 orm etc 操作 led pre 感應器 ipa stm32
採集大氣壓力和溫度也是核算大氣標準狀況下的各種資料的必須參數,為此我們必須知道壓力和溫度才能計算標準狀況下的各種參數,於此我們需要一個既能檢測壓力也能檢測溫度的元件。
1、硬體概述
MS5837壓力感應器是一種可用於電路板上,適用於檢測10-1200mbar壓力範圍的感應器,靈敏度非常高,理論上能夠檢測到0.01mbar的壓力變化,實際使用過程中測試並無明顯的變化。
(1)硬體串連
MS5837採用I2C匯流排通訊,與STM32的MCU可以實現I2C通訊。硬體串連方式如下:
我們發現OneNET麒麟座的I2C引到了J3的第4和5引腳,但是我們發現在OLED的介面也是這個,所以我們直接用這個,因為電源也正好合適,具體位置如紅框處:
(3)寄存器分配
MS5837隻有5個基本命令:複位、讀取出廠校準值、資料1轉換(壓力值資料)、資料2轉換(溫度值資料)和讀取ADC的轉換結果。具體分配如下:
2、軟體設計
因為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);函數並調用就可以了,更換平台也只需要重寫這兩個函數就能實現移植。
3、結果展示
完成上述開發後,編譯下載。我們也將資料結果上傳到OneNET,具體顯示結果如下:
分別顯示了,大氣壓力,溫度以及濕度等參數。
OneNET麒麟座應用開發之八:採集大氣壓力等環境參數