diff --git a/Inc/i2c.h b/Inc/i2c.h index 5578ac3..e810478 100644 --- a/Inc/i2c.h +++ b/Inc/i2c.h @@ -56,18 +56,10 @@ typedef enum { I2C_STATE_RESTART, /* Generate restart condition */ I2C_STATE_RECEIVE_DATA, /* Receive data */ I2C_STATE_STOP, /* Generate stop condition */ - I2C_STATE_ERROR /* Error state */ + I2C_STATE_ERROR, /* Error state */ + I2C_STATE_END } i2c_state_t; -/* Legacy enumeration for compatibility */ -typedef enum { - I2C_START = 0, - I2C_SEND_ADDRESS, - I2C_CLEAR_ADDRESS_FLAG, - I2C_TRANSMIT_DATA, - I2C_STOP -} i2c_process_enum; - /******************************************************************************/ @@ -96,7 +88,6 @@ i2c_result_t i2c_bus_reset(void); */ void i2c_scan(void); -// TODO I2C Result /*! \brief write 16-bit data to I2C device \param[in] slave_addr: 7-bit slave address @@ -105,9 +96,8 @@ void i2c_scan(void); \param[out] none \retval i2c_result_t */ -uint8_t i2c_write_16bits(uint8_t slave_addr, uint8_t reg_addr, uint8_t data[2]); +i2c_result_t i2c_write_16bits(uint8_t slave_addr, uint8_t reg_addr, uint8_t data[2]); -// TODO I2C Result /*! \brief read 16-bit data from I2C device \param[in] slave_addr: 7-bit slave address @@ -115,9 +105,8 @@ uint8_t i2c_write_16bits(uint8_t slave_addr, uint8_t reg_addr, uint8_t data[2]); \param[out] data: pointer to 2-byte data buffer \retval i2c_result_t */ -uint8_t i2c_read_16bits(uint8_t slave_addr, uint8_t reg_addr, uint8_t *data); +i2c_result_t i2c_read_16bits(uint8_t slave_addr, uint8_t reg_addr, uint8_t *data); -// TODO I2C Result /*! \brief read 16-bit data from I2C device \param[in] slave_addr: 7-bit slave address @@ -125,7 +114,7 @@ uint8_t i2c_read_16bits(uint8_t slave_addr, uint8_t reg_addr, uint8_t *data); \param[out] data: pointer to 2-byte data buffer \retval i2c_result_t */ -uint8_t i2c_read_16bits(uint8_t slave_addr, uint8_t reg_addr, uint8_t *data); +i2c_result_t i2c_read_16bits(uint8_t slave_addr, uint8_t reg_addr, uint8_t *data); /*! \brief get status string for debugging diff --git a/Src/i2c.c b/Src/i2c.c index c0df70b..aee320c 100644 --- a/Src/i2c.c +++ b/Src/i2c.c @@ -156,6 +156,7 @@ i2c_result_t i2c_bus_reset(void) { return I2C_RECOVERY_OK; } +#ifdef DEBUG_VERBOSE /** * @brief 扫描I2C总线,查找连接的设备 * @@ -262,17 +263,24 @@ void i2c_scan(void) { while (usart_flag_get(I2C_DEBUG_UART, USART_FLAG_TC) == RESET) {} } } +#endif -uint8_t i2c_write_16bits(uint8_t slave_addr, uint8_t reg_addr, uint8_t data[2]) { - uint8_t state = I2C_START; +i2c_result_t i2c_write_16bits(uint8_t slave_addr, uint8_t reg_addr, uint8_t data[2]) { + uint8_t state = I2C_STATE_START; uint16_t timeout = 0; uint8_t i2c_timeout_flag = 0; + /* parameter validation */ + if (data == NULL || slave_addr > 0x7F) { + return I2C_RESULT_INVALID_PARAM; + } + /* enable acknowledge */ i2c_ack_config(I2C0, I2C_ACK_ENABLE); + while (!(i2c_timeout_flag)) { switch (state) { - case I2C_START: + case I2C_STATE_START: /* i2c master sends start signal only when the bus is idle */ while (i2c_flag_get(I2C0, I2C_FLAG_I2CBSY) && (timeout < I2C_TIME_OUT)) { timeout++; @@ -280,16 +288,16 @@ uint8_t i2c_write_16bits(uint8_t slave_addr, uint8_t reg_addr, uint8_t data[2]) if (timeout < I2C_TIME_OUT) { i2c_start_on_bus(I2C0); timeout = 0; - state = I2C_SEND_ADDRESS; + state = I2C_STATE_SEND_ADDRESS; } else { timeout = 0; - state = I2C_START; + state = I2C_STATE_START; #ifdef DEBUG_VERBOES printf("i2c bus is busy in WRITE BYTE!\n"); #endif } break; - case I2C_SEND_ADDRESS: + case I2C_STATE_SEND_ADDRESS: /* i2c master sends START signal successfully */ while ((!i2c_flag_get(I2C0, I2C_FLAG_SBSEND)) && (timeout < I2C_TIME_OUT)) { timeout++; @@ -297,16 +305,16 @@ uint8_t i2c_write_16bits(uint8_t slave_addr, uint8_t reg_addr, uint8_t data[2]) if (timeout < I2C_TIME_OUT) { i2c_master_addressing(I2C0, slave_addr << 1, I2C_TRANSMITTER); timeout = 0; - state = I2C_CLEAR_ADDRESS_FLAG; + state = I2C_STATE_CLEAR_ADDRESS; } else { timeout = 0; - state = I2C_START; + state = I2C_STATE_START; #ifdef DEBUG_VERBOES printf("i2c master sends start signal timeout in WRITE BYTE!\n"); #endif } break; - case I2C_CLEAR_ADDRESS_FLAG: + case I2C_STATE_CLEAR_ADDRESS: /* address flag set means i2c slave sends ACK */ while ((!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND)) && (timeout < I2C_TIME_OUT)) { timeout++; @@ -314,16 +322,16 @@ uint8_t i2c_write_16bits(uint8_t slave_addr, uint8_t reg_addr, uint8_t data[2]) if (timeout < I2C_TIME_OUT) { i2c_flag_clear(I2C0, I2C_FLAG_ADDSEND); timeout = 0; - state = I2C_TRANSMIT_DATA; + state = I2C_STATE_TRANSMIT_DATA; } else { timeout = 0; - state = I2C_START; + state = I2C_STATE_START; #ifdef DEBUG_VERBOES printf("i2c master clears address flag timeout in WRITE BYTE!\n"); #endif } break; - case I2C_TRANSMIT_DATA: + case I2C_STATE_TRANSMIT_DATA: /* wait until the transmit data buffer is empty */ while ((!i2c_flag_get(I2C0, I2C_FLAG_TBE)) && (timeout < I2C_TIME_OUT)) { timeout++; @@ -334,7 +342,7 @@ uint8_t i2c_write_16bits(uint8_t slave_addr, uint8_t reg_addr, uint8_t data[2]) timeout = 0; } else { timeout = 0; - state = I2C_START; + state = I2C_STATE_START; #ifdef DEBUG_VERBOES printf("i2c master sends data timeout in WRITE BYTE!\n"); #endif @@ -350,7 +358,7 @@ uint8_t i2c_write_16bits(uint8_t slave_addr, uint8_t reg_addr, uint8_t data[2]) timeout = 0; } else { timeout = 0; - state = I2C_START; + state = I2C_STATE_START; #ifdef DEBUG_VERBOES printf("i2c master sends MSB data timeout in WRITE BYTE!\n"); #endif @@ -364,10 +372,10 @@ uint8_t i2c_write_16bits(uint8_t slave_addr, uint8_t reg_addr, uint8_t data[2]) /* send register LSB value */ i2c_data_transmit(I2C0, data[1]); timeout = 0; - state = I2C_STOP; + state = I2C_STATE_STOP; } else { timeout = 0; - state = I2C_START; + state = I2C_STATE_START; #ifdef DEBUG_VERBOES printf("i2c master sends LSB data timeout in WRITE BYTE!\n"); #endif @@ -378,17 +386,17 @@ uint8_t i2c_write_16bits(uint8_t slave_addr, uint8_t reg_addr, uint8_t data[2]) timeout++; } if (timeout < I2C_TIME_OUT) { - state = I2C_STOP; + state = I2C_STATE_STOP; timeout = 0; } else { timeout = 0; - state = I2C_START; + state = I2C_STATE_START; #ifdef DEBUG_VERBOES printf("i2c master sends data timeout in WRITE BYTE!\n"); #endif } break; - case I2C_STOP: + case I2C_STATE_STOP: /* send a stop condition to I2C bus */ i2c_stop_on_bus(I2C0); /* i2c master sends STOP signal successfully */ @@ -397,18 +405,18 @@ uint8_t i2c_write_16bits(uint8_t slave_addr, uint8_t reg_addr, uint8_t data[2]) } if (timeout < I2C_TIME_OUT) { timeout = 0; - state = I2C_END; + state = I2C_STATE_END; i2c_timeout_flag = I2C_OK; } else { timeout = 0; - state = I2C_START; + state = I2C_STATE_START; #ifdef DEBUG_VERBOES printf("i2c master sends stop signal timeout in WRITE BYTE!\n"); #endif } break; default: - state = I2C_START; + state = I2C_STATE_START; i2c_timeout_flag = I2C_OK; timeout = 0; #ifdef DEBUG_VERBOES @@ -417,14 +425,19 @@ uint8_t i2c_write_16bits(uint8_t slave_addr, uint8_t reg_addr, uint8_t data[2]) break; } } - return I2C_END; + return I2C_RESULT_SUCCESS; } -uint8_t i2c_read_16bits(uint8_t slave_addr, uint8_t reg_addr, uint8_t *data) { - uint8_t state = I2C_START; - uint8_t read_cycle = 0; +i2c_result_t i2c_read_16bits(uint8_t slave_addr, uint8_t reg_addr, uint8_t *data) { + // 参数检查:防止空指针和非法地址 + if (data == NULL || slave_addr > 0x7F) { + return I2C_RESULT_INVALID_PARAM; + } + + i2c_state_t state = I2C_STATE_START; + bool read_cycle = false; + bool i2c_timeout_flag = false; uint16_t timeout = 0; - uint8_t i2c_timeout_flag = 0; uint8_t number_of_byte = 2; /* enable acknowledge */ @@ -432,7 +445,7 @@ uint8_t i2c_read_16bits(uint8_t slave_addr, uint8_t reg_addr, uint8_t *data) { while (!(i2c_timeout_flag)) { switch (state) { - case I2C_START: + case I2C_STATE_START: if (RESET == read_cycle) { /* i2c master sends start signal only when the bus is idle */ while (i2c_flag_get(I2C0, I2C_FLAG_I2CBSY) && (timeout < I2C_TIME_OUT)) { @@ -444,7 +457,7 @@ uint8_t i2c_read_16bits(uint8_t slave_addr, uint8_t reg_addr, uint8_t *data) { } else { // i2c_bus_reset(); timeout = 0; - state = I2C_START; + state = I2C_STATE_START; #ifdef DEBUG_VERBOES printf("i2c bus is busy in READ!\n"); #endif @@ -453,9 +466,9 @@ uint8_t i2c_read_16bits(uint8_t slave_addr, uint8_t reg_addr, uint8_t *data) { /* send the start signal */ i2c_start_on_bus(I2C0); timeout = 0; - state = I2C_SEND_ADDRESS; + state = I2C_STATE_SEND_ADDRESS; break; - case I2C_SEND_ADDRESS: + case I2C_STATE_SEND_ADDRESS: /* i2c master sends START signal successfully */ while ((!i2c_flag_get(I2C0, I2C_FLAG_SBSEND)) && (timeout < I2C_TIME_OUT)) { timeout++; @@ -463,45 +476,56 @@ uint8_t i2c_read_16bits(uint8_t slave_addr, uint8_t reg_addr, uint8_t *data) { if (timeout < I2C_TIME_OUT) { if (RESET == read_cycle) { i2c_master_addressing(I2C0, slave_addr << 1, I2C_TRANSMITTER); - state = I2C_CLEAR_ADDRESS_FLAG; + state = I2C_STATE_CLEAR_ADDRESS; } else { i2c_master_addressing(I2C0, slave_addr << 1, I2C_RECEIVER); i2c_ack_config(I2C0, I2C_ACK_DISABLE); - state = I2C_CLEAR_ADDRESS_FLAG; + state = I2C_STATE_CLEAR_ADDRESS; } timeout = 0; } else { timeout = 0; - state = I2C_START; + state = I2C_STATE_START; read_cycle = RESET; #ifdef DEBUG_VERBOES printf("i2c master sends start signal timeout in READ!\n"); #endif } break; - case I2C_CLEAR_ADDRESS_FLAG: + case I2C_STATE_CLEAR_ADDRESS: /* address flag set means i2c slave sends ACK */ while ((!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND)) && (timeout < I2C_TIME_OUT)) { timeout++; } if (timeout < I2C_TIME_OUT) { + /* Check for NACK before clearing address flag */ + if (i2c_flag_get(I2C0, I2C_FLAG_AERR)) { + /* NACK received - slave did not acknowledge address */ + i2c_flag_clear(I2C0, I2C_FLAG_AERR); + i2c_stop_on_bus(I2C0); +#ifdef DEBUG_VERBOES + printf("i2c NACK received for address 0x%02X in read!\n", slave_addr); +#endif + return I2C_RESULT_NACK; + } + i2c_flag_clear(I2C0, I2C_FLAG_ADDSEND); if ((SET == read_cycle) && (1 == number_of_byte)) { /* send a stop condition to I2C bus */ i2c_stop_on_bus(I2C0); } timeout = 0; - state = I2C_TRANSMIT_DATA; + state = I2C_STATE_TRANSMIT_DATA; } else { timeout = 0; - state = I2C_START; + state = I2C_STATE_START; read_cycle = RESET; #ifdef DEBUG_VERBOES printf("i2c master clears address flag timeout in READ!\n"); #endif } break; - case I2C_TRANSMIT_DATA: + case I2C_STATE_TRANSMIT_DATA: if (RESET == read_cycle) { /* wait until the transmit data buffer is empty */ while ((!i2c_flag_get(I2C0, I2C_FLAG_TBE)) && (timeout < I2C_TIME_OUT)) { @@ -513,7 +537,7 @@ uint8_t i2c_read_16bits(uint8_t slave_addr, uint8_t reg_addr, uint8_t *data) { timeout = 0; } else { timeout = 0; - state = I2C_START; + state = I2C_STATE_START; read_cycle = RESET; #ifdef DEBUG_VERBOES printf("i2c master wait data buffer is empty timeout in READ!\n"); @@ -525,11 +549,11 @@ uint8_t i2c_read_16bits(uint8_t slave_addr, uint8_t reg_addr, uint8_t *data) { } if (timeout < I2C_TIME_OUT) { timeout = 0; - state = I2C_START; + state = I2C_STATE_START; read_cycle = SET; } else { timeout = 0; - state = I2C_START; + state = I2C_STATE_START; read_cycle = RESET; #ifdef DEBUG_VERBOES printf("i2c master sends register address timeout in READ!\n"); @@ -556,7 +580,7 @@ uint8_t i2c_read_16bits(uint8_t slave_addr, uint8_t reg_addr, uint8_t *data) { } if (timeout > I2C_TIME_OUT) { timeout = 0; - state = I2C_START; + state = I2C_STATE_START; read_cycle = 0; #ifdef DEBUG_VERBOES printf("i2c master sends data timeout in READ!\n"); @@ -564,21 +588,21 @@ uint8_t i2c_read_16bits(uint8_t slave_addr, uint8_t reg_addr, uint8_t *data) { } } timeout = 0; - state = I2C_STOP; + state = I2C_STATE_STOP; } break; - case I2C_STOP: + case I2C_STATE_STOP: /* i2c master sends STOP signal successfully */ while ((I2C_CTL0(I2C0) & I2C_CTL0_STOP) && (timeout < I2C_TIME_OUT)) { timeout++; } if (timeout < I2C_TIME_OUT) { timeout = 0; - state = I2C_END; + state = I2C_STATE_END; i2c_timeout_flag = I2C_OK; } else { timeout = 0; - state = I2C_START; + state = I2C_STATE_START; read_cycle = 0; #ifdef DEBUG_VERBOES printf("i2c master sends stop signal timeout in READ!\n"); @@ -586,7 +610,7 @@ uint8_t i2c_read_16bits(uint8_t slave_addr, uint8_t reg_addr, uint8_t *data) { } break; default: - state = I2C_START; + state = I2C_STATE_START; read_cycle = 0; i2c_timeout_flag = I2C_OK; timeout = 0; @@ -596,5 +620,32 @@ uint8_t i2c_read_16bits(uint8_t slave_addr, uint8_t reg_addr, uint8_t *data) { break; } } - return I2C_END; + return I2C_RESULT_SUCCESS; } + +#ifdef DEBUG_VERBOSE +/*! + \brief get status string for debugging + \param[in] status: i2c_status_t value + \param[out] none + \retval const char* status string +*/ +const char* i2c_get_status_string(i2c_result_t status) { + switch (status) { + case I2C_RESULT_SUCCESS: + return "SUCCESS"; + case I2C_RESULT_TIMEOUT: + return "TIMEOUT"; + case I2C_RESULT_NACK: + return "NACK"; + case I2C_RESULT_BUS_BUSY: + return "BUS_BUSY"; + case I2C_RESULT_ERROR: + return "ERROR"; + case I2C_RESULT_INVALID_PARAM: + return "INVALID_PARAM"; + default: + return "UNKNOWN"; + } +} +#endif diff --git a/Src/main.c b/Src/main.c index ea592b6..082eb77 100644 --- a/Src/main.c +++ b/Src/main.c @@ -81,10 +81,58 @@ int main(void) i2c_bus_reset(); #endif - i2c_scan(); - ldc1612_iic_get_sensor_infomation(); + // i2c_scan(); + uint8_t ldc_data[2] = {0}; + i2c_result_t i2c_result = i2c_read_16bits(LDC1612_ADDR, READ_MANUFACTURER_ID, ldc_data); + + // const char* i2c_string = i2c_get_status_string(i2c_result); + +// const char* msg1 = "I2C Status: "; +// for (uint8_t i = 0; msg1[i] != '\0'; i++) { +// while (usart_flag_get(RS485_PHY, USART_FLAG_TBE) == RESET) {} +// usart_data_transmit(RS485_PHY, msg1[i]); +// } + +// // 发送i2c_string内容 +// for (uint8_t i = 0; i2c_string[i] != '\0'; i++) { +// while (usart_flag_get(RS485_PHY, USART_FLAG_TBE) == RESET) {} +// usart_data_transmit(RS485_PHY, i2c_string[i]); +// } + +// // 发送换行符 +// const char* newline1 = "\r\n"; +// for (uint8_t i = 0; newline1[i] != '\0'; i++) { +// while (usart_flag_get(RS485_PHY, USART_FLAG_TBE) == RESET) {} +// usart_data_transmit(RS485_PHY, newline1[i]); +// } + +// 第二句:发送 "LDC1612 Manufacturer ID: 0x" + 十六进制数值 + "\r\n" +const char* msg2 = "LDC1612 Manufacturer ID: 0x"; +for (uint8_t i = 0; msg2[i] != '\0'; i++) { + while (usart_flag_get(RS485_PHY, USART_FLAG_TBE) == RESET) {} + usart_data_transmit(RS485_PHY, msg2[i]); +} + +// 发送十六进制数值 +uint16_t manufacturer_id = (ldc_data[0] << 8) | ldc_data[1]; +uint8_t hex_chars[] = "0123456789ABCDEF"; +for (int8_t i = 3; i >= 0; i--) { + uint8_t nibble = (manufacturer_id >> (i * 4)) & 0x0F; + while (usart_flag_get(RS485_PHY, USART_FLAG_TBE) == RESET) {} + usart_data_transmit(RS485_PHY, hex_chars[nibble]); +} + +// 发送换行符 +const char* newline2 = "\r\n"; +for (uint8_t i = 0; newline2[i] != '\0'; i++) { + while (usart_flag_get(RS485_PHY, USART_FLAG_TBE) == RESET) {} + usart_data_transmit(RS485_PHY, newline2[i]); +} + +// 等待所有数据发送完成 +while (usart_flag_get(RS485_PHY, USART_FLAG_TC) == RESET) {} while(1){ command_process(); diff --git a/i2c_wait.c b/i2c_wait.c index 17aa538..8b7af70 100644 --- a/i2c_wait.c +++ b/i2c_wait.c @@ -429,10 +429,6 @@ const char* i2c_get_status_string(i2c_status_t status) { } } - - -// TODO ldc1612.c - // // Created by dell on 24-12-3. // LDC1612 Inductive Sensor Driver Implementation