標題: STM32與多臺MS5803壓力傳感器I2C通訊 [打印本頁]
作者: nm752 時間: 2018-1-6 22:38
標題: 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)復位操作
復位操作的數據流如下圖所示,只需要發送一條命令就可完成:
[url=]
[/url] /*復位MS5803操作*/
void ResetForMS5803(uint8_t deviceAddress,WriteCommandToMS5803Type WriteCommandToMS5803)
{
uint8_t command=COMMAND_RESET;
/*下發復位命令*/
WriteCommandToMS5803(deviceAddress,command);
}
[url=]
[/url] (2)讀取校準值
校準值是出廠時廠家校準的各種系數,每臺設備都有差異,是固定不變的,只需要一次讀取就可以了,共有6個系數,均為16為整數。首先發送讀系數的命令,然后讀取就可以了,每次讀取1個,分6次讀取。過程數據流如下圖所示:
[url=]
[/url] /*從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);
}
[url=]
[/url] (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應用實例八.docx
2018-1-6 22:35 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
489.69 KB, 下載次數: 16, 下載積分: 黑幣 -5
STM32
歡迎光臨 (http://m.zg4o1577.cn/bbs/) |
Powered by Discuz! X3.1 |
主站蜘蛛池模板:
黄色1级片
|
欧美精品在线观看
|
国产精品一区二
|
欧美1级片
|
精品国产精品
|
欧美精品一级片
|
成人免费看片98欧美
|
欧美一级片在线
|
黄色高清网站
|
国产一级一片免费播放放a
免费国产视频
|
在线观看黄色片
|
成年在线观看
|
午夜视频网站
|
午夜精品久久久久久
|
超碰97在线免费观看
|
污视频网站在线观看
|
欧美在线免费观看
|
美日韩一区
|
曰本毛茸茸性生活
|
午夜精品久久久久久久99黑人
|
成人av一区二区三区在线观看
|
国产天堂在线
|
久久精品视频网
|
在线播放av网站
|
欧美色综合天天久久综合精品
|
久久精品国产成人av
|
成人蜜桃视频
|
国产做受视频
|
精品国产乱码久久久久久蜜柚
|
亚洲精品视频免费在线观看
|
国产精品久久视频
|
久久综合在线
|
一级黄色性生活片
|
亚洲国产第一页
|
国产精品99精品久久免费
|
中文字幕永久免费
|
99久久婷婷国产综合精品草原
|
亚洲一区在线播放
|
日韩成人精品一区二区
|
国产伦精品一区二区三区免.费
|
永久免费看片在线播放
|