BMP280从机地址就是0xec的呀,没错呀
BMP280_Read函数呢?里面有没有应答?每次读取完一个字节的数据之后,都要主机产生一个应答信号的
0xf3的读取呢?是不是先读取这个寄存器之后再读取压力和温度数据的?
给你一个我的代码参考一下,这是我几个月刚刚开始学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运行状态位
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) //读取校正值,所有校正值是用两个地址存放的,所以就读取两个字节
{
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) //读取测量值,所有测量值是用三地址存放的,所以就读取三个字节
{
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状态位
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状态位
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() //读取状态位,检测ADC是否完成
{
unsigned char temp;
IIC_start();
Write_byte(Write_BMP280_slave); //从机地址
Write_byte(Read_BMP280_Status); //读取ADC运行状态位
IIC_start();
Write_byte(Read_BMP280_slave); //从机地址
temp=read_byte();
IIC_Nask();
IIC_stop();
return temp;
}
//=================================================================================================
|