单片机教程网

电脑版
提示:原网页已由神马搜索转码, 内容由www.51hei.com提供.
查看:5857|回复:3
打印上一主题下一主题

用于arduino的MS5837-30BAR和02BAR的官方测试源程序与资料

[复制链接]
跳转到指定楼层
楼主
ID:413939发表于 2018-10-23 11:56|只看该作者|只看大图回帖奖励
用于arduino的MS5837-30BAR和02BAR的官方测试程序可以在代码里面自由对MS5837的种类进行切换,非常的方便
MS5837是高精度的压力传感器,形状微小
在很多地方都有应用,比如潜水仪器等等
另上传关于MS5837的芯片手册,供大家使用



BlueRobotics_MS5837_Library-master

源程序如下:

  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.                  Serial.println("here");
  110.                  Ti = (11*int64_t(dT)*int64_t(dT))/(34359738368LL);
  111.                  OFFi = (31*(TEMP-2000)*(TEMP-2000))/8;
  112.                  SENSi = (63*(TEMP-2000)*(TEMP-2000))/32;
  113.            }
  114.        } else {
  115.            if((TEMP/100)<20){       //Low temp
  116.                  Ti = (3*int64_t(dT)*int64_t(dT))/(8589934592LL);
  117.                  OFFi = (3*(TEMP-2000)*(TEMP-2000))/2;
  118.                  SENSi = (5*(TEMP-2000)*(TEMP-2000))/8;
  119.                  if((TEMP/100)<-15){   //Very low temp
  120.                        OFFi = OFFi+7*(TEMP+1500l)*(TEMP+1500l);
  121.                        SENSi = SENSi+4*(TEMP+1500l)*(TEMP+1500l);
  122.                  }
  123.            }
  124.            else if((TEMP/100)>=20){   //High temp
  125.                  Ti = 2*(dT*dT)/(137438953472LL);
  126.                  OFFi = (1*(TEMP-2000)*(TEMP-2000))/16;
  127.                  SENSi = 0;
  128.            }
  129.        }
  130.       
  131.        OFF2 = OFF-OFFi;         //Calculate pressure and temp second order
  132.        SENS2 = SENS-SENSi;
  133.       
  134.        if ( _model == MS5837_02BA ) {
  135.            TEMP = (TEMP-Ti);
  136.            P = (((D1*SENS2)/2097152l-OFF2)/32768l)/100;
  137.        } else {
  138.            TEMP = (TEMP-Ti);
  139.            P = (((D1*SENS2)/2097152l-OFF2)/8192l)/10;
  140.        }
  141. }

  142. float MS5837::pressure(float conversion) {
  143.        return P*conversion;
  144. }

  145. float MS5837::temperature() {
  146.        return TEMP/100.0f;
  147. }

  148. float MS5837::depth() {
  149.        return (pressure(MS5837::Pa)-101300)/(fluidDensity*9.80665);
  150. }

  151. float MS5837::altitude() {
  152.        return (1-pow((pressure()/1013.25),.190284))*145366.45*.3048;
  153. }


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

  156.        n_prom[0] = ((n_prom[0])& 0x0FFF);
  157.        n_prom[7] = 0;

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

  174.        return n_rem ^ 0x00;
  175. }

复制代码

所有资料51hei提供下载:
BlueRobotics_MS5837_Library-master.zip(8.31 KB, 下载次数: 51)
MS5837-30BA芯片手册.pdf(1.21 MB, 下载次数: 22)

评分

黑币 +50
收起理由
+ 50
共享资料的黑币奖励!

查看全部评分

沙发
ID:565602发表于 2019-10-25 19:20|只看该作者
有个客户在用,今天开始调试,先顶再读
板凳
ID:683452发表于 2020-1-8 11:30|只看该作者
蠻厲害的選擇
地板
ID:318415发表于 2020-4-4 10:57|只看该作者
感谢楼主 !

我自己写了个ms5837 一直没找到问题 对着例子 改了改可以用  

再次感谢!!

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

Powered by 单片机教程网