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;
}