|
我想為電子鐘增加環(huán)境數(shù)據(jù)監(jiān)測功能,主要是氣溫,濕度和氣壓這三項,BME280模塊可以測量這三項數(shù)據(jù),是一個不錯的選擇。
Annotation 2020-07-18 231237.png (195.26 KB, 下載次數(shù): 96)
下載附件
2020-7-18 23:39 上傳
Annotation 2020-07-18 232239.png (58.74 KB, 下載次數(shù): 91)
下載附件
2020-7-18 23:43 上傳
今天對照datasheet和之前壇友分享的資料,編寫代碼實現(xiàn)了氣溫,濕度和氣壓這三項數(shù)據(jù)的讀取,并在LCD1602屏幕和UART打印顯示,
效果如圖所示:
51hei圖片_20200718233539.jpg (49.4 KB, 下載次數(shù): 85)
下載附件
2020-7-18 23:35 上傳
Annotation 2020-07-18 225015.png (21.24 KB, 下載次數(shù): 94)
下載附件
2020-7-18 23:36 上傳
在實踐過程中,有以下心得:
1、BME280模塊有三種工作模式,其中forced mode適合我的需要
Annotation 2020-07-18 231315.png (29.02 KB, 下載次數(shù): 84)
下載附件
2020-7-18 23:39 上傳
Annotation 2020-07-18 231523.png (182.63 KB, 下載次數(shù): 97)
下載附件
2020-7-18 23:39 上傳
2、我的需求,可以對照Weather Monitoring方式,文檔上有詳細說明
我對精度要求并不高,oversampleing選擇x1即可,如此設(shè)置,功耗也最小。
Annotation 2020-07-18 231716.png (160.63 KB, 下載次數(shù): 105)
下載附件
2020-7-18 23:41 上傳
Annotation 2020-07-18 231911.png (135.87 KB, 下載次數(shù): 87)
下載附件
2020-7-18 23:42 上傳
Annotation 2020-07-18 232113.png (65.05 KB, 下載次數(shù): 93)
下載附件
2020-7-18 23:42 上傳
3、讀取的ADC數(shù)據(jù),不能直接使用,必須進行補償計算,64位整數(shù)運算精度最高,但對于單片機不太合適,可以使用double類型
計算過程,詳見datasheet中的附件代碼
Annotation 2020-07-18 232716.png (163.19 KB, 下載次數(shù): 82)
下載附件
2020-7-18 23:45 上傳
Annotation 2020-07-18 232401.png (146.6 KB, 下載次數(shù): 94)
下載附件
2020-7-18 23:45 上傳
main函數(shù)代碼:
- void main()
- {
- uint8 chip_id = 0;
- uint8 pdata pbuf[31] = {0};
- ConfigUART(9600);
- printf(">ConfigUART done.\r\n\r\n");
- Delay500ms();
- BME280_Init();
- printf(">BME280_Init done.\r\n\r\n");
- Delay500ms();
- chip_id = BME280_Read_Chip_Id();
- printf(">BME280_Chip_Id = 0x%bx\r\n\r\n", (uint8)chip_id);
- LCD1602_Init(); //初始化液晶
- LCD1602_Show_Char(6, 0, 0); //5x7字符 ℃
- LCD1602_Show_Char(14, 0, '%');//5x7字符 %
- LCD1602_Show_Str(8, 1, "hPa"); // 液晶顯示屏更新顯示
-
- while(1)
- {
- Delay500ms();Delay500ms();
- BME280_Read_ADC(&BME280_adc_P, &BME280_adc_T, &BME280_adc_H);
- printf(">BME280_adc_T = 0x%08lx \r\n", BME280_adc_T);
- printf(">BME280_adc_H = 0x%08lx \r\n", BME280_adc_H);
- printf(">BME280_adc_P = 0x%08lx \r\n", BME280_adc_P);
- printf("\r\n");
- BME280_Temperature = BME280_compensate_T_double(BME280_adc_T);
- BME280_Humidity = BME280_compensate_H_double(BME280_adc_H);
- BME280_Pressure = BME280_compensate_P_double(BME280_adc_P);
-
- sprintf(pbuf, "%6.2f", BME280_Temperature);
- printf(">BME280_Temperature : %s c\r\n", pbuf);
- LCD1602_Show_Str(0, 0, pbuf); // 液晶顯示屏更新顯示
- sprintf(pbuf, "%6.2f", BME280_Humidity);
- printf(">BME280_Humidity : %s %%\r\n", pbuf);
- LCD1602_Show_Str(8, 0, pbuf); // 液晶顯示屏更新顯示
-
- sprintf(pbuf, "%7.2f", BME280_Pressure/100);
- printf(">BME280_Pressure : %s hPa\r\n", pbuf);
- LCD1602_Show_Str(0, 1, pbuf); // 液晶顯示屏更新顯示
- printf("--------------------------------\r\n\r\n");
- }
- }
復(fù)制代碼
讀取ADC數(shù)據(jù)代碼:
- 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));
- }
復(fù)制代碼
ADC數(shù)據(jù)的補償計算代碼(double類型):
- // 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ù)制代碼
詳細代碼請參見附件
Annotation 2020-07-18 230907.png (13.71 KB, 下載次數(shù): 108)
下載附件
2020-7-18 23:51 上傳
以上代碼使用C51開發(fā)板調(diào)試,接線簡單,具體端口可參看config.h
初學(xué)單片機,難免有錯漏之處,還請各位壇友不吝賜教。
BME280_UART_LCD1602_STC89C52RC.7z
(1.33 MB, 下載次數(shù): 162)
2020-7-18 23:51 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|
評分
-
查看全部評分
|