不说废话,上代码,不同之处直接用宏 展开
1. 首先是i2c 时钟配置 函数有些出入
void sensirion_i2c_attribute_config(){#ifdef GD32E230/* I2C clock configure */i2c_clock_config(I2C1, 100000, I2C_DTCY_2);/* I2C address configure */i2c_mode_addr_config(I2C1, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_7BITS, I2C1_OWN_ADDRESS7);/* enable I2C1 */i2c_enable(I2C1);/* enable acknowledge */i2c_ack_config(I2C1, I2C_ACK_ENABLE);#endif#ifdef GD32L235/* configure I2C timing */i2c_timing_config(I2C0, 0, 0x3, 0);i2c_master_clock_config(I2C0, 0x13, 0x36);i2c_address_config(I2C0, I2C1_OWN_ADDRESS7, I2C_ADDFORMAT_7BITS);/* configure slave address *///i2c_master_addressing(I2C0, 0x82, I2C_MASTER_TRANSMIT);/* enable I2C0 */i2c_enable(I2C0);#endif
}
2. 然后是 i2c 的读与 写,请看
a. 读
uint8_t sensirion_i2c_ReadByte_timeout(uint8_t Addr,uint8_t *data,uint16_t count){// IMPLEMENT#ifdef GD32E230uint8_t state = I2C_START;uint16_t timeout = 0;uint8_t i2c_timeout_flag = 0;i2c_ackpos_config(I2C1, I2C_ACKPOS_NEXT);while(!(i2c_timeout_flag)){switch (state){case I2C_START:while(i2c_flag_get(I2CX, I2C_FLAG_I2CBSY) && (timeout < I2C_TIME_OUT)){timeout++;}if(timeout < I2C_TIME_OUT){i2c_start_on_bus(I2C1);//i2c_starttimeout = 0;state = I2C_SEND_ADDRESS;}else{timeout = 0;state = I2C_START;//PR_DEBUG("i2c bus is busy in byte read \r\n");}break;case I2C_SEND_ADDRESS:/* i2c master sends START signal successfully */while((!i2c_flag_get(I2CX, I2C_FLAG_SBSEND)) && (timeout < I2C_TIME_OUT)){timeout++;}if(timeout < I2C_TIME_OUT){i2c_master_addressing(I2CX, (Addr << 1), I2C_RECEIVER);timeout = 0;state = I2C_CLEAR_ADDRESS_FLAG;}else{timeout = 0;state = I2C_START;//add //提前退出循环i2c_timeout_flag = I2C_OK;//PR_DEBUG("i2c master sends start signal timeout in BYTE READ!\n");}break;case I2C_CLEAR_ADDRESS_FLAG:/* address flag set means i2c slave sends ACK */while((!i2c_flag_get(I2CX, I2C_FLAG_ADDSEND)) && (timeout < I2C_TIME_OUT)){timeout++;}if(timeout < I2C_TIME_OUT){i2c_flag_clear(I2CX, I2C_FLAG_ADDSEND);timeout = 0;state = I2C_TRANSMIT_DATA;}else{timeout = 0;state = I2C_START;//add //提前退出循环i2c_timeout_flag = I2C_OK;//PR_DEBUG("i2c master clears address flag timeout in BYTE WRITE!\n");}break;case I2C_TRANSMIT_DATA:/* wait until the transmit data buffer is empty */while((!i2c_flag_get(I2CX, I2C_FLAG_TBE)) && (timeout < I2C_TIME_OUT)){timeout++;}while(count){if(count == 1){i2c_ackpos_config(I2C1, I2C_ACKPOS_CURRENT);i2c_ack_config(I2C1, I2C_ACK_DISABLE);}if(i2c_flag_get(I2C1, I2C_FLAG_RBNE)){*data = i2c_data_receive(I2C1);i2c_ack_config(I2C1, I2C_ACK_ENABLE);data++;count--;}else{state = I2C_START;timeout = 0;}}state = I2C_STOP;timeout = 0;break;case I2C_STOP:/* send a stop condition to I2C bus */i2c_stop_on_bus(I2CX);/* i2c master sends STOP signal successfully */while((I2C_CTL1(I2CX) & 0x0200) && (timeout < I2C_TIME_OUT)){timeout++;}if(timeout < I2C_TIME_OUT){i2c_ackpos_config(I2C1, I2C_ACKPOS_CURRENT);/* enable acknowledge */i2c_ack_config(I2C1, I2C_ACK_ENABLE);timeout = 0;state = I2C_END;i2c_timeout_flag = I2C_OK;}else{timeout = 0;state = I2C_START;//PR_DEBUG("i2c master sends stop signal timeout in BYTE READ\n");}break;default:state = I2C_START;i2c_timeout_flag = I2C_OK;timeout = 0;//PR_DEBUG("i2c master sends start signal in BYTE READ!\n");break;}}#endif#ifdef GD32L235i2c_process_enum state = I2C_START;uint32_t timeout = 0;uint8_t end_flag = 0;//i2c_nack_disable(I2CX);i2c_transfer_byte_number_config(I2CX, count);
#if 1i2c_reload_disable(I2CX);/* enable I2C automatic end mode in master mode */i2c_automatic_end_enable(I2CX);
#endifwhile(!(end_flag)){//printf("i2c bus is busy in read_state:%d,LINE: %d!\r\n",state,__LINE__);switch (state){case I2C_START:/* configure number of bytes to be transferred */while(i2c_flag_get(I2CX, I2C_FLAG_I2CBSY) && (timeout < I2C_TIME_OUT)) {timeout++;}if(timeout < I2C_TIME_OUT) {i2c_start_on_bus(I2CX);timeout = 0;state = I2C_SEND_ADDRESS;} else {/* timeout, bus reset *///i2c_bus_reset();timeout = 0;state = I2C_START;end_flag = I2C_OK;printf("i2c bus is busy in read_%d!\r\n",__LINE__);}break;case I2C_SEND_ADDRESS:while((!i2c_flag_get(I2CX, I2C_FLAG_TBE)) && (timeout < I2C_TIME_OUT)) {timeout++;}if(timeout < I2C_TIME_OUT) {i2c_master_addressing(I2CX, (Addr<<1), I2C_MASTER_RECEIVE);state = I2C_TRANSMIT_DATA;}else{timeout = 0;state = I2C_START;end_flag = I2C_OK;printf("i2c bus is I2C_SEND_ADDRESS timeout:%d!\r\n",__LINE__);}break;case I2C_TRANSMIT_DATA:while(count){if(i2c_flag_get(I2CX, I2C_FLAG_RBNE)){*data = i2c_data_receive(I2CX);data++;count--;}}state = I2C_STOP;timeout = 0;//printf("i2c transmit complete %d \r\n",i2c_flag_get(I2CX, I2C_FLAG_RBNE));break;case I2C_STOP:/* wait until the stop condition is finished */while((!i2c_flag_get(I2CX, I2C_FLAG_STPDET)) && (timeout < I2C_TIME_OUT)) {timeout++;}if(timeout < I2C_TIME_OUT) {/* clear STPDET flag */i2c_flag_clear(I2CX, I2C_FLAG_STPDET);timeout = 0;state = I2C_END;end_flag = I2C_OK;} else {timeout = 0;state = I2C_START;//printf("i2c master sends stop signal timeout in read!\n");}break;default:/* default status */state = I2C_START;end_flag = 1;timeout = 0;printf("i2c master sends start signal in read!\n");break;}}#endifreturn state;
}
b. 写
uint8_t sensirion_i2c_WriteByte_timeout(uint8_t Addr,const uint8_t *data,uint16_t count){#ifdef GD32E230uint8_t state = I2C_START;uint16_t timeout = 0;uint8_t i2c_timeout_flag = 0;while(!(i2c_timeout_flag)){switch (state){case I2C_START:while(i2c_flag_get(I2C1, I2C_FLAG_I2CBSY) && (timeout < I2C_TIME_OUT)){timeout++;}if(timeout < I2C_TIME_OUT){i2c_start_on_bus(I2C1);//i2c_starttimeout = 0;state = I2C_SEND_ADDRESS;}else{timeout = 0;state = I2C_START;i2c_timeout_flag = I2C_OK;//PR_ERR("%s,i2c bus is busy in byte write \r\n",SENSIR_STR);}break;case I2C_SEND_ADDRESS:/* i2c master sends START signal successfully */while((!i2c_flag_get(I2CX, I2C_FLAG_SBSEND)) && (timeout < I2C_TIME_OUT)){timeout++;}if(timeout < I2C_TIME_OUT){i2c_master_addressing(I2CX, (Addr << 1), I2C_TRANSMITTER);timeout = 0;state = I2C_CLEAR_ADDRESS_FLAG;}else{timeout = 0;state = I2C_START;i2c_timeout_flag = I2C_OK;//PR_ERR("%s,i2c master sends start signal timeout in BYTE WRITE!\r\n",SENSIR_STR);}break;case I2C_CLEAR_ADDRESS_FLAG:/* address flag set means i2c slave sends ACK */while((!i2c_flag_get(I2CX, I2C_FLAG_ADDSEND)) && (timeout < I2C_TIME_OUT)){timeout++;}if(timeout < I2C_TIME_OUT){i2c_flag_clear(I2CX, I2C_FLAG_ADDSEND);timeout = 0;state = I2C_TRANSMIT_DATA;}else{timeout = 0;state = I2C_START;//add 提前退出循环i2c_timeout_flag = I2C_OK;//PR_ERR("%s,i2c master clears address flag timeout in BYTE WRITE!\r\n",SENSIR_STR);}break;case I2C_TRANSMIT_DATA:/* wait until the transmit data buffer is empty */while((!i2c_flag_get(I2CX, I2C_FLAG_TBE)) && (timeout < I2C_TIME_OUT)){timeout++;}while(count){i2c_data_transmit(I2CX, *data);data++;count--;while((!i2c_flag_get(I2CX, I2C_FLAG_BTC)) && (timeout < I2C_TIME_OUT)){timeout++;}if(timeout < I2C_TIME_OUT){timeout = 0;}else{timeout = 0;state = I2C_START;i2c_timeout_flag = I2C_OK;//PR_ERR("%s,i2c master sends data timeout in PAGE WRITE!\n",SENSIR_STR);break;}}state = I2C_STOP;timeout = 0;break;case I2C_STOP:/* send a stop condition to I2C bus */i2c_stop_on_bus(I2CX);/* i2c master sends STOP signal successfully */while((I2C_CTL1(I2CX) & 0x0200) && (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;//PR_ERR("%s,i2c master sends stop signal timeout in BYTE WRITE\r\n",SENSIR_STR);}break;default:state = I2C_START;i2c_timeout_flag = I2C_OK;timeout = 0;//PR_DEBUG("%s,i2c master sends start signal in BYTE WRITE!\r\n",SENSIR_STR);break;}}#endif#ifdef GD32L235i2c_process_enum state = I2C_START;uint16_t timeout = 0;uint8_t end_flag = 0;i2c_transfer_byte_number_config(I2C0, 16);//printf("i2c_master_addressing:0x%x\r\n",Addr<<1);while(!(end_flag)){//printf("IIC writeByte,state: %d\r\n",state);switch(state){case I2C_START:while(i2c_flag_get(I2C0, I2C_FLAG_I2CBSY) && (timeout < I2C_TIME_OUT)){timeout++;}if(timeout < I2C_TIME_OUT){i2c_start_on_bus(I2C0);timeout = 0;state = I2C_SEND_ADDRESS;}else{timeout = 0;state = I2C_START;end_flag = I2C_OK;//printf("i2c bus is busy in writeByte! %d\r\n",__LINE__);}break;case I2C_SEND_ADDRESS:while((!i2c_flag_get(I2C0, I2C_FLAG_TBE)) && (timeout < I2C_TIME_OUT)){timeout++;}if(timeout < I2C_TIME_OUT){timeout = 0;i2c_master_addressing(I2C0, Addr<<1, I2C_MASTER_TRANSMIT);state = I2C_TRANSMIT_DATA;}else{timeout = 0;state = I2C_START;//printf("i2c master sends 's internal address timeout in writeByte!\r\n");}break;case I2C_TRANSMIT_DATA:while((!i2c_flag_get(I2C0, I2C_FLAG_TBE)) && (timeout < I2C_TIME_OUT)){timeout++;}if(timeout < I2C_TIME_OUT){timeout = 0;i2c_data_transmit(I2C0, *data);state = I2C_STOP;}else{timeout = 0;state = I2C_START;//printf("i2c master sends data timeout in writeByte! \r\n");}//printf("i2c_step2 NCK:%d! \r\n",i2c_flag_get(I2C0, I2C_FLAG_NACK));break;case I2C_STOP:/* send a stop condition to I2C bus */i2c_stop_on_bus(I2C0);/* i2c master sends STOP signal successfully */while(!i2c_flag_get(I2C0, I2C_FLAG_STPDET) && (timeout < I2C_TIME_OUT)){timeout++;}if(timeout < I2C_TIME_OUT){timeout = 0;state = I2C_END;end_flag = I2C_OK;/* clear the STPDET bit */i2c_flag_clear(I2C0, I2C_FLAG_STPDET);}else{timeout = 0;state = I2C_START;printf("i2c master sends stop signal timeout in writeByte!\r\n");}break;default:state = I2C_START;end_flag = I2C_OK;timeout = 0;printf("i2c master sends start signal in WRITE!\r\n");break;}}#endifreturn state;
}
因为 两套api 接口不一致,所以还是有较大出入的。希望 在用这款单片机的兄弟闷,少走弯路,我这已经调好,拿走不谢!