bmp280 iic读取原始气压数据
本帖最后由 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=I2C_ReceiveData(I2C1);
I2C_AcknowledgeConfig(I2C1, ENABLE);
printf("press_val_%d:%x\n",0,press_val);
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=I2C_ReceiveData(I2C1);
I2C_AcknowledgeConfig(I2C1, ENABLE);
printf("press_val_%d:%x\n",1,press_val);
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=I2C_ReceiveData(I2C1);
I2C_AcknowledgeConfig(I2C1, ENABLE);
printf("press_val_%d:%x\n",2,press_val);
I2C_AcknowledgeConfig(I2C1, DISABLE);
I2C_GenerateSTOP(I2C1, ENABLE);
Delay_Ms(10);
}
uint32_t press_v= (press_val << 12) | (press_val << 4) | (press_val >> 4);
printf("press_val:%d\n",press_v);
printf("finish\n");
编译烧录到单片机看看:
从串口上可以看见,读出值为30多万,单位是hpa,由于是原始的数据,并未经过转换,还需要经过一次转换才能转换为气压值,转换过程官方手册已提供代码,这里就不展示了。
页:
[1]