From ea7d68e35eb319b89a07bf9240fba1b52e39ed22 Mon Sep 17 00:00:00 2001 From: yelvlab Date: Thu, 10 Oct 2024 11:36:08 +0800 Subject: [PATCH] =?UTF-8?q?mlx90614=E4=BC=A0=E6=84=9F=E5=99=A8=E8=AF=BB?= =?UTF-8?q?=E5=8F=96=E7=9B=AE=E6=A0=87=E6=B8=A9=E5=BA=A6=E5=80=BC=E5=AE=8C?= =?UTF-8?q?=E6=88=90=EF=BC=8C=E4=B8=BA=E9=81=BF=E5=85=8D=E6=B5=AE=E7=82=B9?= =?UTF-8?q?=E6=95=B0=E8=BF=90=E7=AE=97=EF=BC=8C=E6=B8=A9=E5=BA=A6=E7=BB=93?= =?UTF-8?q?=E6=9E=9C=E6=95=B4=E4=BD=93=E6=94=BE=E5=A4=A7100=E5=80=8D?= =?UTF-8?q?=EF=BC=8C=E5=90=8C=E6=97=B6=E8=8E=B7=E5=8F=96=E6=B8=A9=E5=BA=A6?= =?UTF-8?q?=E5=87=BD=E6=95=B0=E5=8A=A0=E5=85=A5=E4=BA=86=E8=B6=85=E6=97=B6?= =?UTF-8?q?=E6=9C=BA=E5=88=B6=E6=9C=AA=E5=8A=A0=E5=85=A5=E7=8A=B6=E6=80=81?= =?UTF-8?q?=E6=9C=BA=E3=80=82=E5=90=8C=E6=97=B6=E5=87=BD=E6=95=B0=E5=91=BD?= =?UTF-8?q?=E5=90=8D=E9=A3=8E=E6=A0=BC=E4=BF=AE=E6=94=B9=EF=BC=9A=E7=B3=BB?= =?UTF-8?q?=E7=BB=9F=E5=BA=93=E5=85=A8=E9=83=A8=E4=B8=BA=E5=B0=8F=E5=86=99?= =?UTF-8?q?=EF=BC=8C=E9=A1=B9=E7=9B=AE=E5=87=BD=E6=95=B0=E5=91=BD=E5=90=8D?= =?UTF-8?q?=E9=87=87=E7=94=A8=E9=A9=BC=E5=B3=B0=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- inc/mlx90614.h | 13 +--- src/main.c | 8 ++- src/mlx90614.c | 181 ++++++++++++++++++++++++++++++------------------- 3 files changed, 119 insertions(+), 83 deletions(-) diff --git a/inc/mlx90614.h b/inc/mlx90614.h index 4dbdb8f..84ca25b 100644 --- a/inc/mlx90614.h +++ b/inc/mlx90614.h @@ -19,20 +19,11 @@ #define I2C_TIME_OUT (uint16_t)(5000) -typedef enum { - I2C_START = 0, - I2C_SEND_ADDR, - I2C_CLEAR_ADDRESS_FLAG, - I2C_TRANSMIT_DATA, - I2C_STOP -} i2c_process_enum; - -// #define I2C_EVENT_MASTER_MODE_SELECT ((uint32_t)(I2C_FLAG_I2CBSY | I2C_FLAG_MASTER | I2C_FLAG_RBNE)) #define SLAVE_ADDR (0x5A << 1) #define REG_ADDR_OBJ_TEMP 0x07 #define REG_ADDR_AMB_TEMP 0x06 -void i2c_config(void); -uint32_t read_ir_mlx90614(void); +void MLX90614_I2CConfig(void); +uint16_t MLX90614_GetObjectTemperature(void); #endif //MLX90614_H diff --git a/src/main.c b/src/main.c index 8e94187..191566d 100644 --- a/src/main.c +++ b/src/main.c @@ -30,9 +30,11 @@ int main(void) ultrasonic_transmit_config(); ultrasonic_receive_config(); + MLX90614_I2CConfig(); + /* ---------- debug start ---------- */ - i2c_config(); + /* ---------- debug end ---------- */ @@ -52,11 +54,11 @@ int main(void) delay_ms(2); printf("cap_val:%ld\t", capture_value); - const char* result = (capture_value <= CAPTURE_VALUE_MAX) ? "Distance: %d\n" : "Over Range\n"; + const char* result = (capture_value <= CAPTURE_VALUE_MAX) ? "Distance: %d\t" : "Over Range\t"; distance_uint16 = calculate_distance(capture_value); printf(result, distance_uint16); - printf("Temp:%d\n", read_ir_mlx90614()); + printf("Temp:%d\n", MLX90614_GetObjectTemperature()); } } diff --git a/src/mlx90614.c b/src/mlx90614.c index b823886..5e63364 100644 --- a/src/mlx90614.c +++ b/src/mlx90614.c @@ -7,8 +7,7 @@ #include "systick.h" #include -void i2c_config(void) -{ +void MLX90614_I2CConfig(void) { rcu_periph_clock_enable(RCU_IR_GPIO); rcu_periph_clock_enable(RCU_I2C); @@ -28,81 +27,125 @@ void i2c_config(void) i2c_ack_config(IR_I2C, I2C_ACK_ENABLE); } -uint32_t read_ir_mlx90614(void) -{ - uint8_t Data[3] = {0}; - uint32_t inttemp_ir = 0; +uint16_t MLX90614_GetObjectTemperature(void) { + uint8_t data[3] = {0}; + uint16_t temp_raw = 0; uint16_t timeout = 0; - // 发送起始信号 - i2c_start_on_bus(IR_I2C); - while(i2c_flag_get(IR_I2C, I2C_FLAG_I2CBSY) && (timeout < I2C_TIME_OUT)) { - timeout++; - } - if (timeout >= I2C_TIME_OUT) { - return -41001; // 超时返回错误 - } + i2c_ack_config(IR_I2C, I2C_ACK_ENABLE); - // 发送从机地址和写操作位 - i2c_master_addressing(IR_I2C, SLAVE_ADDR, I2C_TRANSMITTER); - while(!i2c_flag_get(IR_I2C, I2C_FLAG_ADDSEND) && (timeout < I2C_TIME_OUT)) { + while (i2c_flag_get(IR_I2C, I2C_FLAG_I2CBSY) && (timeout < I2C_TIME_OUT)) //判断IIC总线是否忙,发送起始信号 timeout++; - } - if (timeout >= I2C_TIME_OUT) { - return -41002; // 超时返回错误 - } - i2c_flag_clear(IR_I2C, I2C_FLAG_ADDSEND); - - // 发送寄存器地址 - i2c_data_transmit(IR_I2C, REG_ADDR_OBJ_TEMP); - while(!i2c_flag_get(IR_I2C, I2C_FLAG_TBE) && (timeout < I2C_TIME_OUT)) { - timeout++; - } - if (timeout >= I2C_TIME_OUT) { - return -41003; // 超时返回错误 - } - - // 重复起始信号 - i2c_start_on_bus(IR_I2C); - while(i2c_flag_get(IR_I2C, I2C_FLAG_I2CBSY) && (timeout < I2C_TIME_OUT)) { - timeout++; - } - if (timeout >= I2C_TIME_OUT) { - return -41004; // 超时返回错误 - } - - // 发送从机地址和读操作位 - i2c_master_addressing(IR_I2C, SLAVE_ADDR, I2C_RECEIVER); - while(!i2c_flag_get(IR_I2C, I2C_FLAG_ADDSEND) && (timeout < I2C_TIME_OUT)) { - timeout++; - } - if (timeout >= I2C_TIME_OUT) { - return -41005; // 超时返回错误 - } - i2c_flag_clear(IR_I2C, I2C_FLAG_ADDSEND); - - // 读取数据 - for (int i = 0; i < 3; i++) { - while(!i2c_flag_get(IR_I2C, I2C_FLAG_RBNE) && (timeout < I2C_TIME_OUT)) { - timeout++; - } - if (timeout >= I2C_TIME_OUT) { - return -41006; // 超时返回错误 - } - Data[i] = i2c_data_receive(IR_I2C); - if (i < 2) { - i2c_ack_config(IR_I2C, I2C_ACK_ENABLE); - } else { - i2c_ack_config(IR_I2C, I2C_ACK_DISABLE); - } + if (timeout < I2C_TIME_OUT) { + i2c_start_on_bus(IR_I2C); timeout = 0; + } else { + printf("err\r\n"); + return -4100; // 超时返回错误 + } + + while (!i2c_flag_get(IR_I2C, I2C_FLAG_SBSEND) && (timeout < I2C_TIME_OUT)) //判断起始位是否发送,设置sensor地址并设置为写 + timeout++; + if (timeout < I2C_TIME_OUT) { + i2c_master_addressing(IR_I2C, SLAVE_ADDR, I2C_TRANSMITTER); + timeout = 0; + } else { + return -4100; // 超时返回错误 + } + + while (!i2c_flag_get(IR_I2C, I2C_FLAG_ADDSEND) && (timeout < I2C_TIME_OUT)) + timeout++; + if (timeout < I2C_TIME_OUT) { + i2c_flag_clear(IR_I2C, I2C_FLAG_ADDSEND); + timeout = 0; + } else { + return -4100; // 超时返回错误 + } + + while (!i2c_flag_get(IR_I2C, I2C_FLAG_TBE) && (timeout < I2C_TIME_OUT)) //判断地址是否发送完成,然后发送寄存器地址 + timeout++; + if (timeout < I2C_TIME_OUT) { + i2c_data_transmit(IR_I2C, REG_ADDR_OBJ_TEMP); + timeout = 0; + // i2c_start_on_bus(IR_I2C); + } else { + return -4100; // 超时返回错误 + } + + while (i2c_flag_get(IR_I2C, I2C_FLAG_BTC) && (timeout < I2C_TIME_OUT)) //判断发送缓冲器是否为空,为空后(发送完毕)重新发送开始信号 + timeout++; + if (timeout < I2C_TIME_OUT) { + i2c_start_on_bus(IR_I2C); + timeout = 0; + } else { + return -4100; // 超时返回错误 + } + + while (!i2c_flag_get(IR_I2C, I2C_FLAG_SBSEND) && (timeout < I2C_TIME_OUT)) { + timeout++; + } + if (timeout < I2C_TIME_OUT) { + i2c_master_addressing(IR_I2C, SLAVE_ADDR, I2C_RECEIVER); + timeout = 0; + } else { + return -4100; // 超时返回错误 + } + + while (!i2c_flag_get(IR_I2C, I2C_FLAG_ADDSEND) && (timeout < I2C_TIME_OUT)) + timeout++; + if (timeout < I2C_TIME_OUT) { + i2c_flag_clear(IR_I2C, I2C_FLAG_ADDSEND); + timeout = 0; + } else { + return -4100; // 超时返回错误 + } + + // 读取第一个字节的数据 + while (!i2c_flag_get(IR_I2C, I2C_FLAG_RBNE) && (timeout < I2C_TIME_OUT)) { + timeout++; + } + if (timeout < I2C_TIME_OUT) { + data[0] = i2c_data_receive(IR_I2C); + timeout = 0; + } else { + return -4100; // 超时返回错误 + } + + // 读取第二个字节的数据 + while (!i2c_flag_get(IR_I2C, I2C_FLAG_RBNE) && (timeout < I2C_TIME_OUT)) { + timeout++; + } + if (timeout < I2C_TIME_OUT) { + data[1] = i2c_data_receive(IR_I2C); + timeout = 0; + } else { + return -4100; // 超时返回错误 + } + + i2c_ack_config(IR_I2C, I2C_ACK_DISABLE); // 关闭发送ACK,它会在下一个字节完成后发送NAK + + // 读取第三个字节的数据 + while (!i2c_flag_get(IR_I2C, I2C_FLAG_RBNE) && (timeout < I2C_TIME_OUT)) { + timeout++; + } + if (timeout < I2C_TIME_OUT) { + data[2] = i2c_data_receive(IR_I2C); + timeout = 0; + } else { + return -4100; // 超时返回错误 } - // 发送停止信号 i2c_stop_on_bus(IR_I2C); - // 计算温度 - inttemp_ir = ((uint16_t)(Data[1] << 8) | Data[0]) * 2 -27315; + temp_raw = ((uint16_t) (data[1] << 8) | data[0]) * 2 - 27315; + // (Data[1] << 8) | data[0] * 0.02 -273.15 为避免浮点运算,直接放大100倍 - return inttemp_ir; // 返回温度值 + if (temp_raw > 8500) { + temp_raw = 8500; + } + if (temp_raw < -4000) { + temp_raw = -4000; + } + + return temp_raw; }