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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索

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

查看數(shù): 7459 | 評論數(shù): 10 | 收藏 6
關(guān)燈 | 提示:支持鍵盤翻頁<-左 右->
    組圖打開中,請稍候......
發(fā)布時間: 2020-7-18 23:54

正文摘要:

我想為電子鐘增加環(huán)境數(shù)據(jù)監(jiān)測功能,主要是氣溫,濕度和氣壓這三項,BME280模塊可以測量這三項數(shù)據(jù),是一個不錯的選擇。

回復(fù)

ID:468878 發(fā)表于 2025-4-14 18:10
試了一下樓主的程序,改用STC8H8K64U,沒用LCD,直接串口輸出,驗證可用,謝謝樓主。
ID:825397 發(fā)表于 2023-10-19 16:20
謝謝樓主分享。網(wǎng)上BMP280驅(qū)動較少,樓主程序可以借鑒!
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
--------------------------------
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主板
ID:99570 發(fā)表于 2021-7-17 00:24
謝謝樓主分享,一句BMP280提醒了我,我說怎么濕度一直是0!
ID:491278 發(fā)表于 2021-4-4 10:30
3078 發(fā)表于 2021-1-22 21:09
謝謝分享我再找找為什么獲取溫度壓力都可以但是濕度怎么都是0的原因

你會不會用的是BMP280
ID:810398 發(fā)表于 2021-2-13 18:52
謝謝分享!學(xué)習(xí)了,收獲頗多!
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;
}
ID:601357 發(fā)表于 2021-1-22 21:09
謝謝分享我再找找為什么獲取溫度壓力都可以但是濕度怎么都是0的原因
ID:810398 發(fā)表于 2020-8-1 20:14
學(xué)習(xí)一下,有AVR單片機驅(qū)動BME280的程序嗎?

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

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

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 亚洲国产一 | 看特级黄色片 | 免费成人在线网站 | 欧美精品一区二区三区在线四季 | 国产伦精品一区二区三区视频金莲 | 成人午夜 | 国产一区二区中文字幕 | 国产综合网站 | 视频在线一区二区 | 欧美日韩国产三级 | 国产一区二区免费 | 亚洲精品 在线播放 | 精品久久中文字幕 | 国产精品日韩欧美一区二区 | 欧美精品久久久久 | 亚洲精品中文字幕在线 | 在线观看视频中文字幕 | 少妇一级淫片aaaaaaaaa | 久久成人精品视频 | 日韩视频免费看 | 亚洲欧美一区二区在线观看 | 在线视频一区二区三区 | 免费超碰 | 免费看a | 怡红院免费的全部视频 | 欧美三区在线观看 | 久久成人精品视频 | 日韩免费一区 | 亚洲欧美中文日韩在线v日本 | 成人久久久久 | 亚洲成人网在线播放 | 欧美成人精品激情在线观看 | 国产偷久久一级精品60部 | 日韩国产在线 | 精品一区二区三区入口 | 久久综合影院 | 国产成人福利视频在线观看 | 欧美一区二区三区四区视频 | 在线欧美 | 国产午夜精品久久久久免费视高清 | 国产激情视频网站 |