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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

STM32与多台MS5803压力传感器I2C通讯

發布時間:2024/7/23 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 STM32与多台MS5803压力传感器I2C通讯 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

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)復位操作

復位操作的數據流如下圖所示,只需要發送一條命令就可完成:

/*復位MS5803操作*/

void ResetForMS5803(uint8_t deviceAddress,WriteCommandToMS5803Type WriteCommandToMS5803)

{

??uint8_t command=COMMAND_RESET;

??/*下發復位命令*/

??WriteCommandToMS5803(deviceAddress,command);

}

(2)讀取校準值

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

/*從MS5803的PROM中讀取校準數據*/

void GetCalibrationData(uint8_t deviceAddress,uint16_t *caliPara,WriteCommandToMS5803Type WriteCommandToMS5803,ReadBytesFromMS5803Type ReadBytesFromMS5803)

{

??/*C1壓力靈敏度*/

??caliPara[0]=ReadPromFromMS5803(deviceAddress,COMMAND_PROM_READ_C1,WriteCommandToMS5803,ReadBytesFromMS5803);

??/*C2壓力補償值*/

??caliPara[1]=ReadPromFromMS5803(deviceAddress,COMMAND_PROM_READ_C2,WriteCommandToMS5803,ReadBytesFromMS5803);

??/*C3壓力靈敏度溫度系數*/

??caliPara[2]=ReadPromFromMS5803(deviceAddress,COMMAND_PROM_READ_C3,WriteCommandToMS5803,ReadBytesFromMS5803);

??/*C4壓力補償溫度系數*/

??caliPara[3]=ReadPromFromMS5803(deviceAddress,COMMAND_PROM_READ_C4,WriteCommandToMS5803,ReadBytesFromMS5803);

??/*C5參考溫度*/

??caliPara[4]=ReadPromFromMS5803(deviceAddress,COMMAND_PROM_READ_C5,WriteCommandToMS5803,ReadBytesFromMS5803);

??/*C6溫度傳感器溫度系數*/

??caliPara[5]=ReadPromFromMS5803(deviceAddress,COMMAND_PROM_READ_C6,WriteCommandToMS5803,ReadBytesFromMS5803);

}

(3)讀取轉換值

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

/*獲取轉換值,包括溫度和壓力*/

void GetConversionValue(uint8_t deviceAddress,float *pPres,float *pTemp,uint16_t *caliPara,uint16_t *semaphore,WriteCommandToMS5803Type WriteCommandToMS5803,ReadBytesFromMS5803Type ReadBytesFromMS5803)

{

??uint16_t senst1; ???????//C1壓力靈敏度

??uint16_t offt1; ????????//C2壓力補償值

??uint16_t tcs; ??????????//C3壓力靈敏度溫度系數

??uint16_t tco; ??????????//C4壓力補償溫度系數

??uint16_t tref; ?????????//C5參考溫度

??uint16_t tempsens; ?????//C6溫度傳感器溫度系數

??

??/*從MS5803的PROM中讀取校準數據*/

??if(*semaphore>0)

??{

????GetCalibrationData(deviceAddress,caliPara,WriteCommandToMS5803,ReadBytesFromMS5803);

????*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=ReadConversionFromMS5803(deviceAddress,COMMAND_CONVERTD1OSR4096,WriteCommandToMS5803,ReadBytesFromMS5803);

??

??Delayms(20);

??

??/*讀取溫度數據*/

??digitalTemperatureValue=ReadConversionFromMS5803(deviceAddress,COMMAND_CONVERTD2OSR4096,WriteCommandToMS5803,ReadBytesFromMS5803);

??

??/*對溫度進行一階修正*/

??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<=190000))

??{

????*pPres=(float)pres/100.0;

??}

}

最終在STM32的I2C接口實現通訊時,實現2個WriteCommandToMS5803Type(uint8_t deviceAddress,uint8_t command);和ReadBytesFromMS5803Type(uint8_t deviceAddress,uint8_t *pData,uint16_t bytesNum);函數并調用就可以了,換做其他的平臺也只需要重寫這兩個函數就能實現通訊了。

歡迎關注:

總結

以上是生活随笔為你收集整理的STM32与多台MS5803压力传感器I2C通讯的全部內容,希望文章能夠幫你解決所遇到的問題。

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