BMP280從機地址就是0xec的呀,沒錯呀
BMP280_Read函數呢?里面有沒有應答?每次讀取完一個字節(jié)的數據之后,都要主機產生一個應答信號的
0xf3的讀取呢?是不是先讀取這個寄存器之后再讀取壓力和溫度數據的?
給你一個我的代碼參考一下,這是我?guī)讉€月剛剛開始學C語言的時候寫的,已經驗證通過的了
/*BMP280.c BMP280相關操作函數
選擇IIC操作方式,相關的選擇端口要硬件先選擇好
SDO=0,IIC從機地址為:0xec(寫),0xed(讀)
*/
#include "BMP280.h"
#include "IIC.h"
#define BMP280_S32_t long
#define Write_BMP280_slave 0xec
#define Read_BMP280_slave 0xed
#define Read_BMP280_temp_msb 0xfa //讀取溫度最高位地址,讀取是從最高位讀到最低位的
#define Read_BMP280_press_msb 0xf7 //讀取氣壓最高位地址,讀取是從最高位讀到最低位的
#define Read_BMP280_Status 0xf3 //讀取ADC運行狀態(tài)位
unsigned short dig_T1; //BMP280校正值保存的相關地址
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 BMP280_init() //BMP280初始化函數
{
Delay_ms(100);
IIC_start();
Write_byte(Write_BMP280_slave); //從機地址
Write_byte(0xf4); //寄存器設置設備的數據采集選項(0xf4)
Write_byte(0xf0); //先進入休眠模式,完成0xf5的設置之后再進入正常模式
Write_byte(0xf5); //存器設置設備的速率、過濾器和接口選項
Write_byte(0x00); // IIR濾波關閉,0.5mS測量一次
Write_byte(0xf4); //寄存器設置設備的數據采集選項(0xf4)
Write_byte(0xff); //溫度和壓力都是20位模式,采樣模式為正常模式
IIC_stop();
dig_T1=Read_BMP280_2Byte(0x88); //讀取幾個校驗值
dig_T2=Read_BMP280_2Byte(0x8a);
dig_T3=Read_BMP280_2Byte(0x8c);
dig_P1=Read_BMP280_2Byte(0x8e);
dig_P2=Read_BMP280_2Byte(0x90);
dig_P3=Read_BMP280_2Byte(0x92);
dig_P4=Read_BMP280_2Byte(0x94);
dig_P5=Read_BMP280_2Byte(0x96);
dig_P6=Read_BMP280_2Byte(0x98);
dig_P7=Read_BMP280_2Byte(0x9a);
dig_P8=Read_BMP280_2Byte(0x9c);
dig_P9=Read_BMP280_2Byte(0x9e);
}
//=================================================================================================
short Read_BMP280_2Byte(unsigned char BMP280_addr) //讀取校正值,所有校正值是用兩個地址存放的,所以就讀取兩個字節(jié)
{
short temp;
unsigned char Data_LSB,Data_MSB;
IIC_start();
Write_byte(Write_BMP280_slave); //從機地址
Write_byte(BMP280_addr);
IIC_start();
Write_byte(Read_BMP280_slave); //從機地址
Data_LSB=read_byte();
IIC_Ask();
Data_MSB=read_byte();
IIC_Nask();
IIC_stop();
temp=(Data_MSB<<8)|Data_LSB;
return temp;
}
//=================================================================================================
long Read_BMP280_3Byte(unsigned char BMP280_addr) //讀取測量值,所有測量值是用三地址存放的,所以就讀取三個字節(jié)
{
long temp;
unsigned char Data_XLSB,Data_LSB,Data_MSB;
IIC_start();
Write_byte(Write_BMP280_slave); //從機地址
Write_byte(BMP280_addr);
IIC_start();
Write_byte(Read_BMP280_slave); //從機地址
Data_MSB=read_byte();
IIC_Ask();
Data_LSB=read_byte();
IIC_Ask();
Data_XLSB=read_byte();
IIC_Nask();
IIC_stop();
temp=(long)(((unsigned long)Data_MSB<<12)|((unsigned long)Data_LSB<<4)|((unsigned long)Data_XLSB>>4));
return temp;
}
//=================================================================================================
double Read_BMP280_adc(unsigned char Reg_addr) //讀取傳感器adc數據
{ //
double Data; //返回值就是加入校正計算好的溫度或者壓力值
long adc_data,adc_data_add; //轉換結果保存
unsigned char f,measuring; //
//
if(Reg_addr==Read_BMP280_temp_msb) //根據輸入選擇溫度或者氣壓ADC
{ //
for(f=0;f<32;f++) //
{ //
do{measuring=Read_status();} //讀取ADC狀態(tài)位
while(measuring==0x08); //
adc_data=Read_BMP280_3Byte(Read_BMP280_temp_msb); //讀取溫度ADC結果
adc_data_add=adc_data_add+adc_data; //adc結果相加
} //
adc_data_add=adc_data_add/32; //進行多次ADC,然后取平均值
Data=bmp280_compensate_T_double(adc_data); //進行校正處理
} //
else //
{ //
for(f=0;f<128;f++) //
{ //
do{measuring=Read_status();} //讀取ADC狀態(tài)位
while(measuring==0x08); //
adc_data=Read_BMP280_3Byte(Read_BMP280_press_msb); //讀取氣壓ADC結果
adc_data_add=adc_data_add+adc_data; //adc結果相加
} //
adc_data_add=adc_data_add/128; //進行多次ADC,然后取平均值
Data=bmp280_compensate_P_double(adc_data); //進行校正處理
}
return Data;
}
//=================================================================================================
double bmp280_compensate_T_double(long adc_T) //數據手冊復制過來的,溫度和校正值的計算
{
double var1, var2, T,t_fine;
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 = (long)(var1 + var2);
T = (var1 + var2) / 5120.0;
return T;
}
//=================================================================================================
double bmp280_compensate_P_double(long adc_P) //數據手冊復制過來的氣壓和校正值的計算
{
double var1, var2, p,t_fine;
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 (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;
var2 = p * ((double)dig_P8) / 32768.0;
p = p + (var1 + var2 + ((double)dig_P7)) / 16.0;
return p;
}
//=================================================================================================
unsigned char Read_status() //讀取狀態(tài)位,檢測ADC是否完成
{
unsigned char temp;
IIC_start();
Write_byte(Write_BMP280_slave); //從機地址
Write_byte(Read_BMP280_Status); //讀取ADC運行狀態(tài)位
IIC_start();
Write_byte(Read_BMP280_slave); //從機地址
temp=read_byte();
IIC_Nask();
IIC_stop();
return temp;
}
//=================================================================================================
|