From 00dfdc4c8fa7afc348514791a7c75524d629172e Mon Sep 17 00:00:00 2001 From: yelvlab Date: Wed, 9 Oct 2024 17:38:05 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9mlx90614=EF=BC=8C=E6=9C=AA?= =?UTF-8?q?=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- inc/mlx90614.h | 24 ++- inc/ultrasonic_driver.h | 2 +- src/mlx90614.c | 403 ++++++++++++++++++++-------------------- 3 files changed, 221 insertions(+), 208 deletions(-) diff --git a/inc/mlx90614.h b/inc/mlx90614.h index b0136e7..4dbdb8f 100644 --- a/inc/mlx90614.h +++ b/inc/mlx90614.h @@ -5,12 +5,34 @@ #ifndef MLX90614_H #define MLX90614_H +#include "gd32e23x.h" + +#define I2C_SPEED 100000 +#define IR_I2C I2C0 +#define RCU_IR_GPIO RCU_GPIOF +#define RCU_I2C RCU_I2C0 +#define I2C_SCL_PORT GPIOF +#define I2C_SCL_PIN GPIO_PIN_1 +#define I2C_SDA_PORT GPIOF +#define I2C_SDA_PIN GPIO_PIN_0 +#define I2C_GPIO_AF GPIO_AF_1 + +#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); -int read_ir_mlx90614(void); +uint32_t read_ir_mlx90614(void); #endif //MLX90614_H diff --git a/inc/ultrasonic_driver.h b/inc/ultrasonic_driver.h index b7aaffb..17f941d 100644 --- a/inc/ultrasonic_driver.h +++ b/inc/ultrasonic_driver.h @@ -21,7 +21,7 @@ #endif #define ULTRASONIC_CYCLES 0x05U -#define ULTRASONIC_TRAN_US 500 // (ms) +#define ULTRASONIC_TRAN_US 998 // (ms) #define LED_PORT GPIOA #define LED_PIN GPIO_PIN_9 diff --git a/src/mlx90614.c b/src/mlx90614.c index 5020641..9f2061b 100644 --- a/src/mlx90614.c +++ b/src/mlx90614.c @@ -8,220 +8,211 @@ #include void i2c_config(void) { - rcu_periph_clock_enable(RCU_I2C0); - rcu_periph_clock_enable(RCU_GPIOF); + rcu_periph_clock_enable(RCU_IR_GPIO); + rcu_periph_clock_enable(RCU_I2C); - gpio_af_set(GPIOF, GPIO_AF_1, GPIO_PIN_0 | GPIO_PIN_1); - gpio_output_options_set(GPIOF, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, GPIO_PIN_0 | GPIO_PIN_1); + gpio_af_set(I2C_SCL_PORT, I2C_GPIO_AF, I2C_SCL_PIN); + gpio_af_set(I2C_SDA_PORT, I2C_GPIO_AF, I2C_SDA_PIN); - i2c_clock_config(I2C0, 400000U, I2C_DTCY_2); - i2c_mode_addr_config(I2C0, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_7BITS, 0xA0); - i2c_enable(I2C0); - i2c_ack_config(I2C0, I2C_ACK_ENABLE); + gpio_mode_set(I2C_SCL_PORT, GPIO_MODE_AF, GPIO_PUPD_PULLUP, I2C_SCL_PIN); + gpio_output_options_set(I2C_SCL_PORT, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, I2C_SCL_PIN); - i2c_start_on_bus(I2C0); + gpio_mode_set(I2C_SDA_PORT, GPIO_MODE_AF, GPIO_PUPD_PULLUP, I2C_SDA_PIN); + gpio_output_options_set(I2C_SDA_PORT, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, I2C_SDA_PIN); - // nvic_irq_enable(I2C0_EV_IRQn, 2); - // nvic_irq_enable(I2C0_ER_IRQn, 2); + i2c_clock_config(IR_I2C, I2C_SPEED, I2C_DTCY_2); + + i2c_mode_addr_config(IR_I2C, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_7BITS, SLAVE_ADDR); + i2c_enable(IR_I2C); + i2c_ack_config(IR_I2C, I2C_ACK_ENABLE); } -int read_ir_mlx90614(void) { +uint32_t read_ir_mlx90614(void) { uint8_t Data[5]; - int inttemp_ir = 0; + uint32_t inttemp_ir = 0; uint32_t TIMEOUT = 0; - // while(TIMEOUT<10000&&I2C_GetFlagStatus(I2C1,I2C_FLAG_BUSY)) - while (TIMEOUT < 10000 && i2c_flag_get(I2C0, I2C_FLAG_I2CBSY)) - TIMEOUT++; - if (TIMEOUT >= 10000) { - printf("ERROR0\r\n"); - return -410; - } - TIMEOUT = 0; - // I2C_GenerateSTART(I2C0, ENABLE); - i2c_start_on_bus(I2C0); - // while (TIMEOUT < 10000 && !I2C_CheckEvent(I2C0, I2C_EVENT_MASTER_MODE_SELECT)) - /* 等待发送模式 - * I2C_EVENT_MASTER_MODE_SELECT --> BUSY, MSL and SB flags - * || - * !i2c_flag_get(I2C0, I2C_FLAG_I2CBSY) && - * !i2c_flag_get(I2C0, I2C_FLAG_MASTER) && - * !i2c_flag_get(I2C0, I2C_FLAG_SBSEND) - */ - while (TIMEOUT < 10000 - && !i2c_flag_get(I2C0, I2C_FLAG_I2CBSY) - && !i2c_flag_get(I2C0, I2C_FLAG_MASTER) - && !i2c_flag_get(I2C0, I2C_FLAG_SBSEND)) - TIMEOUT++; - if (TIMEOUT >= 10000) { - printf("ERROR1\r\n"); - return -410; - } - // I2C_AcknowledgeConfig(I2C0,DISABLE); - TIMEOUT = 0; - // I2C_Send7bitAddress(I2C0, 0XB4, I2C_Direction_Transmitter); - i2c_master_addressing(I2C0, SLAVE_ADDR, I2C_TRANSMITTER); - // while (TIMEOUT < 10000 && !I2C_CheckEvent(I2C0, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) - /* 等待发送地址完成 - * I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED --> BUSY, MSL, ADDR, TXE and TRA flags - * || - * !i2c_flag_get(I2C0, I2C_FLAG_I2CBSY) && - * !i2c_flag_get(I2C0, I2C_FLAG_MASTER) && - * !i2c_flag_get(I2C0, I2C_FLAG_ADDSEND) && - * !i2c_flag_get(I2C0, I2C_FLAG_TBE) && - * !i2c_flag_get(I2C0, I2C_FLAG_TR) - */ - while (TIMEOUT < 10000 && - !i2c_flag_get(I2C0, I2C_FLAG_I2CBSY) && - !i2c_flag_get(I2C0, I2C_FLAG_MASTER) && - !i2c_flag_get(I2C0, I2C_FLAG_ADDSEND) && - !i2c_flag_get(I2C0, I2C_FLAG_TBE) && - !i2c_flag_get(I2C0, I2C_FLAG_TR)) - TIMEOUT++; - if (TIMEOUT >= 10000) { - printf("ERROR2\r\n"); - return -410; - } - // I2C_SendData(I2C0, 0x07); - i2c_data_transmit(I2C0, REG_ADDR_OBJ_TEMP); - TIMEOUT = 0; - // I2C_GenerateSTART(I2C0, ENABLE); - i2c_start_on_bus(I2C0); - // while (TIMEOUT < 10000 && !I2C_CheckEvent(I2C0, I2C_EVENT_MASTER_MODE_SELECT)) - /* 等待发送模式 - * I2C_EVENT_MASTER_MODE_SELECT --> BUSY, MSL and SB flags - * || - * !i2c_flag_get(I2C0, I2C_FLAG_I2CBSY) && - * !i2c_flag_get(I2C0, I2C_FLAG_MASTER) && - * !i2c_flag_get(I2C0, I2C_FLAG_SBSEND) - */ - while (TIMEOUT < 10000 && !i2c_flag_get(I2C0, I2C_FLAG_I2CBSY) - && !i2c_flag_get(I2C0, I2C_FLAG_MASTER) - && !i2c_flag_get(I2C0, I2C_FLAG_SBSEND)) - TIMEOUT++; - if (TIMEOUT >= 10000) { - printf("ERROR3\r\n"); - return -410; + uint8_t state = I2C_START; + uint8_t read_cycle = 0; + uint16_t timeout = 0; + uint8_t i2c_timeout_flag = 0; + + i2c_ack_config(IR_I2C, I2C_ACK_ENABLE); + while (!(i2c_timeout_flag)) + { + switch (state) + { + case I2C_START: + if(RESET == read_cycle) + { + /* i2c master sends start signal only when the bus is idle */ + while (i2c_flag_get(IR_I2C, I2C_FLAG_I2CBSY) && (timeout < i2c_timeout_flag)) + { + timeout ++; + } + if(timeout < I2C_TIME_OUT) + { + /* whether to send ACK or not for the next byte */ + if(2 == RegisterLen) { + i2c_ackpos_config(IR_I2C, I2C_ACKPOS_NEXT); + } + } else { + i2c_bus_reset(); + timeout = 0; + state = I2C_START; + printf("i2c bus is busy in READ!\n"); + } + } + /* send the start signal */ + i2c_start_on_bus(IR_I2C); + timeout = 0; + state = I2C_SEND_ADDR; + break; + + case I2C_SEND_ADDR: + /* i2c master sends START signal successfully */ + while((!i2c_flag_get(IR_I2C, I2C_FLAG_SBSEND)) && (timeout < I2C_TIME_OUT)) + { + timeout++; + } + if(timeout < I2C_TIME_OUT) + { + if(RESET == read_cycle) + { + i2c_master_addressing(IR_I2C, SLAVE_ADDR, I2C_TRANSMITTER); + state = I2C_CLEAR_ADDRESS_FLAG; + } else { + i2c_master_addressing(IR_I2C, SLAVE_ADDR, I2C_RECEIVER); + if(RegisterLen < 3) { + /* disable acknowledge */ + i2c_ack_config(IR_I2C, I2C_ACK_DISABLE); + } + state = I2C_CLEAR_ADDRESS_FLAG; + } + timeout = 0; + } else { + timeout = 0; + state = I2C_START; + read_cycle = 0; + printf("i2c master sends start signal timeout in READ!\n"); + } + break; + + case I2C_CLEAR_ADDRESS_FLAG: + /* address flag set means i2c slave sends ACK */ + 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); + if((SET == read_cycle) && (1 == RegisterLen)) { + /* send a stop condition to I2C bus */ + i2c_stop_on_bus(IR_I2C); + } + timeout = 0; + state = I2C_TRANSMIT_DATA; + } else { + timeout = 0; + state = I2C_START; + read_cycle = 0; + printf("i2c master clears address flag timeout in READ!\n"); + } + break; + + case I2C_TRANSMIT_DATA: + if(RESET == read_cycle) { + /* wait until the transmit data buffer is empty */ + while((!i2c_flag_get(IR_I2C, I2C_FLAG_TBE)) && (timeout < I2C_TIME_OUT)) { + timeout++; + } + if(timeout < I2C_TIME_OUT) { + /* send the EEPROM's internal address to write to : only one byte address */ + i2c_data_transmit(IR_I2C, RegisterAddr); + timeout = 0; + } else { + timeout = 0; + state = I2C_START; + read_cycle = 0; + printf("i2c master wait data buffer is empty timeout in READ!\n"); + } + /* wait until BTC bit is set */ + while((!i2c_flag_get(IR_I2C, I2C_FLAG_BTC)) && (timeout < I2C_TIME_OUT)) { + timeout++; + } + if(timeout < I2C_TIME_OUT) { + timeout = 0; + state = I2C_START; + read_cycle++; + } else { + timeout = 0; + state = I2C_START; + read_cycle = 0; + printf("i2c master sends i2c_master_read_register1 internal address timeout in READ!\n"); + } + } else { + while(RegisterLen) { + timeout++; + if(3 == RegisterLen) { + /* wait until BTC bit is set */ + while(!i2c_flag_get(IR_I2C, I2C_FLAG_BTC)); + /* disable acknowledge */ + i2c_ack_config(IR_I2C, I2C_ACK_DISABLE); + } + if(2 == RegisterLen) { + /* wait until BTC bit is set */ + while(!i2c_flag_get(IR_I2C, I2C_FLAG_BTC)); + /* send a stop condition to I2C bus */ + i2c_stop_on_bus(IR_I2C); + } + /* wait until RBNE bit is set */ + if(i2c_flag_get(IR_I2C, I2C_FLAG_RBNE)) { + /* read a byte from the EEPROM */ + *RegisterValue = i2c_data_receive(IR_I2C); + /* point to the next location where the byte read will be saved */ + RegisterValue++; + /* decrement the read bytes counter */ + RegisterLen--; + timeout = 0; + } + if(timeout > I2C_TIME_OUT) { + timeout = 0; + state = I2C_START; + read_cycle = 0; + printf("i2c master sends data timeout in READ!\n"); + } + } + timeout = 0; + state = I2C_STOP; + } + break; + + case I2C_STOP: + /* i2c master sends STOP signal successfully */ + while((I2C_CTL0(IR_I2C) & I2C_CTL0_STOP) && (timeout < I2C_TIME_OUT)) { + timeout++; + } + if(timeout < I2C_TIME_OUT) { + timeout = 0; + state = I2C_END; + i2c_timeout_flag = I2C_OK; + } else { + timeout = 0; + state = I2C_START; + read_cycle = 0; + printf("i2c master sends stop signal timeout in READ!\n"); + } + break; + + default: + state = I2C_START; + read_cycle = 0; + i2c_timeout_flag = I2C_OK; + timeout = 0; + printf("i2c master sends start signal in READ.\n"); + break; + } } - TIMEOUT = 0; - // I2C_Send7bitAddress(I2C0, 0XB4, I2C_Direction_Receiver); - i2c_master_addressing(I2C0, SLAVE_ADDR, I2C_RECEIVER); - // while (TIMEOUT < 10000 && !I2C_CheckEvent(I2C0, I2C_EVENT_MASTER_BYTE_RECEIVED)) - /* 等待接收完成 - * I2C_EVENT_MASTER_BYTE_RECEIVED --> BUSY, MSL, RXNE flags - * || - * !i2c_flag_get(I2C0, I2C_FLAG_I2CBSY) && - * !i2c_flag_get(I2C0, I2C_FLAG_MASTER) && - * !i2c_flag_get(I2C0, I2C_FLAG_RBNE) - */ - while (TIMEOUT < 10000 && !i2c_flag_get(I2C0, I2C_FLAG_I2CBSY) - && !i2c_flag_get(I2C0, I2C_FLAG_MASTER) - && !i2c_flag_get(I2C0, I2C_FLAG_RBNE)) - TIMEOUT++; - if (TIMEOUT >= 10000) { - printf("ERROR4\r\n"); - return -410; - } - //I2C_AcknowledgeConfig(I2C0,DISABLE); - TIMEOUT = 0; - // Data[0] = I2C_ReceiveData(I2C0); - Data[0] = i2c_data_receive(I2C0); - // while (TIMEOUT < 10000 && !I2C_CheckEvent(I2C0, I2C_EVENT_MASTER_BYTE_RECEIVED)) - /* 等待接收完成 - * I2C_EVENT_MASTER_BYTE_RECEIVED --> BUSY, MSL, RXNE flags - * || - * !i2c_flag_get(I2C0, I2C_FLAG_I2CBSY) && - * !i2c_flag_get(I2C0, I2C_FLAG_MASTER) && - * !i2c_flag_get(I2C0, I2C_FLAG_RBNE) - */ - while (TIMEOUT < 10000 && !i2c_flag_get(I2C0, I2C_FLAG_I2CBSY) - && !i2c_flag_get(I2C0, I2C_FLAG_MASTER) - && !i2c_flag_get(I2C0, I2C_FLAG_RBNE)) - TIMEOUT++; - if (TIMEOUT >= 10000) { - printf("ERROR5\r\n"); - return -410; - } - - TIMEOUT = 0; - // Data[1] = I2C_ReceiveData(I2C0); - Data[1] = i2c_data_receive(I2C0); - // while (TIMEOUT < 10000 && !I2C_CheckEvent(I2C0, I2C_EVENT_MASTER_BYTE_RECEIVED)) - /* 等待接收完成 - * I2C_EVENT_MASTER_BYTE_RECEIVED --> BUSY, MSL, RXNE flags - * || - * !i2c_flag_get(I2C0, I2C_FLAG_I2CBSY) && - * !i2c_flag_get(I2C0, I2C_FLAG_MASTER) && - * !i2c_flag_get(I2C0, I2C_FLAG_RBNE) - */ - while (TIMEOUT < 10000 && !i2c_flag_get(I2C0, I2C_FLAG_I2CBSY) - && !i2c_flag_get(I2C0, I2C_FLAG_MASTER) - && !i2c_flag_get(I2C0, I2C_FLAG_RBNE)) - TIMEOUT++; - if (TIMEOUT >= 10000) { - printf("ERROR6\r\n"); - return -410; - } - - TIMEOUT = 0; - // Data[2] = I2C_ReceiveData(I2C0); - Data[2] = i2c_data_receive(I2C0); - // while (TIMEOUT < 10000 && !I2C_CheckEvent(I2C0, I2C_EVENT_MASTER_BYTE_RECEIVED)) - /* 等待接收完成 - * I2C_EVENT_MASTER_BYTE_RECEIVED --> BUSY, MSL, RXNE flags - * || - * !i2c_flag_get(I2C0, I2C_FLAG_I2CBSY) && - * !i2c_flag_get(I2C0, I2C_FLAG_MASTER) && - * !i2c_flag_get(I2C0, I2C_FLAG_RBNE) - */ - while (TIMEOUT < 10000 && !i2c_flag_get(I2C0, I2C_FLAG_I2CBSY) - && !i2c_flag_get(I2C0, I2C_FLAG_MASTER) - && !i2c_flag_get(I2C0, I2C_FLAG_RBNE)) - TIMEOUT++; - if (TIMEOUT >= 10000) { - //printf("ERROR7\r\n"); - return -410; - } - - - // I2C_AcknowledgeConfig(I2C0, DISABLE); - i2c_ack_config(I2C0, I2C_ACK_DISABLE); - // Data[3] = I2C_ReceiveData(I2C0); - Data[3] = i2c_data_receive(I2C0); - // while (TIMEOUT < 10000 && !I2C_CheckEvent(I2C0, I2C_EVENT_MASTER_BYTE_RECEIVED)) - /* 等待接收完成 - * I2C_EVENT_MASTER_BYTE_RECEIVED --> BUSY, MSL, RXNE flags - * || - * !i2c_flag_get(I2C0, I2C_FLAG_I2CBSY) && - * !i2c_flag_get(I2C0, I2C_FLAG_MASTER) && - * !i2c_flag_get(I2C0, I2C_FLAG_RBNE) - */ - while (TIMEOUT < 10000 && !i2c_flag_get(I2C0, I2C_FLAG_I2CBSY) - && !i2c_flag_get(I2C0, I2C_FLAG_MASTER) - && !i2c_flag_get(I2C0, I2C_FLAG_RBNE)) - TIMEOUT++; - if (TIMEOUT >= 10000) { - //printf("ERROR11\r\n"); - return -410; - } - - - // I2C_GenerateSTOP(I2C0, ENABLE); - i2c_stop_on_bus(I2C0); - // I2C_AcknowledgeConfig(I2C0, ENABLE); - i2c_ack_config(I2C0, I2C_ACK_ENABLE); - printf("data:%x,%x,%x\r\n",Data[0],Data[1],Data[2]); - // inttemp_ir = (int) ((Data[0] + Data[1] * 255) * 0.2 - 2731.5); - // Data[0] = 0x41; - // Data[1] = 0x39; - inttemp_ir = (((Data[1] << 8) | Data[0]) * 2 - 27315); - // printf("temp:%d\r\n",inttemp_ir); - - - // if (inttemp_ir < -4000) - // inttemp_ir = -4000; - // if (inttemp_ir > 8500) - // inttemp_ir = 8500; - // - return inttemp_ir; + return IIC_SUCCESS; }