在嵌入式開發板上使用c語言采用IIC獲取ICP10125傳感器的有效值文件內含相關文檔及程序源碼
ICP10125.c
- #include <stdio.h>
- #include <sys/ioctl.h>
- #include <sys/types.h>
- #include <fcntl.h>
- #include <stdlib.h>
- #include <linux/i2c-dev.h>
- #include <i2c/smbus.h>
- #include <unistd.h>
- #define ICP_I2C_ID 0x63
- #define ICP_CMD_READ_ID 0xefc8
- #define ICP_CMD_SET_ADDR 0xc595
- #define ICP_CMD_READ_OTP 0xc7f7
- // Transmit T First
- #define ICP_CMD_MEAS_LP 0x609c
- #define ICP_CMD_MEAS_N 0x6825
- #define ICP_CMD_MEAS_LN 0x70df
- #define ICP_CMD_MEAS_ULN 0x7866
- // 壓力計算常數
- typedef struct inv_invpres
- {
- int file;
- u_int32_t min_delay_us;
- u_int8_t pressure_en;
- u_int8_t temperature_en;
- float sensor_constants[4]; // OTP values
- float p_Pa_calib[3];
- float LUT_lower;
- float LUT_upper;
- float quadr_factor;
- float offst_factor;
- } inv_invpres_t;
- int file_init()
- {
- int file = 0;
- file = open("/dev/i2c-1", O_RDWR);
- if (file < 0)
- {
- printf("open error\n");
- exit(1);
- }
- if (ioctl(file, I2C_SLAVE, ICP_I2C_ID) < 0)
- {
- printf("ioctl error\n");
- exit(1);
- }
- return file;
- }
- void init_base(struct inv_invpres *s, short *otp)
- {
- int i;
- for (i = 0; i < 4; i++)
- {
- s->sensor_constants[i] = (float)otp[i];
- // printf("sensor_constants[%d]:%.2f, ", i, s->sensor_constants[i]);
- }
- s->p_Pa_calib[0] = 45000.0;
- s->p_Pa_calib[1] = 80000.0;
- s->p_Pa_calib[2] = 105000.0;
- s->LUT_lower = 3.5 * (1 << 20);
- s->LUT_upper = 11.5 * (1 << 20);
- s->quadr_factor = 1 / 16777216.0;
- s->offst_factor = 2048.0;
- // printf("\n");
- }
- int read_otp_from_i2c(struct inv_invpres *s, short *out)
- {
- unsigned char data_write[10];
- unsigned char data_read[10] = {0};
- int ret;
- int i;
- // OTP Read mode
- data_write[0] = 0xC5;
- data_write[1] = 0x95;
- data_write[2] = 0x00;
- data_write[3] = 0x66;
- data_write[4] = 0x9C;
- ret = write(s->file, data_write, 5);
- if (ret == 0)
- return 1;
- // Read OTP values
- for (i = 0; i < 4; i++)
- {
- data_write[0] = 0xC7;
- data_write[1] = 0xF7;
- ret = write(s->file, data_write, 2);
- if (ret == 0)
- return 1;
- ret = read(s->file, data_read, 3);
- if (ret == 0)
- return 2;
- out[i] = data_read[0] << 8 | data_read[1];
- // printf("%02x, %02x, %02x\n", data_read[0], data_read[1], data_read[2]);
- }
- return 0;
- }
- int inv_invpres_init(struct inv_invpres *s)
- {
- short otp[4];
- s->file = file_init();
- read_otp_from_i2c(s, otp);
- init_base(s, otp);
- return 0;
- }
- // p_Pa -- List of 3 values corresponding to applied pressure in Pa
- // p_LUT -- List of 3 values corresponding to the measured p_LUT values at the applied pressures.
- void calculate_conversion_constants(struct inv_invpres *s, float *p_Pa,
- float *p_LUT, float *out)
- {
- float A, B, C;
- C = (p_LUT[0] * p_LUT[1] * (p_Pa[0] - p_Pa[1]) +
- p_LUT[1] * p_LUT[2] * (p_Pa[1] - p_Pa[2]) +
- p_LUT[2] * p_LUT[0] * (p_Pa[2] - p_Pa[0])) /
- (p_LUT[2] * (p_Pa[0] - p_Pa[1]) +
- p_LUT[0] * (p_Pa[1] - p_Pa[2]) +
- p_LUT[1] * (p_Pa[2] - p_Pa[0]));
- A = (p_Pa[0] * p_LUT[0] - p_Pa[1] * p_LUT[1] - (p_Pa[1] - p_Pa[0]) * C) / (p_LUT[0] - p_LUT[1]);
- B = (p_Pa[0] - A) * (p_LUT[0] + C);
- out[0] = A;
- out[1] = B;
- out[2] = C;
- }
- // p_LSB -- Raw pressure data from sensor
- // T_LSB -- Raw temperature data from sensor
- int inv_invpres_process_data(struct inv_invpres *s, int p_LSB, int T_LSB,
- float *pressure, float *temperature)
- {
- float t;
- float s1, s2, s3;
- float in[3];
- float out[3];
- float A, B, C;
- t = (float)(T_LSB - 32768);
- s1 = s->LUT_lower + (float)(s->sensor_constants[0] * t * t) * s->quadr_factor;
- s2 = s->offst_factor * s->sensor_constants[3] + (float)(s->sensor_constants[1] * t * t) * s->quadr_factor;
- s3 = s->LUT_upper + (float)(s->sensor_constants[2] * t * t) * s->quadr_factor;
- in[0] = s1;
- in[1] = s2;
- in[2] = s3;
- calculate_conversion_constants(s, s->p_Pa_calib, in, out);
- A = out[0];
- B = out[1];
- C = out[2];
- *pressure = A + B / (C + p_LSB);
- // printf("%.2f, %.2f, %.2f, %d\n", A, B, C, p_LSB);
- *temperature = -45.f + 175.f / 65536.f * T_LSB;
- return 0;
- }
- void measure(struct inv_invpres *s, int32_t *raw_t, int32_t *raw_p)
- {
- u_int8_t buf[2];
- u_int8_t res_buf[12];
- buf[0] = 0x68;
- buf[1] = 0x25;
- int ret = write(s->file, buf, 2);
- if (ret != 2) {
- printf("i2c transaction failed %d\n", ret);
- }
- while(read(s->file, res_buf, 9) !=9 ) usleep(10*1000);
- {
- // printf("contains the read byte \n");
- // for(int i=0;i<9;i++)
- // {
- // printf("%02x ",res_buf[i]);
- // }
- // printf("\n");
- }
- *raw_t = (res_buf[0]<<8)|res_buf[1];
- *raw_p = (res_buf[3]<<16)|(res_buf[4]<<8)|res_buf[6];
- }
- int main()
- {
- int32_t raw_t;
- int32_t raw_p;
- float temperature;
- float pressure;
- inv_invpres_t obj;
- inv_invpres_init(&obj);
- measure(&obj, &raw_t, &raw_p);
- // printf("raw_t: %02x, raw_p: %02x \n", raw_t, raw_p);
- inv_invpres_process_data(&obj, raw_p, raw_t,
- &pressure, &temperature);
- printf("%.3f,%.3f", temperature, pressure);
- return 0;
- }
復制代碼
51hei.png (4.61 KB, 下載次數: 78)
下載附件
2021-12-9 17:32 上傳
pdf下載:
ICP-101251.2.zip
(1.28 MB, 下載次數: 8)
2021-12-9 15:20 上傳
點擊文件名下載附件
|