Embedded 从BMP085读回的I2C温度0xffff
我正在通过I2C将Rabbit 5760 CPU连接到一个接口。一切正常,除了读取温度寄存器正在回读Embedded 从BMP085读回的I2C温度0xffff,embedded,microcontroller,sensors,i2c,Embedded,Microcontroller,Sensors,I2c,我正在通过I2C将Rabbit 5760 CPU连接到一个接口。一切正常,除了读取温度寄存器正在回读0xffff(请参阅开关中的BP\u FINISHTEMP案例)。我不明白为什么它不起作用。代码如下。有人知道怎么了吗?压力和校准值可以很好地读回。如果有人能帮忙,谢谢 // baro.lib, Barometer related functions /*** BeginHeader InitBarometer, ReadBarometer */ int InitBarometer(vo
0xffff
(请参阅开关中的BP\u FINISHTEMP
案例)。我不明白为什么它不起作用。代码如下。有人知道怎么了吗?压力和校准值可以很好地读回。如果有人能帮忙,谢谢
// baro.lib, Barometer related functions
/*** BeginHeader InitBarometer, ReadBarometer */
int InitBarometer(void);
int ReadBarometer(void); // has 4 phases
/*** EndHeader */
// this all comes from the barometer data sheet
struct s_baroparams {
short ac1;
short ac2;
short ac3;
unsigned short ac4;
unsigned short ac5;
unsigned short ac6;
short b1;
short b2;
short mb;
short mc;
short md;
} baroparams;
enum {BP_FAIL,BP_STARTTEMP,BP_FINISHTEMP,BP_STARTPRESSURE,BP_FINISHPRESSURE} BarometerPhase;
unsigned long LastBarometerStartTime;
long baro_ut;
long baro_up;
// Returns TRUE if successful, else FALSE
int InitBarometer(void) {
char *ptmp;
char hi,lo;
int i;
assert(Stack_Low());
BarometerPhase = BP_FAIL;
// OLD CODE THAT USED TO USE PORT B FOR I2C
// cannot use i2c_init because it assumes port D
// so these lines sorta replace it
// PB1,PB3,PB5 are SCL, SDA, and XCLR on the barometer
// we want pb1 and pb3 to be low inputs to let the pullups work, and pb5 to be low, output, then high output
// These pins assigned to portD for the HS4, used to be port B
/*
WrPortI(PDDR,&PDDRShadow,0); // all low to start
WrPortI(PDDDR,&PDDDRShadow,(1<<5)); // all inputs except pd5
WrPortI(PDDR,&PDDRShadow,PDDRShadow|(1<<5)); // now pd5 is high
*/
// pull baro. sensor out of reset by setting XLR high (XLR is port D bit 1).
// This assumes we'll want it out of reset before initting the I2C interface,
// VERIFY THIS
BitWrPortI(PDDDR,&PDDDRShadow,1,1);
BitWrPortI(PDDR,&PDDRShadow,1,1);
i2c_init();
// i2c_clocks_per_us = (int)(19200L*32*freq_divider/1000000L);
// evil evil hack here
ptmp = (char *)&baroparams.ac1;
for (i=0;i<11;i++) { // 11 is number of 2-byte values in baroparams above
// start condition
if (i2c_start_tx()) {
return FALSE;
}
// send ef
if (i2c_write_char(0xee))
return FALSE;
if (i2c_write_char(0xaa+i*2))
return FALSE;
if (i2c_start_tx()) {
return FALSE;
}
if (i2c_write_char(0xef))
return FALSE;
if (i2c_read_char(&hi))
return FALSE;
i2c_send_ack();
if (i2c_read_char(&lo))
return FALSE;
i2c_send_nak();
// stop condition
i2c_stop_tx();
*ptmp++ = lo;
*ptmp++ = hi;
}
BarometerPhase = BP_STARTTEMP;
LastBarometerStartTime = 0;
return TRUE;
}
// Return -1 if failed, 0 if success
int ReadBarometer() {
unsigned long dt;
// unsigned char hi,lo,xlo;
union { long l; unsigned char uc[4]; } u;
long x1,x2,x3,b3,b5,b6,b7,t,p;
unsigned long b4;
long b6x;
assert(Stack_Low());
switch (BarometerPhase) {
case BP_FAIL:
return -1;
case BP_STARTTEMP:
if (i2c_start_tx()) {
return -1;
}
if (i2c_write_char(0xee))
return -1;
if (i2c_write_char(0xf4))
return -1;
if (i2c_write_char(0x2e))
return -1;
i2c_stop_tx();
BarometerPhase = BP_FINISHTEMP;
LastBarometerStartTime = MS_TIMER;
break;
case BP_FINISHTEMP:
u.l = 0;
dt = MS_TIMER - LastBarometerStartTime;
if (dt < 6) break;
if (i2c_start_tx()) {
return -1;
}
if (i2c_write_char(0xee))
return -1;
if (i2c_write_char(0xf6))
return -1;
if (i2c_start_tx()) {
return -1;
}
if (i2c_write_char(0xef))
return -1;
if (i2c_read_char(&u.uc[1]))
return -1;
i2c_send_ack();
if (i2c_read_char(&u.uc[0]))
return -1;
i2c_send_nak();
i2c_stop_tx();
baro_ut = u.l; // THIS IS THE PROBLEM U.L IS 0XFFFF HERE ******************************
BarometerPhase = BP_STARTPRESSURE;
break;
case BP_STARTPRESSURE:
if (i2c_start_tx()) {
return -1;
}
if (i2c_write_char(0xee))
return -1;
if (i2c_write_char(0xf4))
return -1;
if (i2c_write_char(0x34+(BARO_OSS<<6)))
return -1;
i2c_stop_tx();
BarometerPhase = BP_FINISHPRESSURE;
LastBarometerStartTime = MS_TIMER;
break;
case BP_FINISHPRESSURE:
u.l = 0;
dt = MS_TIMER - LastBarometerStartTime;
if (dt < BARO_TIME) break;
if (i2c_start_tx()) {
return -1;
}
if (i2c_write_char(0xee))
return -1;
if (i2c_write_char(0xf6))
return -1;
if (i2c_start_tx()) {
return -1;
}
if (i2c_write_char(0xef))
return -1;
if (i2c_read_char(&u.uc[2]))
return -1;
i2c_send_ack();
if (i2c_read_char(&u.uc[1]))
return -1;
i2c_send_ack();
if (i2c_read_char(&u.uc[0]))
return -1;
i2c_send_nak();
i2c_stop_tx();
baro_up = u.l >> (8-BARO_OSS);
// need lots of work here
x1 = ((baro_ut-baroparams.ac6)*baroparams.ac5) >> 15;
x2 = (((long)baroparams.mc)<<11)/(x1+baroparams.md);
b5 = x1+x2;
t = (b5+8)>>4;
// sprintf(g_Temperature,"%ld",t);
// append units
gf_Temperature = t / 10.0;
if (gConfiguration.tempUnits == Celcius) {
sprint_fixedpoint(g_Temperature,t,1);
strlcat(g_Temperature, "°C", sizeof g_Temperature);
}
else {
sprint_fixedpoint(g_Temperature, CelciusToF(t), 1);
strlcat(g_Temperature, "°F", sizeof g_Temperature);
}
b6 = b5 - 4000;
b6x = (b6*b6)>>12;
x1 = (baroparams.b2*b6x)>>11;
x2 = (baroparams.ac2*b6)>>11;
x3 = x1 + x2;
b3 = ((((long)baroparams.ac1*4+x3)<<BARO_OSS)+2)/4;
x1 = (baroparams.ac3*b6)>>13;
x2 = (baroparams.b1*b6x)>>16;
x3 = ((x1+x2)+2)>>2;
b4 = baroparams.ac4*(unsigned long)(x3+32768)>>15;
b7 = ((unsigned long)baro_up-b3)*(50000>>BARO_OSS);
if (b7 < 0x80000000)
p = (b7*2)/b4;
else
p = (b7/b4)*2;
x1 = (p>>8)*(p>>8);
x1 = (x1*3038)>>16;
x2 = (-7357*p)>>16;
p = p + ((x1+x2+3791)>>4);
gf_Pressure = p / 100.0;
// append units
if (gConfiguration.baroUnits == Millibars) {
sprint_fixedpoint(g_Pressure,p,2);
strlcat(g_Pressure, " millibars", sizeof g_Pressure);
}
else {
sprint_fixedpoint(g_Pressure, millibarsToInHg(p), 2);
strlcat(g_Pressure, " inHg", sizeof g_Pressure);
}
BarometerPhase = BP_STARTTEMP;
break;
}
return 0;
}
//baro.lib,气压计相关函数
/***起始气压计,读数气压计*/
内部气压计(无效);
内部读数气压计(无效);//有4个阶段
/***端头*/
//这些都来自气压表数据表
结构s_baroparams{
短ac1;
短ac2;
短ac3;
无符号短ac4;
无符号短ac5;
无符号短ac6;
短b1;
短b2;
短mb;
短mc;
短md;
}巴罗帕拉斯;
枚举{BP_FAIL,BP_STARTTEMP,BP_FINISHTEMP,BP_STARTPRESSURE,BP_FINISHPRESSURE}气压相位;
未签名的长LastBaromerStartTime;
长巴罗乌特;
长巴罗;
//如果成功,则返回TRUE,否则返回FALSE
内部气压计(无效){
char*ptmp;
查尔你好,你好;
int i;
断言(Stack_Low());
气压相位=BP_故障;
//用于将端口B用于I2C的旧代码
//无法使用i2c_init,因为它假定为端口D
//所以这些线可以代替它
//PB1、PB3、PB5是气压计上的SCL、SDA和XCLR
//我们希望pb1和pb3是低输入,让上拉工作,pb5是低输出,然后是高输出
//这些分配给HS4端口D的引脚过去是端口B
/*
WrPortI(PDDR,&PDDRShadow,0);//开始时都处于低位
WrPortI(PDDDR,&PDDDRShadow,&PDDDRShadow,(1可能您没有从芯片读取数据,您会得到一个错误,导致返回-1
您应该调试此部分,或者您可以将(错误)结果值更改为
return 1
,return 2
…return 7
,以获得有问题的行
也许这也可能是uc[4]和long联合体的问题。这是可行的,但这取决于您使用的编译器/平台,它不是一个好的、安全的解决方案。
你最好用像这样的东西
i2c_read_char(byteVal);
value=((uint16_t)byteVal) << 8;
i2c_read_char(byteVal);
value|=byteVal;
i2c_read_char(字节值);
value=((uint16_t)byteVal)可能您没有从芯片读取数据,您会得到一个错误,导致返回-1
您应该调试此部分,或者您可以将(错误)结果值更改为
return 1
,return 2
…return 7
,以获得有问题的行
也许这也可能是uc[4]和long联合体的问题。这是可行的,但这取决于您使用的编译器/平台,它不是一个好的、安全的解决方案。
你最好用像这样的东西
i2c_read_char(byteVal);
value=((uint16_t)byteVal) << 8;
i2c_read_char(byteVal);
value|=byteVal;
i2c_read_char(字节值);
值=((uint16_t)字节)结果是硬件不好。一批新的芯片工作正常。结果是硬件不好。一批新的芯片工作正常。如果您有一个寄存器可以读取,而另一个寄存器不能真正集中精力处理这两个寄存器之间的差异,请修复代码格式。另外,重新阅读数据表,您可能会e计算了一个错误的地址,或者可能是您必须先做的事情,或者其他一些可以忽略的问题。如果您有一个寄存器可以读取,而另一个寄存器不能真正集中精力处理这两个寄存器之间的差异,请修复您的代码格式。另外,重新阅读数据表,您可能计算了错误的a地址,或者可能有一些事情你必须先做,或者其他一些可以忽略的问题。