找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2713|回复: 0
收起左侧

ms5837+arduino源程序

[复制链接]
ID:369562 发表于 2020-4-10 20:55 | 显示全部楼层 |阅读模式
  1. #include "MS5837.h"
  2. #include <Wire.h>

  3. #define MS5837_ADDR               0x76  
  4. #define MS5837_RESET              0x1E
  5. #define MS5837_ADC_READ           0x00
  6. #define MS5837_PROM_READ          0xA0
  7. #define MS5837_CONVERT_D1_8192    0x4A
  8. #define MS5837_CONVERT_D2_8192    0x5A

  9. const float MS5837::Pa = 100.0f;
  10. const float MS5837::bar = 0.001f;
  11. const float MS5837::mbar = 1.0f;

  12. const uint8_t MS5837::MS5837_30BA = 0;
  13. const uint8_t MS5837::MS5837_02BA = 1;

  14. MS5837::MS5837() {
  15.         fluidDensity = 1029;
  16. }

  17. bool MS5837::init() {
  18.         // Reset the MS5837, per datasheet
  19.         Wire.beginTransmission(MS5837_ADDR);
  20.         Wire.write(MS5837_RESET);
  21.         Wire.endTransmission();

  22.         // Wait for reset to complete
  23.         delay(10);

  24.         // Read calibration values and CRC
  25.         for ( uint8_t i = 0 ; i < 7 ; i++ ) {
  26.                 Wire.beginTransmission(MS5837_ADDR);
  27.                 Wire.write(MS5837_PROM_READ+i*2);
  28.                 Wire.endTransmission();

  29.                 Wire.requestFrom(MS5837_ADDR,2);
  30.                 C[i] = (Wire.read() << 8) | Wire.read();
  31.         }

  32.         // Verify that data is correct with CRC
  33.         uint8_t crcRead = C[0] >> 12;
  34.         uint8_t crcCalculated = crc4(C);

  35.         if ( crcCalculated == crcRead ) {
  36.                 return true; // Initialization success
  37.         }

  38.         return false; // CRC fail
  39. }

  40. void MS5837::setModel(uint8_t model) {
  41.         _model = model;
  42. }

  43. void MS5837::setFluidDensity(float density) {
  44.         fluidDensity = density;
  45. }

  46. void MS5837::read() {
  47.         // Request D1 conversion
  48.         Wire.beginTransmission(MS5837_ADDR);
  49.         Wire.write(MS5837_CONVERT_D1_8192);
  50.         Wire.endTransmission();

  51.         delay(20); // Max conversion time per datasheet
  52.        
  53.         Wire.beginTransmission(MS5837_ADDR);
  54.         Wire.write(MS5837_ADC_READ);
  55.         Wire.endTransmission();

  56.         Wire.requestFrom(MS5837_ADDR,3);
  57.         D1 = 0;
  58.         D1 = Wire.read();
  59.         D1 = (D1 << 8) | Wire.read();
  60.         D1 = (D1 << 8) | Wire.read();
  61.        
  62.         // Request D2 conversion
  63.         Wire.beginTransmission(MS5837_ADDR);
  64.         Wire.write(MS5837_CONVERT_D2_8192);
  65.         Wire.endTransmission();

  66.         delay(20); // Max conversion time per datasheet
  67.        
  68.         Wire.beginTransmission(MS5837_ADDR);
  69.         Wire.write(MS5837_ADC_READ);
  70.         Wire.endTransmission();

  71.         Wire.requestFrom(MS5837_ADDR,3);
  72.         D2 = 0;
  73.         D2 = Wire.read();
  74.         D2 = (D2 << 8) | Wire.read();
  75.         D2 = (D2 << 8) | Wire.read();

  76.         calculate();
  77. }

  78. void MS5837::calculate() {
  79.         // Given C1-C6 and D1, D2, calculated TEMP and P
  80.         // Do conversion first and then second order temp compensation
  81.        
  82.         int32_t dT = 0;
  83.         int64_t SENS = 0;
  84.         int64_t OFF = 0;
  85.         int32_t SENSi = 0;
  86.         int32_t OFFi = 0;  
  87.         int32_t Ti = 0;   
  88.         int64_t OFF2 = 0;
  89.         int64_t SENS2 = 0;
  90.        
  91.         // Terms called
  92.         dT = D2-uint32_t(C[5])*256l;
  93.         if ( _model == MS5837_02BA ) {
  94.                 SENS = int64_t(C[1])*65536l+(int64_t(C[3])*dT)/128l;
  95.                 OFF = int64_t(C[2])*131072l+(int64_t(C[4])*dT)/64l;
  96.                 P = (D1*SENS/(2097152l)-OFF)/(32768l);
  97.         } else {
  98.                 SENS = int64_t(C[1])*32768l+(int64_t(C[3])*dT)/256l;
  99.                 OFF = int64_t(C[2])*65536l+(int64_t(C[4])*dT)/128l;
  100.                 P = (D1*SENS/(2097152l)-OFF)/(8192l);
  101.         }
  102.        
  103.         // Temp conversion
  104.         TEMP = 2000l+int64_t(dT)*C[6]/8388608LL;
  105.        
  106.         //Second order compensation
  107.         if ( _model == MS5837_02BA ) {
  108.                 if((TEMP/100)<20){         //Low temp
  109.                         Ti = (11*int64_t(dT)*int64_t(dT))/(34359738368LL);
  110.                         OFFi = (31*(TEMP-2000)*(TEMP-2000))/8;
  111.                         SENSi = (63*(TEMP-2000)*(TEMP-2000))/32;
  112.                 }
  113.         } else {
  114.                 if((TEMP/100)<20){         //Low temp
  115.                         Ti = (3*int64_t(dT)*int64_t(dT))/(8589934592LL);
  116.                         OFFi = (3*(TEMP-2000)*(TEMP-2000))/2;
  117.                         SENSi = (5*(TEMP-2000)*(TEMP-2000))/8;
  118.                         if((TEMP/100)<-15){    //Very low temp
  119.                                 OFFi = OFFi+7*(TEMP+1500l)*(TEMP+1500l);
  120.                                 SENSi = SENSi+4*(TEMP+1500l)*(TEMP+1500l);
  121.                         }
  122.                 }
  123.                 else if((TEMP/100)>=20){    //High temp
  124.                         Ti = 2*(dT*dT)/(137438953472LL);
  125.                         OFFi = (1*(TEMP-2000)*(TEMP-2000))/16;
  126.                         SENSi = 0;
  127.                 }
  128.         }
  129.        
  130.         OFF2 = OFF-OFFi;           //Calculate pressure and temp second order
  131.         SENS2 = SENS-SENSi;
  132.        
  133.         TEMP = (TEMP-Ti);
  134.        
  135.         if ( _model == MS5837_02BA ) {
  136.                 P = (((D1*SENS2)/2097152l-OFF2)/32768l);
  137.         } else {
  138.                 P = (((D1*SENS2)/2097152l-OFF2)/8192l);
  139.         }
  140. }

  141. float MS5837::pressure(float conversion) {
  142.     if ( _model == MS5837_02BA ) {
  143.         return P*conversion/100.0f;
  144.     }
  145.     else {
  146.         return P*conversion/10.0f;
  147.     }
  148. }

  149. float MS5837::temperature() {
  150.         return TEMP/100.0f;
  151. }

  152. float MS5837::depth() {
  153.         return (pressure(MS5837::Pa)-101300)/(fluidDensity*9.80665);
  154. }

  155. float MS5837::altitude() {
  156.         return (1-pow((pressure()/1013.25),.190284))*145366.45*.3048;
  157. }


  158. uint8_t MS5837::crc4(uint16_t n_prom[]) {
  159.         uint16_t n_rem = 0;

  160.         n_prom[0] = ((n_prom[0]) & 0x0FFF);
  161.         n_prom[7] = 0;

  162.         for ( uint8_t i = 0 ; i < 16; i++ ) {
  163.                 if ( i%2 == 1 ) {
  164.                         n_rem ^= (uint16_t)((n_prom[i>>1]) & 0x00FF);
  165.                 } else {
  166.                         n_rem ^= (uint16_t)(n_prom[i>>1] >> 8);
  167.                 }
  168.                 for ( uint8_t n_bit = 8 ; n_bit > 0 ; n_bit-- ) {
  169.                         if ( n_rem & 0x8000 ) {
  170.                                 n_rem = (n_rem << 1) ^ 0x3000;
  171.                         } else {
  172.                                 n_rem = (n_rem << 1);
  173.                         }
  174.                 }
  175.         }
  176.        
  177.         n_rem = ((n_rem >> 12) & 0x000F);

  178.         return n_rem ^ 0x00;
  179. }
复制代码

全部资料51hei下载地址:
MS5837资料.rar (1.63 MB, 下载次数: 20)
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表