LPS331使用 高精度大気圧モジュールのI2CでのONE_SHOT測定テスト

I2C通信chkに引き続き、大気圧ONE_SHOT測定のテストをしました。装置をactiveにして、one_shotの命令をし、測定が終わったかをSTATUS_REGで確認し、終わっていたらば大気圧を読みに行く、という流れです。
こちらも無事読み取りができました。

= 0x3f32b6 / 4096 とグーグル先生に聞いたら、1011.17 mbarだそうです。

コードはこちら。エラー処理はしてません。


#include <avr/io.h>
#include <util/delay.h>
#include <util/twi.h>


#define SLA_R  0b10111001
#define SLA_W  0b10111000

#define SCL PORTC5
#define SDA PORTC4

#define WHO_AM_I 0x0f
#define CTRL_REG1 0x20
#define PD 7 // power down when 0
#define BDU 2 // block data update

#define CTRL_REG2 0x21
#define ONE_SHOT 0

#define CTRL_REG3 0x22
#define STATUS_REG 0x27
#define P_DA 1
#define T_DA 0

#define PRESS_OUT 0x28
#define TEMP_OUT 0x2b


int32_t read(uint8_t reg_add, uint8_t bits);
int8_t write_one(uint8_t reg_add, uint8_t dat);


int main(void){
  uint32_t p;
  PORTC = (1 << SCL) | (1 << SDA);//pull up

  // 1e6/(16+2*TWBR*TWPS) < 100 kHz = 1e5
  //TWSR |= (0 << TWPS1) | (0 << TWPS0); //prescaler 1
  //TWBR = 0x00;// TWBR = 0
  //TWAR = //address & general call

  while(1){
    write_one(CTRL_REG1, ((1 << PD) | (1 << BDU))); // wake up
    //read_one(0x0f);
    write_one(CTRL_REG2, (1 << ONE_SHOT)); //set one shot meas
    while(!(read(STATUS_REG, 1) & (1 << P_DA))); //wait meas
    p = read(PRESS_OUT, 3); //read pout
    _delay_ms(5000);
  }
}

int32_t read(uint8_t reg_add, uint8_t bits){
  int32_t res = 0;
  if(bits > 3){ return -1;}

  // ST send start bit
  TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN); // | (1 << TWIE);
  while (!(TWCR & (1 << TWINT))); // wait
  if((TWSR & 0xf8) != TW_START){ // chk status
    return -1; //error
  }

  // SLA+W
  TWDR = SLA_W;
  TWCR = (1 << TWINT) | (1 << TWEN);//return
  while (!(TWCR & (1 << TWINT)));//wait
  if((TWSR & 0xf8) != TW_MT_SLA_ACK){ //chk
    return -1;//error
  }

  // SUB: multiread? + register add
  TWDR = reg_add + (((bits > 1)?1:0) << 7); //single read MSB = 0;
  TWCR = (1 << TWINT) | (1 << TWEN);
  while (!(TWCR & (1 << TWINT)));//wait
  if((TWSR & 0xf8) != TW_MT_DATA_ACK){ //chk
    return -1;//error
  }

  // SR: restart
  TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN);
  while (!(TWCR & (1 << TWINT))); // wait
  if((TWSR & 0xf8) != TW_REP_START){ // chk status
    return -1; //error
  }

  // SLA + R
  TWDR = SLA_R;
  TWCR = (1 << TWINT) | (1 << TWEN);//return
  while (!(TWCR & (1 << TWINT)));//wait
  if((TWSR & 0xf8) != TW_MR_SLA_ACK){ //chk
    return -1;//error
  }

  // DATA read
  for(uint8_t i = 0; i < bits; i++){
    if(i == (bits-1)){ //is next data last?
      TWCR = (1 << TWINT) | (1 << TWEN) | (0 << TWEA); //NACK
      while (!(TWCR & (1 << TWINT)));//wait
      if((TWSR & 0xf8) != TW_MR_DATA_NACK){ //chk
        return -1;//error
      }
    }else{
      TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWEA); //ACK
      while (!(TWCR & (1 << TWINT)));//wait
      if((TWSR & 0xf8) != TW_MR_DATA_ACK){ //chk
        return -1;//error
      }
    }
    res += (TWDR << 8*i);
  }


  // SP
  TWCR = (1 << TWINT) | (1 << TWSTO)| (1 << TWEN);

  return res;
}


//
// write
//
int8_t write_one(uint8_t reg_add, uint8_t dat){

  // ST send start bit
  TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN); // | (1 << TWIE);
  while (!(TWCR & (1 << TWINT))); // wait
  if((TWSR & 0xf8) != TW_START){ // chk status
    return -1; //error
  }

  // SLA+W
  TWDR = SLA_W;
  TWCR = (1 << TWINT) | (1 << TWEN);//return
  while (!(TWCR & (1 << TWINT)));//wait
  if((TWSR & 0xf8) != TW_MT_SLA_ACK){ //chk
    return -1;//error
  }

  // SUB: multiread? + register add
  TWDR = reg_add + (0 << 7); //single read MSB = 0;
  TWCR = (1 << TWINT) | (1 << TWEN);
  while (!(TWCR & (1 << TWINT)));//wait
  if((TWSR & 0xf8) != TW_MT_DATA_ACK){ //chk
    return -1;//error
  }

  // DATA write
  TWDR = dat;
  TWCR = (1 << TWINT) | (1 << TWEN);
  while (!(TWCR & (1 << TWINT)));//wait
  if((TWSR & 0xf8) != TW_MT_DATA_ACK){ //chk
    return -1;//error
  }

  // SP
  TWCR = (1 << TWINT) | (1 << TWSTO)| (1 << TWEN);

  return 0;
}