2011-08-06 4 views
2

I2C를 통해 토끼 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;