#define SW_I2C_WAIT_TIME 22 #define I2C_READ 0x01 #define READ_CMD 1 #define WRITE_CMD 0 void SW_I2C_init(void) { GPIO_InitTypeDef GPIO_InitStructure = { 0 }; GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH; GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStructure.Pin = SW_I2C1_SCL_PIN; HAL_GPIO_Init(SW_I2C1_SCL_GPIO, &GPIO_InitStructure); GPIO_InitStructure.Pin = SW_I2C1_SDA_PIN; HAL_GPIO_Init(SW_I2C1_SDA_GPIO, &GPIO_InitStructure); } uint8_t SW_I2C_ReadVal_SDA(void) { uint8_t ret; ret = (uint16_t)HAL_GPIO_ReadPin(SW_I2C1_SDA_GPIO, SW_I2C1_SDA_PIN); return ret; } void sda_high(void) { HAL_GPIO_WritePin(SW_I2C1_SDA_GPIO, SW_I2C1_SDA_PIN, GPIO_PIN_SET); } void sda_low(void) { HAL_GPIO_WritePin(SW_I2C1_SDA_GPIO, SW_I2C1_SDA_PIN, GPIO_PIN_RESET); } void scl_high(void) { HAL_GPIO_WritePin(SW_I2C1_SCL_GPIO, SW_I2C1_SCL_PIN, GPIO_PIN_SET); } void scl_low(void) { HAL_GPIO_WritePin(SW_I2C1_SCL_GPIO, SW_I2C1_SCL_PIN, GPIO_PIN_RESET); } void sda_out(uint8_t out) { if (out) { sda_high(); } else { sda_low(); } } void sda_in_mode(void) { GPIO_InitTypeDef GPIO_InitStructure = { 0 }; GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH; GPIO_InitStructure.Mode = GPIO_MODE_INPUT; GPIO_InitStructure.Pin = SW_I2C1_SDA_PIN; HAL_GPIO_Init(SW_I2C1_SDA_GPIO, &GPIO_InitStructure); } void sda_out_mode(void) { GPIO_InitTypeDef GPIO_InitStructure = { 0 }; GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH; GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_OD; GPIO_InitStructure.Pin = SW_I2C1_SDA_PIN; HAL_GPIO_Init(SW_I2C1_SDA_GPIO, &GPIO_InitStructure); } void i2c_clk_data_out(void) { scl_high(); delay(SW_I2C_WAIT_TIME); scl_low(); } void i2c_port_init(void) { sda_high(); scl_high(); } void i2c_start_condition(void) { sda_high(); scl_high(); delay(SW_I2C_WAIT_TIME); sda_low(); delay(SW_I2C_WAIT_TIME); scl_low(); delay(SW_I2C_WAIT_TIME << 1); } void i2c_stop_condition(void) { sda_low(); scl_high(); delay(SW_I2C_WAIT_TIME); sda_high(); delay(SW_I2C_WAIT_TIME); } uint8_t i2c_check_ack(void) { uint8_t ack; int i; unsigned int temp; sda_in_mode(); scl_high(); ack = 0; delay(SW_I2C_WAIT_TIME); for (i = 10; i > 0; i--) { temp = !(SW_I2C_ReadVal_SDA()); if (temp) { ack = 1; break; } } scl_low(); sda_out_mode(); delay(SW_I2C_WAIT_TIME); return ack; } void i2c_check_not_ack(void) { sda_in_mode(); i2c_clk_data_out(); sda_out_mode(); delay(SW_I2C_WAIT_TIME); } void i2c_slave_address(uint8_t IICID, uint8_t readwrite) { int x; if (readwrite) { IICID |= I2C_READ; } else { IICID &= ~I2C_READ; } scl_low(); for (x = 7; x >= 0; x--) { sda_out(IICID & (1 << x)); delay(SW_I2C_WAIT_TIME); i2c_clk_data_out(); } } void i2c_register_address(uint8_t addr) { int x; scl_low(); for (x = 7; x >= 0; x--) { sda_out(addr & (1 << x)); delay(SW_I2C_WAIT_TIME); i2c_clk_data_out(); } } void i2c_send_ack(void) { sda_out_mode(); sda_low(); delay(SW_I2C_WAIT_TIME); scl_high(); delay(SW_I2C_WAIT_TIME << 1); sda_low(); delay(SW_I2C_WAIT_TIME << 1); scl_low(); sda_out_mode(); delay(SW_I2C_WAIT_TIME); } void SW_I2C_Write_Data(uint8_t data) { int x; scl_low(); for (x = 7; x >= 0; x--) { sda_out(data & (1 << x)); delay(SW_I2C_WAIT_TIME); i2c_clk_data_out(); } } uint8_t SW_I2C_Read_Data(void) { int x; uint8_t readdata = 0; sda_in_mode(); for (x = 8; x--;) { scl_high(); readdata <<= 1; if (SW_I2C_ReadVal_SDA()) { readdata |= 0x01; } delay(SW_I2C_WAIT_TIME); scl_low(); delay(SW_I2C_WAIT_TIME); } sda_out_mode(); return readdata; } uint8_t SW_I2C_WriteControl_8Bit(uint8_t IICID, uint8_t regaddr, uint8_t data) { uint8_t returnack = true; i2c_start_condition(); i2c_slave_address(IICID, WRITE_CMD); if (!i2c_check_ack()) { returnack = false; } delay(SW_I2C_WAIT_TIME); i2c_register_address(regaddr); if (!i2c_check_ack()) { returnack = false; } delay(SW_I2C_WAIT_TIME); SW_I2C_Write_Data(data); if (!i2c_check_ack()) { returnack = false; } delay(SW_I2C_WAIT_TIME); i2c_stop_condition(); return returnack; } uint8_t SW_I2C_Multi_ReadnControl_8Bit(uint8_t IICID, uint8_t regaddr, uint8_t rcnt, uint8_t (*pdata)) { uint8_t returnack = true; uint8_t index; i2c_port_init(); i2c_start_condition(); i2c_slave_address(IICID, WRITE_CMD); if (!i2c_check_ack()) { returnack = false; } delay(SW_I2C_WAIT_TIME); i2c_register_address(regaddr); if (!i2c_check_ack()) { returnack = false; } delay(SW_I2C_WAIT_TIME); i2c_start_condition(); i2c_slave_address(IICID, READ_CMD); if (!i2c_check_ack()) { returnack = false; } for ( index = 0 ; index < (rcnt-1) ; index++) { delay(SW_I2C_WAIT_TIME); pdata[index] = SW_I2C_Read_Data(); i2c_send_ack(); } pdata[rcnt-1] = SW_I2C_Read_Data(); i2c_check_not_ack(); i2c_stop_condition(); return returnack; }