不说废话,上代码,不同之处直接用宏 展开
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 GD32E230
uint8_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_start
timeout = 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 GD32L235
i2c_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 1
i2c_reload_disable(I2CX);
/* enable I2C automatic end mode in master mode */
i2c_automatic_end_enable(I2CX);
#endif
while(!(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;
}
}
#endif
return state;
}
b. 写
uint8_t sensirion_i2c_WriteByte_timeout(uint8_t Addr,const uint8_t *data,uint16_t count){
#ifdef GD32E230
uint8_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_start
timeout = 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 GD32L235
i2c_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;
}
}
#endif
return state;
}
因为 两套api 接口不一致,所以还是有较大出入的。希望 在用这款单片机的兄弟闷,少走弯路,我这已经调好,拿走不谢!