2011-08-06 64 views
2

我通過I2C將Rabbit 5760 CPU連接到Bosch BMP085 sensor。除了讀取溫度寄存器正在讀回0xffff(參見BP_FINISHTEMP開關盒),一切都很好。我看不出爲什麼它不起作用。代碼如下。任何人都可以看到有什麼不對?壓力和校準值讀回正常。謝謝如果有人可以幫忙。從BMP085讀取I2C溫度讀回0xffff

// 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, "&deg;C", sizeof g_Temperature); 
      } 
      else { 
       sprint_fixedpoint(g_Temperature, CelciusToF(t), 1); 
       strlcat(g_Temperature, "&deg;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; 
} 
+0

請修復您的代碼格式 –

+0

如果您有一個寄存器可以讀取,而另一個寄存器不能真正專注於兩者之間的區別。也重新閱讀數據表,您可能計算了錯誤的地址,或者可能有些事情需要先做,或者其他可忽略的問題。 –

回答

0

原來這是壞的硬件。一批新的芯片工作正常。

0

也許你不從芯片中讀取,你導致的return -1
一個錯誤你應該調試這一部分,或者你可以改變的(錯誤)結果值return 1return 2 ... return 7得到有問題的線。

也許這也可能是你的uc [4]和長聯合的問題。
這可以工作,但它取決於您使用的編譯器/平臺,它不是一個好的,安全的解決方案。
更好地使用像

i2c_read_char(byteVal); 
value=((uint16_t)byteVal) << 8; 
i2c_read_char(byteVal); 
value|=byteVal;