收藏官网首页
查看: 1339|回复: 0

[经验分享] bmp280 iic读取原始气压数据

106

主题

107

帖子

7261

积分

论坛元老

Rank: 8Rank: 8

积分
7261
跳转到指定楼层
楼主
 楼主| 发表于 2023-10-10 00:37:19 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
校园创客福利
本帖最后由 mmuyu 于 2023-10-10 00:47 编辑

    BMP280是一种常用的气压和温度传感器,广泛用于气象站、气象传感器、室内导航、气压高度计、无人机和其他应用中。它由博世(Bosch Sensortec)公司制造,是其先前版本BMP180的改进型号。使用bmp20可以测量大气压力,以提供当前海拔高度或气压信息,还能够测量环境温度,提供精确的温度数据,用于温度补偿或其他环境监测应用。


首先,要读取bmp20,我们要先了解地址和寄存器配置。



首先是地址,sdo线接到vcc或者gnd会影响第六位的位,我使用的接到gnd,因此是0,实际地址加上读写位在传送的时候实际位0xee,0xef

接下来是寄存器



可见,d0寄存器存放的是芯片的id,始终读出为0x58 我们可以使用这个检测芯片是否损坏。

F4和F5是关于温度寄存器,气压寄存器、模式配置,把寄存器f4配置为0xff则为温度和气压使用最大精度测量,正常工作模式,把f5配置为0x00则是配置自动转换以0.5ms自动转换,至于为什么这样设置,可以看官方手册,由于太多无法一次性放出来。




接下来是读写时序,官方手册提供了写多个寄存器和读出多个寄存器的读写时序:



那么代码的逻辑就是:
读芯片id》》写f4 f5寄存器  读气压寄存器 f6 f7 f8》》 组合20位数据

实际代码:

代码注释已给出

  1. I2C_GenerateSTART(I2C1, ENABLE);//启动iic
  2.             while( !I2C_CheckEvent( I2C1, I2C_EVENT_MASTER_MODE_SELECT ) );//等待切换到主线模式
  3.             I2C_Send7bitAddress(I2C1, 0xee, I2C_Direction_Transmitter);//发送从机地址 写模式
  4.             while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));//等待切换到发送模式
  5.             printf("ack\n");
  6.             I2C_SendData(I2C1, 0xd0);//发送读id地址
  7.             while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));//等待发送完成
  8.             printf("recv\n");


  9.             I2C_GenerateSTART(I2C1, ENABLE);
  10.             while( !I2C_CheckEvent( I2C1, I2C_EVENT_MASTER_MODE_SELECT ) );
  11.             I2C_Send7bitAddress(I2C1, 0xef, I2C_Direction_Receiver);//发送从机地址 读模式
  12.             while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));//等待切换到接收模式 同时充当ack确认
  13.             while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED));//等待接收数据
  14.             uint8_t temp1=I2C_ReceiveData(I2C1);
  15.             printf("data:%x\n",temp1);
  16.             I2C_AcknowledgeConfig(I2C1, DISABLE);//主机发送ack
  17.             I2C_GenerateSTOP(I2C1, ENABLE);
  18.             Delay_Ms(2000);

  19.             if(temp1==0x58){
  20.                 if(is_w==0){
  21.                 printf("ok\n");
  22.                 I2C_GenerateSTART(I2C1, ENABLE);
  23.                 while( !I2C_CheckEvent( I2C1, I2C_EVENT_MASTER_MODE_SELECT ) );
  24.                 I2C_Send7bitAddress(I2C1, 0xee, I2C_Direction_Transmitter);
  25.                 while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
  26.                 printf("ack\n");
  27.                 I2C_SendData(I2C1, 0xf4);//写温度寄存器
  28.                 while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
  29.                 I2C_SendData(I2C1, 0xff);
  30.                 while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
  31.                 printf("f4 send\n");
  32.                 I2C_SendData(I2C1, 0xf5);//写气压寄存器
  33.                 while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
  34.                 I2C_SendData(I2C1, 0x00);
  35.                 while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
  36.                 printf("f5 send\n");
  37.                 I2C_GenerateSTOP(I2C1, ENABLE);
  38.                 Delay_Ms(50);
  39.                 is_w=1;
  40.                 }
  41.                 //press_read
  42.                 I2C_GenerateSTART(I2C1, ENABLE);
  43.                 while( !I2C_CheckEvent( I2C1, I2C_EVENT_MASTER_MODE_SELECT ) );
  44.                 I2C_Send7bitAddress(I2C1, 0xee, I2C_Direction_Transmitter);
  45.                 while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
  46.                 printf("ack\n");
  47.                 I2C_SendData(I2C1, 0xf7);
  48.                 while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
  49.                 printf("recv\n");

  50.                 I2C_GenerateSTART(I2C1, ENABLE);
  51.                 while( !I2C_CheckEvent( I2C1, I2C_EVENT_MASTER_MODE_SELECT ) );
  52.                 I2C_Send7bitAddress(I2C1, 0xef, I2C_Direction_Receiver);
  53.                 while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
  54.                 while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED));
  55.                 press_val[0]=I2C_ReceiveData(I2C1);
  56.                 I2C_AcknowledgeConfig(I2C1, ENABLE);
  57.                 printf("press_val_%d:%x\n",0,press_val[0]);
  58.                 I2C_AcknowledgeConfig(I2C1, DISABLE);
  59.                 I2C_GenerateSTOP(I2C1, ENABLE);
  60.                 Delay_Ms(10);

  61.                 I2C_GenerateSTART(I2C1, ENABLE);
  62.                 while( !I2C_CheckEvent( I2C1, I2C_EVENT_MASTER_MODE_SELECT ) );
  63.                 I2C_Send7bitAddress(I2C1, 0xee, I2C_Direction_Transmitter);
  64.                 while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
  65.                 printf("ack\n");
  66.                 I2C_SendData(I2C1, 0xf8);
  67.                 while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
  68.                 printf("recv\n");

  69.                 I2C_GenerateSTART(I2C1, ENABLE);
  70.                 while( !I2C_CheckEvent( I2C1, I2C_EVENT_MASTER_MODE_SELECT ) );
  71.                 I2C_Send7bitAddress(I2C1, 0xef, I2C_Direction_Receiver);
  72.                 while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
  73.                 while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED));
  74.                 press_val[1]=I2C_ReceiveData(I2C1);
  75.                 I2C_AcknowledgeConfig(I2C1, ENABLE);
  76.                 printf("press_val_%d:%x\n",1,press_val[1]);
  77.                 I2C_AcknowledgeConfig(I2C1, DISABLE);
  78.                 I2C_GenerateSTOP(I2C1, ENABLE);
  79.                 Delay_Ms(10);

  80.                 I2C_GenerateSTART(I2C1, ENABLE);
  81.                 while( !I2C_CheckEvent( I2C1, I2C_EVENT_MASTER_MODE_SELECT ) );
  82.                 I2C_Send7bitAddress(I2C1, 0xee, I2C_Direction_Transmitter);
  83.                 while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
  84.                 printf("ack\n");
  85.                 I2C_SendData(I2C1, 0xf9);
  86.                 while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
  87.                 printf("recv\n");

  88.                 I2C_GenerateSTART(I2C1, ENABLE);
  89.                 while( !I2C_CheckEvent( I2C1, I2C_EVENT_MASTER_MODE_SELECT ) );
  90.                 I2C_Send7bitAddress(I2C1, 0xef, I2C_Direction_Receiver);
  91.                 while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
  92.                 while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED));
  93.                 press_val[2]=I2C_ReceiveData(I2C1);
  94.                 I2C_AcknowledgeConfig(I2C1, ENABLE);
  95.                 printf("press_val_%d:%x\n",2,press_val[2]);
  96.                 I2C_AcknowledgeConfig(I2C1, DISABLE);
  97.                 I2C_GenerateSTOP(I2C1, ENABLE);
  98.                 Delay_Ms(10);
  99.             }
  100.             uint32_t press_v= (press_val[0] << 12) | (press_val[1] << 4) | (press_val[2] >> 4);
  101.             printf("press_val:%d\n",press_v);
  102.             printf("finish\n");
复制代码


编译烧录到单片机看看:



从串口上可以看见,读出值为30多万,单位是hpa,由于是原始的数据,并未经过转换,还需要经过一次转换才能转换为气压值,转换过程官方手册已提供代码,这里就不展示了。

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

本版积分规则

加入Q群 返回顶部

版权与免责声明 © 2006-2024 Gizwits IoT Technology Co., Ltd. ( 粤ICP备11090211号 )

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