mmuyu 发表于 2023-10-10 00:37:19

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]
查看完整版本: bmp280 iic读取原始气压数据