单片机学习小组
直播中

陈杰

7年用户 1429经验值
私信 关注

bmp280调出数据一直不对该怎么办?

调了能有一周了,bmp280,用iic通讯,一直调出数据不对,地址什么的都是按照说明来的,0xec,大神指点一下是不是还差哪里没有配置对,附上程序
#define        BMP280_SlaveAddress   0xec          //定义器件在IIC总线中的从地址                              
#define OSS 0        // Oversampling Setting (note: code is not set up to use other OSS values)
unsigned short dig_T1;
short dig_T2;
short dig_T3;
unsigned short dig_P1;
short dig_P2;
short dig_P3;
short dig_P4;
short dig_P5;
short dig_P6;
short dig_P7;
short dig_P8;
short dig_P9;
void delay()    //略微延时  6us约>4.7us
{
_nop_();
  _nop_();
   _nop_();
    _nop_();
         _nop_();
          _nop_();
}
void iic_start()   //启动信号
{
  SDA=1;
  SCL=1;
  delay();
  SDA=0;
  delay();
  SCL=0;
}
void iic_stop()  //停止信号
{
        SDA=0;
        SCL=1;
        delay();
        SDA=1;
        delay();
        SCL=0;
}
void iic_ack()   //应答信号
{
        uchar i=0;
        SCL=1;
        delay();
        while((SDA==1)&&(i<255))
        i++;
        SCL=0;
        delay();
}
void iic_send_byte(uchar bat)  //发送数据
{
        uchar i,temp;
        temp=bat;
        for(i=0;i<=7;i++)
        {
          temp=temp<<1;
          SCL=0;
          SDA=CY;
          delay();
          SCL=1;
          delay();
        }
        SCL=0;
        delay();
        SDA=1;
        delay();
}
unsigned char iic_rev()  //接受数据
{
  uchar temp,i;
  SCL=0;
  delay();
  SDA=1;
  for(i=0;i<=7;i++)
  {
   SCL=1;
   delay();
   temp=(temp<<1)|SDA;
   SCL=0;
   delay();
  }
  delay();
  return temp;
}
uchar Single_Read(uchar ST_Address)
{
        uchar REG_data;
        //uchar bit;
        
        iic_start();         //起始信号
        iic_send_byte(BMP280_SlaveAddress);           //发送设备地址+写信号
        iic_ack();
        iic_send_byte(ST_Address);             //发送存储单元地址
        iic_ack();
        iic_start();                          //起始信号
        iic_send_byte(BMP280_SlaveAddress+1);         //发送设备地址+读信号
        iic_ack();
        REG_data = iic_rev();     
        iic_ack();    //最后一个数据需要回NOACK
        return REG_data;
}
void Single_Write(uchar SlaveAddress,uchar REG_Address,uchar REG_data)
{
    iic_start();                       //起始信号
    iic_send_byte(SlaveAddress);   //发送设备地址+写信号
        iic_ack();
        iic_send_byte(REG_Address);    //内部寄存器地址
        iic_ack();
        iic_send_byte(REG_data);       //内部寄存器数据
        iic_ack();
        iic_stop();                   //发送停止信号
}
//*********************************************************
//读出BMP085内部数据,连续两个
//*********************************************************
short Multiple_read(uchar ST_Address)
{   
        uchar m***, l***;
        short _data;
        
        l*** = Single_Read(ST_Address);
        m*** = Single_Read(ST_Address+1);
        
        _data = m*** << 8;
        _data |= l***;        
        //rt_kprintf("data is %x %xn",m***,l***);
        return _data;
}
//*********************************************************
//读出BMP085内部数据,连续三个
//*********************************************************
long Multiple_three_read(uchar ST_Address)
{   
        uchar m***, l***,xl***;
        long _data = 0;
        
        m*** = Single_Read(ST_Address);
        l*** = Single_Read(ST_Address+1);
        xl*** = Single_Read(ST_Address+2);
        
        //rt_kprintf("data is %x %x %xn",m***,l***,xl***);
        
        _data = m*** << 16;
        _data |= l*** << 8;        
        _data |= xl***;
        _data = _data >> 4;
        return _data;
}
//**************************************************************
//初始化BMP280,根据需要请参考pdf进行修改**************
void Init_BMP280(void)
{
        unsigned short temp = 0;
        unsigned char write_byte;
        temp = Single_Read(0xd0);//
        dig_T1 = Multiple_read(0x88);
        dig_T2 = Multiple_read(0x8A);
        dig_T3 = Multiple_read(0x8C);
        dig_P1 = Multiple_read(0x8E);
        dig_P2 = Multiple_read(0x90);
        dig_P3 = Multiple_read(0x92);
        dig_P4 = Multiple_read(0x94);
        dig_P5 = Multiple_read(0x96);
        dig_P6 = Multiple_read(0x98);
        dig_P7 = Multiple_read(0x9A);
        dig_P8 = Multiple_read(0x9C);
        dig_P9 = Multiple_read(0x9E);
        write_byte = 0x91;
        Single_Write(BMP280_SlaveAddress,0xf4,write_byte);
        write_byte = 0x00;//配置
        Single_Write(BMP280_SlaveAddress,0xf5,write_byte);//5<<2
        //rt_thread_delay(RT_TICK_PER_SECOND);
        Delay_N1ms(200);        
}
//***********************************************************************
long bmp280Convert(void)
{
        long adc_T;
        long adc_P;
        long var1, var2,t_fine,T,p;
         //rt_kprintf("----------------------------n");
        
        //adc_T = Multiple_three_read(0xFA);
        adc_T = Multiple_three_read(0xFA);    // 读取温度
        //adc_P = Multiple_three_read(0xF7);
        adc_P = Multiple_three_read(0xF7); // 读取压强
        if(adc_P == 0)
        {
                return 0;
        }
        //Temperature
        var1 = (((double)adc_T)/16384.0-((double)dig_T1)/1024.0)*((double)dig_T2);
        //rt_kprintf("var1 is %dn",var1);
        var2 = ((((double)adc_T)/131072.0-((double)dig_T1)/8192.0)*(((double)adc_T)/131072.0-((double)dig_T1)/8192.0))*((double)dig_T3);
        //rt_kprintf("var2 is %dn",var2);
        
        t_fine = (uint32)(var1+var2);
        //rt_kprintf("t_fine is %dn",t_fine);
        
        T = (var1+var2)/5120.0;
        T = T;
        //rt_kprintf("temperature is %dn",T);
        
        var1 = ((double)t_fine/2.0)-64000.0;
        //rt_kprintf("var1 is %dn",var1);
        
        var2 = var1*var1*((double)dig_P6)/32768.0;
        //rt_kprintf("var2 is %dn",var2);
        
        var2 = var2+var1*((double)dig_P5)*2.0;
        //rt_kprintf("var2 is %dn",var2);
        
        var2 = (var2/4.0)+(((double)dig_P4)*65536.0);
        //rt_kprintf("var2 is %dn",var2);
        
        var1 = (((double)dig_P3)*var1*var1/524288.0+((double)dig_P2)*var1)/524288.0;
        //rt_kprintf("var1 is %dn",var1);
        
        var1 = (1.0+var1/32768.0)*((double)dig_P1);
        //rt_kprintf("var1 is %dn",var1);
        
        p = 1048576.0-(double)adc_P;
        //rt_kprintf("p is %dn",p);
        p = (p-(var2/4096.0))*6250.0/var1;
        //rt_kprintf("p is %dn",p);
        
        var1 = ((double)dig_P9)*p*p/2147483648.0;
        //rt_kprintf("var1 is %dn",var1);
        
        var2 = p*((double)dig_P8)/32768.0;
        //rt_kprintf("var2 is %dn",var2);
        
        p = p+(var1+var2+((double)dig_P7))/16.0;
         
        //rt_kprintf("pressure is %dn",p);
        return p;
}
int get_pressure(void)
{         int pressure = 0;
        int i = 0;
         SDA=1;
        SCL=1;
        Delay_N1ms(200);                           //上电延时               
        Init_BMP280();                //初始化BMP085
        while(i < 3)
        {
                pressure = bmp280Convert();
                i++;
        }
//        printf("pressure is %dn",pressure);
        Single_Write(BMP280_SlaveAddress,0xf4,0x24);
        return pressure;
}

回帖(4)

crhm51900928

2019-10-16 08:44:35
扔个程序上来opt101和温湿度.rar (6.91 MB )
举报

朱红艳

2019-10-16 09:03:12
官方都写好了的
举报

老玩铜

2021-11-21 21:59:25
刚搞清楚,我用的是STC8 硬件I2C+BMP280方案,暂时只需要气压读数。不知道你具体用的什么MCU? 软硬件I2C又不同,具体细节太多。。。。

testBMP280ID:
bmp280 id is right...
0101 1000
temp                    press
0000 0000 0000 0001 1000 1011 1000 1111
举报

老玩铜

2022-2-10 17:43:07
目前基本正常,最后的主要问题:
(1) dig_P1 为unsigned short,但我读出来显示总是负数(但好像不影响最终结果),其他参数都正常; 不知道哪里错了,统一定义和读取显示的。
(2)计算气压时,已加手册公式里的一句:if (var1 == 0) { retune 0};
但最后一个var1不知为何读出来都总是0,于是我又在后面再加了一句“if (var1 == 0) { retune0};不然继续算下去最终读数总是低1850Pa(但没用到dig_P7、8、9);
P: var1 = ...;
var2 = ...;
var2 = ...;
var2 = ...;
var1 = (((double)dig_P3)*var1*var1/524288.0+((double)dig_P2)*var1)/524288.0;
var1 = (1.0+var1/32768.0)*((double)dig_P1);
if (var1 == 0.0) return 0; //avoid exception caused by division by zero避免被零除异常;
p = 1048576.0-(double)adc_P;
p = (p-(var2/4096.0))*6250.0/var1;
var1 = ((double)dig_P9)*P*P/2147483648.0; //这个 var1读出来总是0???
if (var1 == 0.0) return 0; // 于是自己再加了1句:更准了(后面2句无效)!
var2 = p*((double)dig_P8)/32768.0;
p = p+(var1+var2+((double)dig_P7))/16.0;
return p;
(3)GY-63模块如此便宜,真不敢相信是否原装货?
(4)其实16位足够一般人用了,用BMP180也够了,模块还小不少,价钱倒还贵一点停产了,不知道什么库存或拆件?MS5611也试过只接4脚就可用,但贵很多很多暂无必要。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分