传感器定制
投稿量: 粉丝量: 关注量:

BMP388源代码

#include "iic_bmp388.h"

#include "iic.h"

#include "delay.h"

#include "app.h"

#include <math.h>



/* Private define ------------------------------------------------------------*/

//IIC地址,SDO接地为0x76,接VCC地址为0x77

#define BMP388_Addr 0x76


#define Concat_Bytes(msb, lsb) (((uint16_t)msb << 8) | (uint16_t)lsb)


/* Public variables ----------------------------------------------------------*/

struct bmp3_calib_data  calib_data;

struct bmp3_uncomp_data uncomp_data;

struct bmp3_data        comp_data;


/* Public function -----------------------------------------------------------*/

//读取未修正的气压和温度信息

uint8_t get_PandT()

{

  uint8_t reg_data[6]={0};

  uint8_t time = 0 ,status = 0;

  

  while(!((status&0x40)&&(status&0x20)))  //查询数据是否准备完毕  0 1 1 0 0000

  {

    DS.sensor_iic[DS.iic.read_index].failed_code = IIC_WriteRead(BMP388_Addr << 1, 0x03, 0, 0, 1, &status, 0);

    delay_ms(1);

    time++;

    if(time >= 5)

    {

      if(DS.sensor_iic[DS.iic.read_index].continue_failed_cnt < 0xFF)

        DS.sensor_iic[DS.iic.read_index].continue_failed_cnt++;

      if(DS.sensor_iic[DS.iic.read_index].total_failed_cnt < 0xFFFF)

        DS.sensor_iic[DS.iic.read_index].total_failed_cnt++;

      DS.sensor_iic[DS.iic.read_index].failed_code = 1;

      

      if(DS.sensor_iic[DS.iic.read_index].continue_failed_cnt >= 5)

      {

        DS.sensor_iic[DS.iic.read_index].value.flts[0] = Var.iic_sensor[DS.iic.read_index].invalid_value;

        DS.sensor_iic[DS.iic.read_index].value.flts[1] = Var.iic_sensor[DS.iic.read_index].invalid_value;

      }

      return 1;

    }

  }

  DS.sensor_iic[DS.iic.read_index].failed_code = IIC_WriteRead(BMP388_Addr << 1, 0x04, 0, 0, 6, reg_data, 0);

  

  //数据合成

  uncomp_data.pressure    =  reg_data[2]<<16 | reg_data[1]<<8 | reg_data[0];

  uncomp_data.temperature =  reg_data[5]<<16 | reg_data[4]<<8 | reg_data[3];

  DS.sensor_iic[DS.iic.read_index].continue_failed_cnt = 0;

  DS.sensor_iic[DS.iic.read_index].failed_code = 0;

  return 0;

}



//读取修正系数

void get_calib_data()

{

  uint8_t reg_data[21] = {0};

  

  if(IIC_WriteRead(BMP388_Addr << 1, 0x31, 0, 0, 21, reg_data, 0))

    return;

  

  //根据数据手册的数据类型转换

  calib_data.par_t1  = Concat_Bytes(reg_data[1], reg_data[0]);

  calib_data.par_t2  = Concat_Bytes(reg_data[3], reg_data[2]);

  calib_data.par_t3  = (int8_t)reg_data[4];

  calib_data.par_p1  = (int16_t)Concat_Bytes(reg_data[6], reg_data[5]);

  calib_data.par_p2  = (int16_t)Concat_Bytes(reg_data[8], reg_data[7]);

  calib_data.par_p3  = (int8_t)reg_data[9];

  calib_data.par_p4  = (int8_t)reg_data[10];

  calib_data.par_p5  = Concat_Bytes(reg_data[12], reg_data[11]);

  calib_data.par_p6  = Concat_Bytes(reg_data[14],  reg_data[13]);

  calib_data.par_p7  = (int8_t)reg_data[15];

  calib_data.par_p8  = (int8_t)reg_data[16];

  calib_data.par_p9  = (int16_t)Concat_Bytes(reg_data[18], reg_data[17]);

  calib_data.par_p10 = (int8_t)reg_data[19];

  calib_data.par_p11 = (int8_t)reg_data[20];

}


//修正温度

void compensate_temperature()

{

  uint64_t partial_data1;

  uint64_t partial_data2;

  uint64_t partial_data3;

  int64_t  partial_data4;

  int64_t  partial_data5;

  int64_t  partial_data6;

  int64_t  comp_temp;


  partial_data1 = uncomp_data.temperature - (256 * calib_data.par_t1);

  partial_data2 = calib_data.par_t2 * partial_data1;

  partial_data3 = partial_data1 * partial_data1;

  partial_data4 = (int64_t)partial_data3 * calib_data.par_t3;

  partial_data5 = ((int64_t)(partial_data2 * 262144) + partial_data4);

  partial_data6 = partial_data5 / 4294967296;

  calib_data.t_lin = partial_data6;               /* 存储这个data6为t_lin因为计算气压要用到 */

  comp_temp = (int64_t)((partial_data6 * 25)  / 16384);

  comp_data.temperature = comp_temp;

}


//修正气压

void compensate_pressure()

{

  int64_t partial_data1;

  int64_t partial_data2;

  int64_t partial_data3;

  int64_t partial_data4;

  int64_t partial_data5;

  int64_t partial_data6;

  int64_t offset;

  int64_t sensitivity;

  uint64_t comp_press;


  partial_data1 = calib_data.t_lin * calib_data.t_lin;

  partial_data2 = partial_data1 / 64;

  partial_data3 = (partial_data2 * calib_data.t_lin) / 256;

  partial_data4 = (calib_data.par_p8 * partial_data3) / 32;

  partial_data5 = (calib_data.par_p7 * partial_data1) * 16;

  partial_data6 = (calib_data.par_p6 * calib_data.t_lin) * 4194304;

  offset = (calib_data.par_p5 * 140737488355328) + partial_data4 + partial_data5 + partial_data6;


  partial_data2 = (calib_data.par_p4 * partial_data3) / 32;

  partial_data4 = (calib_data.par_p3 * partial_data1) * 4;

  partial_data5 = (calib_data.par_p2 - 16384) * calib_data.t_lin * 2097152;

  sensitivity = ((calib_data.par_p1 - 16384) * 70368744177664) + partial_data2 + partial_data4 + partial_data5;


  partial_data1 = (sensitivity / 16777216) * uncomp_data.pressure;

  partial_data2 = calib_data.par_p10 * calib_data.t_lin;

  partial_data3 = partial_data2 + (65536 * calib_data.par_p9);

  partial_data4 = (partial_data3 * uncomp_data.pressure) / 8192;

  partial_data5 = (partial_data4 * uncomp_data.pressure) / 512;

  partial_data6 = (int64_t)((uint64_t)uncomp_data.pressure * (uint64_t)uncomp_data.pressure);

  partial_data2 = (calib_data.par_p11 * partial_data6) / 65536;

  partial_data3 = (partial_data2 * uncomp_data.pressure) / 128;

  partial_data4 = (offset / 4) + partial_data1 + partial_data5 + partial_data3;

  comp_press = (((uint64_t)partial_data4 * 25) / (uint64_t)1099511627776);

  comp_data.pressure = comp_press;

}


//BMP388初始化

uint8_t BMP388_Init()

{

  uint8_t tx_buff[1], rx_buff[1];

  

  if(IIC_WriteRead(BMP388_Addr << 1, 0x00, 0, 0, 1, rx_buff, 0)) //读取芯片ID

    return 1;

  if(rx_buff[0] != 0x50) //验证芯片ID

    return 1;

  

  get_calib_data(); //读取补偿系数

  while(1)

  {

    if(IIC_WriteRead(BMP388_Addr << 1, 0x00, 0, 0, 1, rx_buff, 0))

      return 1;

    

    if(rx_buff[0] & 0x10)

      break;

    

    delay_ms(3);

  }

  

  tx_buff[0] = 0xb6;

  IIC_WriteRead(BMP388_Addr << 1, 0x7e, 1, tx_buff, 0, 0, 0); //写重置指令,重置全部寄存器

  delay_ms(5);

  IIC_WriteRead(BMP388_Addr << 1, 0x02, 0, 0, 1, rx_buff, 0);

  if(rx_buff[0] & 0x07) //查看错误指示寄存器,有错误返回1

    return 1;

  tx_buff[0] = 0x00;

  IIC_WriteRead(BMP388_Addr << 1, 0x1c, 1, tx_buff, 0, 0, 0); //设置设置温度过采样*1 气压过采样*1  00 000 000

  tx_buff[0] = 0x04;

  IIC_WriteRead(BMP388_Addr << 1, 0x1f, 1, tx_buff, 0, 0, 0); //设置滤波系数2  0000 010 0

  tx_buff[0] = 0x01;

  IIC_WriteRead(BMP388_Addr << 1, 0x1d, 1, tx_buff, 0, 0, 0); //设置输出分频系数,请按照相关公式计算得出要写的值

  tx_buff[0] = 0x33;

  IIC_WriteRead(BMP388_Addr << 1, 0x1b, 1, tx_buff, 0, 0, 0); //使能气压和温度采样, 启动采样

  return 0;

}


//获得正确的值

void BMP388_Get_PaT()

{

  if(!get_PandT())

  {

    compensate_temperature();

    compensate_pressure();

    

    DS.sensor_iic[DS.iic.read_index].value.flts[0] = comp_data.pressure/100.0; //大气压值

    //DS.sensor_iic[DS.iic.read_index].value.flts[1] = comp_data.temperature/100.0; //温度值

    DS.sensor_iic[DS.iic.read_index].value.flts[1] = 44300*(1-pow(DS.sensor_iic[DS.iic.read_index].value.flts[0]/101325, 1/5.256));//高度值

  }

  DS.iic.read_index++;

  if(DS.iic.read_index >= IIC_MAX_NUM)

    DS.iic.read_index = 0;

}


void BMP388_ON()

{

  uint8_t tx_buff[1];

  

  tx_buff[0] = 0x33;

  IIC_WriteRead(BMP388_Addr << 1, 0x1b, 1, tx_buff, 0, 0, 0); //启动传输 00 11 00 11

}


void BMP388_OFF()

{

  uint8_t tx_buff[1];

  

  tx_buff[0] = 0x03;

  IIC_WriteRead(BMP388_Addr << 1, 0x1b, 1, tx_buff, 0, 0, 0); //进入睡眠 00 00 00 11

}

无线传感器

   无线传感器
● 内置电池或外接5V电源供电
● 多种传感器和通讯接口:I2C、UART、RS485
● 支持WIFI、4G、Lora等多种无线通讯方式
● 支持串口固件升级

9775460cb15acb62aac9043559bac65f.jpg
【传感器 ● 单片机项目定制开发】

dettek

声明:该文观点仅代表作者本人,我们只提供信息存储空间服务。
我来说两句
加载中~