单片机教程网

电脑版
提示:原网页已由神马搜索转码, 内容由www.51hei.com提供.
查看:2662|回复: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 单片机教程网