![]() |
發(fā)布時間: 2020-7-18 23:54
正文摘要:我想為電子鐘增加環(huán)境數(shù)據(jù)監(jiān)測功能,主要是氣溫,濕度和氣壓這三項,BME280模塊可以測量這三項數(shù)據(jù),是一個不錯的選擇。 |
試了一下樓主的程序,改用STC8H8K64U,沒用LCD,直接串口輸出,驗證可用,謝謝樓主。![]() ![]() ![]() |
謝謝樓主分享。網(wǎng)上BMP280驅(qū)動較少,樓主程序可以借鑒! |
能讀到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 -------------------------------- |
老師,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主板 |
謝謝樓主分享,一句BMP280提醒了我,我說怎么濕度一直是0! |
3078 發(fā)表于 2021-1-22 21:09 你會不會用的是BMP280 |
謝謝分享!學(xué)習(xí)了,收獲頗多! |
以上代碼轉(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; } |
謝謝分享我再找找為什么獲取溫度壓力都可以但是濕度怎么都是0的原因 |
學(xué)習(xí)一下,有AVR單片機驅(qū)動BME280的程序嗎? |
Powered by 單片機教程網(wǎng)