|
本帖最后由 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位数据
实际代码:
代码注释已给出
- I2C_GenerateSTART(I2C1, ENABLE);//启动iic
- while( !I2C_CheckEvent( I2C1, I2C_EVENT_MASTER_MODE_SELECT ) );//等待切换到主线模式
- I2C_Send7bitAddress(I2C1, 0xee, I2C_Direction_Transmitter);//发送从机地址 写模式
- while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));//等待切换到发送模式
- printf("ack\n");
- I2C_SendData(I2C1, 0xd0);//发送读id地址
- while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));//等待发送完成
- printf("recv\n");
- I2C_GenerateSTART(I2C1, ENABLE);
- while( !I2C_CheckEvent( I2C1, I2C_EVENT_MASTER_MODE_SELECT ) );
- I2C_Send7bitAddress(I2C1, 0xef, I2C_Direction_Receiver);//发送从机地址 读模式
- while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));//等待切换到接收模式 同时充当ack确认
- while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED));//等待接收数据
- uint8_t temp1=I2C_ReceiveData(I2C1);
- printf("data:%x\n",temp1);
- I2C_AcknowledgeConfig(I2C1, DISABLE);//主机发送ack
- I2C_GenerateSTOP(I2C1, ENABLE);
- Delay_Ms(2000);
- if(temp1==0x58){
- if(is_w==0){
- printf("ok\n");
- I2C_GenerateSTART(I2C1, ENABLE);
- while( !I2C_CheckEvent( I2C1, I2C_EVENT_MASTER_MODE_SELECT ) );
- I2C_Send7bitAddress(I2C1, 0xee, I2C_Direction_Transmitter);
- while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
- printf("ack\n");
- I2C_SendData(I2C1, 0xf4);//写温度寄存器
- while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
- I2C_SendData(I2C1, 0xff);
- while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
- printf("f4 send\n");
- I2C_SendData(I2C1, 0xf5);//写气压寄存器
- while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
- I2C_SendData(I2C1, 0x00);
- while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
- printf("f5 send\n");
- I2C_GenerateSTOP(I2C1, ENABLE);
- Delay_Ms(50);
- is_w=1;
- }
- //press_read
- I2C_GenerateSTART(I2C1, ENABLE);
- while( !I2C_CheckEvent( I2C1, I2C_EVENT_MASTER_MODE_SELECT ) );
- I2C_Send7bitAddress(I2C1, 0xee, I2C_Direction_Transmitter);
- while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
- printf("ack\n");
- I2C_SendData(I2C1, 0xf7);
- while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
- printf("recv\n");
- I2C_GenerateSTART(I2C1, ENABLE);
- while( !I2C_CheckEvent( I2C1, I2C_EVENT_MASTER_MODE_SELECT ) );
- I2C_Send7bitAddress(I2C1, 0xef, I2C_Direction_Receiver);
- while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
- while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED));
- press_val[0]=I2C_ReceiveData(I2C1);
- I2C_AcknowledgeConfig(I2C1, ENABLE);
- printf("press_val_%d:%x\n",0,press_val[0]);
- I2C_AcknowledgeConfig(I2C1, DISABLE);
- I2C_GenerateSTOP(I2C1, ENABLE);
- Delay_Ms(10);
- I2C_GenerateSTART(I2C1, ENABLE);
- while( !I2C_CheckEvent( I2C1, I2C_EVENT_MASTER_MODE_SELECT ) );
- I2C_Send7bitAddress(I2C1, 0xee, I2C_Direction_Transmitter);
- while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
- printf("ack\n");
- I2C_SendData(I2C1, 0xf8);
- while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
- printf("recv\n");
- I2C_GenerateSTART(I2C1, ENABLE);
- while( !I2C_CheckEvent( I2C1, I2C_EVENT_MASTER_MODE_SELECT ) );
- I2C_Send7bitAddress(I2C1, 0xef, I2C_Direction_Receiver);
- while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
- while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED));
- press_val[1]=I2C_ReceiveData(I2C1);
- I2C_AcknowledgeConfig(I2C1, ENABLE);
- printf("press_val_%d:%x\n",1,press_val[1]);
- I2C_AcknowledgeConfig(I2C1, DISABLE);
- I2C_GenerateSTOP(I2C1, ENABLE);
- Delay_Ms(10);
- I2C_GenerateSTART(I2C1, ENABLE);
- while( !I2C_CheckEvent( I2C1, I2C_EVENT_MASTER_MODE_SELECT ) );
- I2C_Send7bitAddress(I2C1, 0xee, I2C_Direction_Transmitter);
- while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
- printf("ack\n");
- I2C_SendData(I2C1, 0xf9);
- while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
- printf("recv\n");
- I2C_GenerateSTART(I2C1, ENABLE);
- while( !I2C_CheckEvent( I2C1, I2C_EVENT_MASTER_MODE_SELECT ) );
- I2C_Send7bitAddress(I2C1, 0xef, I2C_Direction_Receiver);
- while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
- while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED));
- press_val[2]=I2C_ReceiveData(I2C1);
- I2C_AcknowledgeConfig(I2C1, ENABLE);
- printf("press_val_%d:%x\n",2,press_val[2]);
- I2C_AcknowledgeConfig(I2C1, DISABLE);
- I2C_GenerateSTOP(I2C1, ENABLE);
- Delay_Ms(10);
- }
- uint32_t press_v= (press_val[0] << 12) | (press_val[1] << 4) | (press_val[2] >> 4);
- printf("press_val:%d\n",press_v);
- printf("finish\n");
复制代码
编译烧录到单片机看看:
从串口上可以看见,读出值为30多万,单位是hpa,由于是原始的数据,并未经过转换,还需要经过一次转换才能转换为气压值,转换过程官方手册已提供代码,这里就不展示了。
|
|