久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 6954|回復(fù): 10
打印 上一主題 下一主題
收起左側(cè)

51單片機初學(xué)實踐:用BME280模塊獲取溫度、濕度和氣壓數(shù)據(jù)

  [復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:759974 發(fā)表于 2020-7-18 23:54 | 只看該作者 |只看大圖 回帖獎勵 |倒序瀏覽 |閱讀模式
我想為電子鐘增加環(huán)境數(shù)據(jù)監(jiān)測功能,主要是氣溫,濕度和氣壓這三項,BME280模塊可以測量這三項數(shù)據(jù),是一個不錯的選擇。









今天對照datasheet和之前壇友分享的資料,編寫代碼實現(xiàn)了氣溫,濕度和氣壓這三項數(shù)據(jù)的讀取,并在LCD1602屏幕和UART打印顯示,
效果如圖所示:






在實踐過程中,有以下心得:

1、BME280模塊有三種工作模式,其中forced mode適合我的需要







2、我的需求,可以對照Weather Monitoring方式,文檔上有詳細說明
我對精度要求并不高,oversampleing選擇x1即可,如此設(shè)置,功耗也最小。










3、讀取的ADC數(shù)據(jù),不能直接使用,必須進行補償計算,64位整數(shù)運算精度最高,但對于單片機不太合適,可以使用double類型
計算過程,詳見datasheet中的附件代碼









main函數(shù)代碼:

  1. void main()
  2. {
  3.         uint8 chip_id = 0;
  4.         uint8 pdata pbuf[31] = {0};

  5.         ConfigUART(9600);
  6.         printf(">ConfigUART done.\r\n\r\n");
  7.         Delay500ms();

  8.         BME280_Init();
  9.         printf(">BME280_Init done.\r\n\r\n");
  10.         Delay500ms();

  11.         chip_id        = BME280_Read_Chip_Id();
  12.         printf(">BME280_Chip_Id = 0x%bx\r\n\r\n", (uint8)chip_id);

  13.     LCD1602_Init();        //初始化液晶
  14.         LCD1602_Show_Char(6, 0, 0);        //5x7字符 ℃
  15.         LCD1602_Show_Char(14, 0, '%');//5x7字符 %
  16.         LCD1602_Show_Str(8, 1, "hPa"); // 液晶顯示屏更新顯示
  17.        
  18.         while(1)
  19.         {
  20.                 Delay500ms();Delay500ms();
  21.                 BME280_Read_ADC(&BME280_adc_P, &BME280_adc_T, &BME280_adc_H);
  22.                 printf(">BME280_adc_T = 0x%08lx \r\n", BME280_adc_T);
  23.                 printf(">BME280_adc_H = 0x%08lx \r\n", BME280_adc_H);
  24.                 printf(">BME280_adc_P = 0x%08lx \r\n", BME280_adc_P);
  25.                 printf("\r\n");

  26.                 BME280_Temperature        = BME280_compensate_T_double(BME280_adc_T);
  27.                 BME280_Humidity                = BME280_compensate_H_double(BME280_adc_H);
  28.                 BME280_Pressure                = BME280_compensate_P_double(BME280_adc_P);
  29.                
  30.                 sprintf(pbuf, "%6.2f", BME280_Temperature);
  31.                 printf(">BME280_Temperature : %s c\r\n", pbuf);
  32.                 LCD1602_Show_Str(0, 0, pbuf); // 液晶顯示屏更新顯示

  33.                 sprintf(pbuf, "%6.2f", BME280_Humidity);
  34.                 printf(">BME280_Humidity : %s %%\r\n", pbuf);
  35.                 LCD1602_Show_Str(8, 0, pbuf); // 液晶顯示屏更新顯示
  36.                
  37.                 sprintf(pbuf, "%7.2f", BME280_Pressure/100);
  38.                 printf(">BME280_Pressure : %s hPa\r\n", pbuf);
  39.                 LCD1602_Show_Str(0, 1, pbuf); // 液晶顯示屏更新顯示

  40.                 printf("--------------------------------\r\n\r\n");
  41.         }
  42. }
復(fù)制代碼

讀取ADC數(shù)據(jù)代碼:

  1. void BME280_Read_ADC(int32 *adc_P, int32 *adc_T, int32 *adc_H)
  2. {
  3.         uint8 press_msb, press_lsb, press_xlsb;
  4.         uint8 temp_msb, temp_lsb, temp_xlsb;
  5.         uint8 hum_msb, hum_lsb;

  6.         BME280_Set_Measure_Mode();
  7.         BME280_Read_Compensation_Parameters();

  8.         i2c_start();
  9.         i2c_write_byte(BME280_SlaveAddr_Write);
  10.         i2c_send_nack();
  11.         i2c_write_byte(BME280_RegAddr_Pressure);
  12.         i2c_send_nack();
  13.         i2c_start();                        
  14.         i2c_write_byte(BME280_SlaveAddr_Read); // burst read from 0xF7 to 0xFE
  15.         i2c_send_nack();

  16.         // read pressure
  17.         press_msb  = BME280_Burst_Read_Byte_Ack(); // 0xF7, burst read begin
  18.         press_lsb  = BME280_Burst_Read_Byte_Ack(); // 0xF8
  19.         press_xlsb = BME280_Burst_Read_Byte_Ack(); // 0xF9

  20.         // read temperature
  21.         temp_msb  = BME280_Burst_Read_Byte_Ack(); // 0xFA
  22.         temp_lsb  = BME280_Burst_Read_Byte_Ack(); // 0xFB
  23.         temp_xlsb = BME280_Burst_Read_Byte_Ack(); // 0xFC

  24.         // read humidity
  25.         hum_msb  = BME280_Burst_Read_Byte_Ack(); // 0xFD
  26.         hum_lsb  = BME280_Burst_Read_Byte_NAck(); // 0xFE, burst read end

  27.         *adc_P        = (int32)(((uint32)press_msb << 12)|((uint32)press_lsb << 4)|((uint32)press_xlsb >> 4));
  28.         *adc_T        = (int32)(((uint32)temp_msb << 12)|((uint32)temp_lsb << 4)|((uint32)temp_xlsb >> 4));
  29.         *adc_H        = (int32)(((uint32)hum_msb<<8)|((uint32)hum_lsb));
  30. }
復(fù)制代碼

ADC數(shù)據(jù)的補償計算代碼(double類型):

  1. // Returns temperature in DegC, double precision. Output value of "51.23" equals 51.23 DegC.
  2. // t_fine carries fine temperature as global value
  3. double BME280_compensate_T_double(BME280_s32_t adc_T)
  4. {
  5.         double var1, var2, T;
  6.         var1 = (((double)adc_T) / 16384.0 - ((double)dig_T1) / 1024.0) * ((double)dig_T2);
  7.         var2 = ((((double)adc_T) / 131072.0 - ((double)dig_T1) / 8192.0) * (((double)adc_T) / 131072.0 - ((double)dig_T1) / 8192.0)) * ((double)dig_T3);

  8.         t_fine = (BME280_s32_t)(var1 + var2);
  9.         T = (var1 + var2) / 5120.0;

  10.         return T;
  11. }

  12. // Returns pressure in Pa as unsigned 32 bit integer. Output value of "96386.2" equals 96386 Pa = 963.86 hPa
  13. double BME280_compensate_P_double(BME280_s32_t adc_P)
  14. {
  15.         double var1, var2, p;
  16.         var1 = ((double)t_fine / 2.0) - 64000.0;
  17.         var2 = var1 * var1 * ((double)dig_P6) / 32768.0;
  18.         var2 = var2 + var1 * ((double)dig_P5) * 2.0;
  19.         var2 = (var2 / 4.0) + (((double)dig_P4) * 65536.0);
  20.         var1 = (((double)dig_P3) * var1 * var1 / 524288.0 + ((double)dig_P2) * var1) / 524288.0;
  21.         var1 = (1.0 + var1 / 32768.0) * ((double)dig_P1);
  22.         if(0.0 == var1)
  23.         {
  24.                 return 0; // avoid exception caused by division by zero
  25.         }
  26.         p = 1048576.0 - (double)adc_P;
  27.         p = (p - (var2 / 4096.0)) * 6250.0 / var1;
  28.         var1 = ((double)dig_P9) * p * p / 2147483648.0;
  29.         var2 = p * ((double)dig_P8) / 32768.0;
  30.         p = p + (var1 + var2 + ((double)dig_P7)) / 16.0;
  31.        
  32.         return p;
  33. }

  34. // Returns humidity in %rH as as double. Output value of "46.332" represents 46.332 %rH
  35. double BME280_compensate_H_double(BME280_s32_t adc_H)
  36. {
  37.         double var_H;

  38.         var_H = (((double)t_fine) - 76800.00);
  39.         var_H = (adc_H - (((double)dig_H4) * 64.0 + ((double)dig_H5) / 16384.0 * var_H)) * (((double)dig_H2) / 65536.0 * (1.0 + ((double)dig_H6) / 67108864.0 * var_H * (1.0 + ((double)dig_H3) / 67108864.0 * var_H)));
  40.         var_H = var_H * (1.0 - ((double)dig_H1) * var_H / 524288.0);
  41.        
  42.         if(var_H > 100.0)
  43.         {
  44.                 var_H = 100.0;
  45.         }
  46.         else if(var_H < 0.0)
  47.         {
  48.                 var_H = 0.0;
  49.         }
  50.        
  51.         return var_H;
  52. }
復(fù)制代碼

詳細代碼請參見附件





以上代碼使用C51開發(fā)板調(diào)試,接線簡單,具體端口可參看config.h

初學(xué)單片機,難免有錯漏之處,還請各位壇友不吝賜教。


BME280_UART_LCD1602_STC89C52RC.7z (1.33 MB, 下載次數(shù): 162)



評分

參與人數(shù) 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏6 分享淘帖 頂1 踩
回復(fù)

使用道具 舉報

沙發(fā)
ID:810398 發(fā)表于 2020-8-1 20:14 | 只看該作者
學(xué)習(xí)一下,有AVR單片機驅(qū)動BME280的程序嗎?
回復(fù)

使用道具 舉報

板凳
ID:601357 發(fā)表于 2021-1-22 21:09 | 只看該作者
謝謝分享我再找找為什么獲取溫度壓力都可以但是濕度怎么都是0的原因
回復(fù)

使用道具 舉報

地板
ID:810398 發(fā)表于 2021-2-13 18:50 | 只看該作者
以上代碼轉(zhuǎn)換為AVR單片機的程序,多謝分享!

#define   int8     signed   char
#define   int16    signed   int
#define   int32    signed long int
#define   uint8    unsigned char
#define   uint16   unsigned int       
#define   uint32   unsigned long int  
#define BME280_s32_t signed long int
#define BME280_u32_t unsigned long int

#define BME280_SCL_INPUT    (DDRD &= ~(1 << PD7))  //SCL設(shè)置為輸入口
#define BME280_SCL_OUTPUT   (DDRD |= (1 << PD7))  //SCL設(shè)置為輸出口
#define BME280_SCL_LOW      (PORTD &= ~(1 << PD7))   //SCL設(shè)置為輸出低電平
#define BME280_SCL_HIGH     (PORTD |= (1 << PD7))   //SCL設(shè)置為輸出高電平
#define BME280_SCL_INDATA   (PIND & (1 << PD7))   //讀取SCL的端口狀態(tài)

#define BME280_SDA_INPUT    (DDRB &= ~(1 << PB7))  //SDA設(shè)置為輸入口
#define BME280_SDA_OUTPUT   (DDRB |= (1 << PB7))  //SDA設(shè)置為輸出口
#define BME280_SDA_LOW      (PORTB &= ~(1 << PB7))   //SDA設(shè)置為輸出低電平
#define BME280_SDA_HIGH     (PORTB |= (1 << PB7))   //SDA設(shè)置為輸出高電平
#define BME280_SDA_INDATA   (PINB & (1 << PB7))   //讀取SDA的端口狀態(tài)

#define        BME280_SlaveAddr_Write        0xEC
#define        BME280_SlaveAddr_Read        0xEC+1
#define        BME280_RegAddr_Pressure        0xF7

uint16         dig_T1;
int16         dig_T2;
int16         dig_T3;
uint16         dig_P1;
int16         dig_P2;
int16         dig_P3;
int16         dig_P4;
int16         dig_P5;
int16         dig_P6;
int16         dig_P7;
int16         dig_P8;
int16         dig_P9;
uint8         dig_H1;
int16         dig_H2;
uint8         dig_H3;
int16         dig_H4;
int16         dig_H5;
int16         dig_H6;

int32  BME280_adc_T;
int32  BME280_adc_P;
int32  BME280_adc_H;

double  BME280_Temperature;
double  BME280_Pressure;
double  BME280_Humidity;

BME280_s32_t  t_fine;


void BME280_delay_us(unsigned int delay_counter)//延時1us
{   
   do
   {
      delay_counter--;       
          WDR();             //喂狗程序  
   }while(delay_counter>1);
}
void BME280_Delay_ms(unsigned int delay_counter)
{
while(delay_counter!=0)
   {
          BME280_delay_us(1000);
      delay_counter--;
          WDR();             //喂狗程序
   }
}

/* 產(chǎn)生I2C總線INPUT;                              //SDA設(shè)置為輸入口
   BME280_dela起始信號 */
void i2c_start()
{
   /* I2C_SDA = 1; //首先確保SDA、SCL都是高電平
    I2C_SCL = 1;
    i2c_delay();
    I2C_SDA = 0; //先拉低SDA
    i2c_delay();
    I2C_SCL = 0; //再拉低SCL
        */
// BME280_delay_us(10);
  BME280_SDA_INPUT;//SDA=1;
  //BME280_delay_us(10);
  BME280_SCL_INPUT;//SCL=1;
  BME280_delay_us(10);
  BME280_SDA_OUTPUT;//SDA=0;
  BME280_delay_us(10);
  BME280_SCL_OUTPUT;//SCL=0;
  //BME280_delay_us(10);
  //return 1;
}

/* 產(chǎn)生I2C總線停止信號 */
void i2c_stop()
{
    /*
        I2C_SCL = 0; //首先確保SDA、SCL都是低電平
    I2C_SDA = 0;
    i2c_delay();
    I2C_SCL = 1; //先拉高SCL
    i2c_delay();
    I2C_SDA = 1; //再拉高SDA
    i2c_delay();
        */
        //BME280_delay_us(10);
        BME280_SCL_OUTPUT;//SCL=0;
        BME280_SDA_OUTPUT; //SDA=0;
        BME280_delay_us(10);
        BME280_SCL_INPUT;//SCL=1;
        BME280_delay_us(10);
        BME280_SDA_INPUT;//SDA=1;
        BME280_delay_us(10);       
}

/* I2C總線發(fā)送ACK信號 */
void i2c_send_ack()
{
    /*
        I2C_SDA = 0;   //8位數(shù)據(jù)發(fā)送完后,拉低SDA,發(fā)送ACK應(yīng)答信號
    i2c_delay();
    I2C_SCL = 1;   //拉高SCL
    i2c_delay();
    I2C_SCL = 0;   //再拉低SCL完成應(yīng)答位,并保持住總線       
        */
        BME280_SDA_OUTPUT; //SDA=0;
        BME280_delay_us(10);
        BME280_SCL_INPUT;//SCL=1;
        BME280_delay_us(10);       
        BME280_SCL_OUTPUT;//SCL=0;
}

/* I2C總線發(fā)送NACK信號 */
void i2c_send_nack()
{
    /*
        I2C_SDA = 1;   //8位數(shù)據(jù)發(fā)送完后,拉高SDA,發(fā)送NACK非應(yīng)答信號
    i2c_delay();
    I2C_SCL = 1;   //拉高SCL
    i2c_delay();
    I2C_SCL = 0;   //再拉低SCL完成應(yīng)答位,并保持住總線       
        */
        BME280_SDA_INPUT;//SDA=1;
        BME280_delay_us(10);
        BME280_SCL_INPUT;//SCL=1;
        BME280_delay_us(10);       
        BME280_SCL_OUTPUT;//SCL=0;
}

/* I2C總線寫操作,dat-待寫入字節(jié),返回值-從機應(yīng)答位的值 */
void i2c_write_byte(uint8 dat)
{
    uint8 mask;  //用于探測字節(jié)內(nèi)某一位值的掩碼變量

    for (mask=0x80; mask!=0; mask>>=1) //從高位到低位依次進行
    {
        if ((mask&dat) == 0)  //該位的值輸出到SDA上
            BME280_SDA_OUTPUT; //SDA=0;//I2C_SDA = 0;
        else
            BME280_SDA_INPUT;//SDA=1;//I2C_SDA = 1;
        BME280_delay_us(10);        //i2c_delay();
        BME280_SCL_INPUT;//SCL=1;//I2C_SCL = 1;          //拉高SCL
        BME280_delay_us(10);        //i2c_delay();
        BME280_SCL_OUTPUT;//SCL=0;//I2C_SCL = 0;          //再拉低SCL,完成一個位周期
    }
}


/* I2C總線讀操作,返回值-讀到的字節(jié) */
uint8 i2c_read_byte()
{
    uint8 mask;
    uint8 dat;

    BME280_SDA_INPUT;//SDA=1;I2C_SDA = 1;  //首先確保主機釋放SDA
    for (mask=0x80; mask!=0; mask>>=1) //從高位到低位依次進行
    {
        BME280_delay_us(10);        //i2c_delay();
        BME280_SCL_INPUT;//SCL=1;I2C_SCL = 1;      //拉高SCL
        if(BME280_SDA_INDATA)//if(I2C_SDA == 0)  //讀取SDA的值
            dat |= mask;  //為1時,dat中對應(yīng)位置1
        else            
                        dat &= ~mask; //為0時,dat中對應(yīng)位清零
        BME280_delay_us(10);        //i2c_delay();
        BME280_SCL_OUTPUT;//SCL=0;I2C_SCL = 0;      //再拉低SCL,以使從機發(fā)送出下一位
    }

    return dat;
}

uint8 BME280_Read_Byte(uint8 read_addr)
{
        uint8 dat;

        i2c_start();         
        i2c_write_byte(BME280_SlaveAddr_Write);
        i2c_send_nack();
        i2c_write_byte(read_addr);
        i2c_send_nack();

        i2c_start();
        i2c_write_byte(BME280_SlaveAddr_Read);
        i2c_send_nack();

        dat = i2c_read_byte();
        i2c_send_nack();

        return dat;
}

void BME280_Write_Byte(uint8 write_addr, uint8 dat)
{
        i2c_start();                       
        i2c_write_byte(BME280_SlaveAddr_Write);
        i2c_send_nack();
        i2c_write_byte(write_addr);
        i2c_send_nack();
        i2c_write_byte(dat);
        i2c_send_nack();
        i2c_stop();                  
}

int16 BME280_Read_Word(uint8 read_addr)
{   
        uint8 msb, lsb;
        int16 dat;

        i2c_start();
        i2c_write_byte(BME280_SlaveAddr_Write);
        i2c_send_nack();
        i2c_write_byte(read_addr);
        i2c_send_nack();
        i2c_start();
        i2c_write_byte(BME280_SlaveAddr_Read); // burst read two bytes
        i2c_send_nack();
    lsb = i2c_read_byte();
        i2c_send_ack();
    msb = i2c_read_byte();
        i2c_send_nack();

        dat = msb << 8;
        dat |= lsb;        

        return dat;
}

void BME280_Reset()
{
    BME280_Write_Byte(0xE0, 0xB6);
}

uint8 BME280_Read_Chip_Id()
{
        uint8 cid = 0;
        cid = BME280_Read_Byte(0xD0);
        // ASSERT(cid == 0X60)
       
        return cid;
}

void BME280_Set_Measure_Mode()
{
        // Humidity oversampling x1
        BME280_Write_Byte(0xF2, 0x01);
        // Pressure oversampling x1
        // Temperature oversampling x1
        // Set sensor forced mode
        BME280_Write_Byte(0xF4, 0x26);
}


uint8 BME280_Burst_Read_Byte_Ack()
{
        uint8 dat;

    dat = i2c_read_byte();
        i2c_send_ack();
       
        return dat;
}

uint8 BME280_Burst_Read_Byte_NAck()
{
        uint8 dat;

    dat = i2c_read_byte();
        i2c_send_nack();
       
        return dat;
}


uint16 BME280_Burst_Read_Word_Ack()
{
        uint8 msb, lsb;
        uint16 dat;

    lsb = i2c_read_byte();
        i2c_send_ack();
    msb = i2c_read_byte();
        i2c_send_ack();
        dat = msb << 8;
        dat |= lsb;
       
        return dat;
}

void BME280_Read_Compensation_Parameters()
{
        uint8 i, j, k;

        i2c_start();
        i2c_write_byte(BME280_SlaveAddr_Write);
        i2c_send_nack();
        i2c_write_byte(0x88);
        i2c_send_nack();

        i2c_start();
        i2c_write_byte(BME280_SlaveAddr_Read);
        i2c_send_nack();
       
        /* 0x88 - 0x89 */
        dig_T1 = (uint16)BME280_Burst_Read_Word_Ack();
        /* 0x8a - 0x8b */
        dig_T2 = (int16)BME280_Burst_Read_Word_Ack();
        /* 0x8c - 0x8d */
        dig_T3 = (int16)BME280_Burst_Read_Word_Ack();

        /* 0x8E - 0x8F */
        dig_P1 = (uint16)BME280_Burst_Read_Word_Ack();
        /* 0x90 - 0x91 */
        dig_P2 = (int16)BME280_Burst_Read_Word_Ack();
        /* 0x92 - 0x93 */
        dig_P3 = (int16)BME280_Burst_Read_Word_Ack();
        /* 0x94 - 0x95 */
        dig_P4 = (int16)BME280_Burst_Read_Word_Ack();
        /* 0x96 - 0x97 */
        dig_P5 = (int16)BME280_Burst_Read_Word_Ack();
        /* 0x98 - 0x99 */
        dig_P6 = (int16)BME280_Burst_Read_Word_Ack();
        /* 0x9A - 0x9B */
        dig_P7 = (int16)BME280_Burst_Read_Word_Ack();
        /* 0x9C - 0x9D */
        dig_P8 = (int16)BME280_Burst_Read_Word_Ack();
        /* 0x9E - 0x9F */
        dig_P9 = (int16)BME280_Burst_Read_Word_Ack();

        /* 0xA0 skip */
        BME280_Burst_Read_Byte_Ack();

        /* 0xA1 */
        dig_H1 = (uint8)BME280_Burst_Read_Byte_NAck();

        i2c_start();
        i2c_write_byte(BME280_SlaveAddr_Write);
        i2c_send_nack();
        i2c_write_byte(0xE1);
        i2c_send_nack();

        i2c_start();
        i2c_write_byte(BME280_SlaveAddr_Read);
        i2c_send_nack();

        /* 0xE1 - 0xE2 */
        dig_H2 = (int16)BME280_Burst_Read_Word_Ack();
        /* 0xE3 */
        dig_H3 = (uint8)BME280_Burst_Read_Byte_Ack();

        /* 0xE4 - 0xE6 */
        i = (uint8)BME280_Burst_Read_Byte_Ack();
        j = (uint8)BME280_Burst_Read_Byte_Ack();
        k = (uint8)BME280_Burst_Read_Byte_Ack();

        dig_H4 = (int16)((i << 4) | (j & 0x0F));
        dig_H5 = (int16)((k << 4) | (j >> 4));

        /* 0xE7 */
        dig_H6 = (int16)BME280_Burst_Read_Byte_NAck();
}

void BME280_Init(void)
{

        BME280_Reset();
        BME280_Write_Byte(0xF5, 0x00);
}

void BME280_Read_ADC(int32 *adc_P, int32 *adc_T, int32 *adc_H)
{
        uint8 press_msb, press_lsb, press_xlsb;
        uint8 temp_msb, temp_lsb, temp_xlsb;
        uint8 hum_msb, hum_lsb;

        BME280_Set_Measure_Mode();
        BME280_Read_Compensation_Parameters();

        i2c_start();
        i2c_write_byte(BME280_SlaveAddr_Write);
        i2c_send_nack();
        i2c_write_byte(BME280_RegAddr_Pressure);
        i2c_send_nack();
        i2c_start();                        
        i2c_write_byte(BME280_SlaveAddr_Read); // burst read from 0xF7 to 0xFE
        i2c_send_nack();

        // read pressure
        press_msb  = BME280_Burst_Read_Byte_Ack(); // 0xF7, burst read begin
        press_lsb  = BME280_Burst_Read_Byte_Ack(); // 0xF8
        press_xlsb = BME280_Burst_Read_Byte_Ack(); // 0xF9

        // read temperature
        temp_msb  = BME280_Burst_Read_Byte_Ack(); // 0xFA
        temp_lsb  = BME280_Burst_Read_Byte_Ack(); // 0xFB
        temp_xlsb = BME280_Burst_Read_Byte_Ack(); // 0xFC

        // read humidity
        hum_msb  = BME280_Burst_Read_Byte_Ack(); // 0xFD
        hum_lsb  = BME280_Burst_Read_Byte_NAck(); // 0xFE, burst read end

        *adc_P        = (int32)(((uint32)press_msb << 12)|((uint32)press_lsb << 4)|((uint32)press_xlsb >> 4));
        *adc_T        = (int32)(((uint32)temp_msb << 12)|((uint32)temp_lsb << 4)|((uint32)temp_xlsb >> 4));
        *adc_H        = (int32)(((uint32)hum_msb<<8)|((uint32)hum_lsb));
}


// Returns temperature in DegC, double precision. Output value of "51.23" equals 51.23 DegC.
// t_fine carries fine temperature as global value
double BME280_compensate_T_double(BME280_s32_t adc_T)
{
        double var1, var2, T;
        var1 = (((double)adc_T) / 16384.0 - ((double)dig_T1) / 1024.0) * ((double)dig_T2);
        var2 = ((((double)adc_T) / 131072.0 - ((double)dig_T1) / 8192.0) * (((double)adc_T) / 131072.0 - ((double)dig_T1) / 8192.0)) * ((double)dig_T3);

        t_fine = (BME280_s32_t)(var1 + var2);
        T = (var1 + var2) / 5120.0;

        return T;
}

// Returns pressure in Pa as unsigned 32 bit integer. Output value of "96386.2" equals 96386 Pa = 963.86 hPa
double BME280_compensate_P_double(BME280_s32_t adc_P)
{
        double var1, var2, p;
        var1 = ((double)t_fine / 2.0) - 64000.0;
        var2 = var1 * var1 * ((double)dig_P6) / 32768.0;
        var2 = var2 + var1 * ((double)dig_P5) * 2.0;
        var2 = (var2 / 4.0) + (((double)dig_P4) * 65536.0);
        var1 = (((double)dig_P3) * var1 * var1 / 524288.0 + ((double)dig_P2) * var1) / 524288.0;
        var1 = (1.0 + var1 / 32768.0) * ((double)dig_P1);
        if(0.0 == var1)
        {
                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;
        var2 = p * ((double)dig_P8) / 32768.0;
        p = p + (var1 + var2 + ((double)dig_P7)) / 16.0;
       
        return p;
}

// Returns humidity in %rH as as double. Output value of "46.332" represents 46.332 %rH
double BME280_compensate_H_double(BME280_s32_t adc_H)
{
        double var_H;

        var_H = (((double)t_fine) - 76800.00);
        var_H = (adc_H - (((double)dig_H4) * 64.0 + ((double)dig_H5) / 16384.0 * var_H)) * (((double)dig_H2) / 65536.0 * (1.0 + ((double)dig_H6) / 67108864.0 * var_H * (1.0 + ((double)dig_H3) / 67108864.0 * var_H)));
        var_H = var_H * (1.0 - ((double)dig_H1) * var_H / 524288.0);
       
        if(var_H > 100.0)
        {
                var_H = 100.0;
        }
        else if(var_H < 0.0)
        {
                var_H = 0.0;
        }
       
        return var_H;
}
回復(fù)

使用道具 舉報

5#
ID:810398 發(fā)表于 2021-2-13 18:52 | 只看該作者
謝謝分享!學(xué)習(xí)了,收獲頗多!
回復(fù)

使用道具 舉報

6#
ID:491278 發(fā)表于 2021-4-4 10:30 | 只看該作者
3078 發(fā)表于 2021-1-22 21:09
謝謝分享我再找找為什么獲取溫度壓力都可以但是濕度怎么都是0的原因

你會不會用的是BMP280
回復(fù)

使用道具 舉報

7#
ID:99570 發(fā)表于 2021-7-17 00:24 | 只看該作者
謝謝樓主分享,一句BMP280提醒了我,我說怎么濕度一直是0!
回復(fù)

使用道具 舉報

8#
ID:1005210 發(fā)表于 2022-2-16 12:31 | 只看該作者
老師,config.h里,我的配置是這樣如下,bme280.c里面的Reset()、BME280_Read_Chip_Id()等函數(shù)里面的參數(shù)需要修改嗎?
sbit I2C_SCL = P2^0;  //I2C總線引腳,BME280 clock
sbit I2C_SDA = P2^1;  //I2C總線引腳,BME280 data

#define LCD1602_DB  P0        //1602液晶數(shù)據(jù)端口
sbit LCD1602_RS = P2^6; //1602液晶指令/數(shù)據(jù)選擇引腳 EasyBoard主板
sbit LCD1602_RW = P2^5; //1602液晶讀寫引腳 EasyBoard主板
sbit LCD1602_E  = P2^7; //1602液晶使能引腳 EasyBoard主板
回復(fù)

使用道具 舉報

9#
ID:375045 發(fā)表于 2022-9-3 11:08 | 只看該作者
能讀到ID,但是溫度壓力濕度都讀不到是什么問題?
>ConfigUART done.

>BME280_Init done.

>BME280_Chip_Id = 0x60

>BME280_adc_T = 0x000fffff
>BME280_adc_H = 0x0000ffff
>BME280_adc_P = 0x000fffff

>BME280_Temperature :   0.00 c
>BME280_Humidity :   2.14 %
>BME280_Pressure :    0.02 hPa
--------------------------------
回復(fù)

使用道具 舉報

10#
ID:825397 發(fā)表于 2023-10-19 16:20 | 只看該作者
謝謝樓主分享。網(wǎng)上BMP280驅(qū)動較少,樓主程序可以借鑒!
回復(fù)

使用道具 舉報

11#
ID:468878 發(fā)表于 2025-4-14 18:10 | 只看該作者
試了一下樓主的程序,改用STC8H8K64U,沒用LCD,直接串口輸出,驗證可用,謝謝樓主。
回復(fù)

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機教程網(wǎng)

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 精品欧美一区二区中文字幕视频 | 一级片av| 精品一区二区三区在线视频 | 精品亚洲一区二区三区 | 日本一本在线 | 羞羞视频网站免费看 | 午夜私人影院 | 一区二区三区四区视频 | 国产精品av久久久久久毛片 | 亚洲国产aⅴ成人精品无吗 欧美激情欧美激情在线五月 | 日韩欧美亚洲 | 在线免费观看黄a | 欧美一级小视频 | 91精品国产91久久久久游泳池 | 成人精品久久 | 亚洲综合视频一区 | 中文字幕乱码一区二区三区 | 国产色99精品9i | 在线激情视频 | 日韩av在线中文字幕 | 亚洲精品成人 | 色视频在线播放 | 日本特黄特色aaa大片免费 | 日本精品一区二区三区视频 | av天天干 | 激情三区 | 亚洲一区 中文字幕 | 久久久久久国产一区二区三区 | 欧美视频免费在线 | 久久国产精品99久久久久久丝袜 | 天堂一区二区三区 | 日本免费一区二区三区四区 | 亚洲欧美激情精品一区二区 | 一级片成人 | 91在线看 | 超碰成人免费 | 国产精品海角社区在线观看 | 一区二区三区四区在线免费观看 | 日本高清不卡视频 | 国产成人精品一区二区三区四区 | 亚洲精品视频久久 |