一、数据格式
1、读数据:
2、写数据:
二、I2C时序图
1、读写时序图:
三、软件实现
1、开始
在SCL处于高电平的状态时,SDA产生一个下降沿信号;
/* *@brief i2c Start *@author Mr.W *@date 2020-8-3 */ static void i2c_start(void) { I2C_SDA_SET; i2c_delay(5); I2C_SCL_SET; i2c_delay(5); I2C_SDA_CLR; i2c_delay(5); I2C_SCL_CLR; i2c_delay(5); }
2、停止
在SCL处于高电平的状态时,SDA产生一个上升沿信号;
/* *@brief i2c Stop *@author Mr.W *@date 2020-8-3 */ static void i2c_stop(void) { I2C_SCL_CLR; i2c_delay(5); I2C_SDA_CLR; i2c_delay(5); I2C_SCL_SET; i2c_delay(5); I2C_SDA_SET; i2c_delay(5); }
3、等待响应信号
如果等到响应信号SDA电平信号由高电平变成低电平,否则未等到响应信号;
/* *@brief i2c Wait Acknowledge *@author Mr.W *@date 2020-8-3 */ static uint8_t i2c_wait_ack(void) { I2C_SDA_SET; i2c_delay(5); I2C_SCL_SET; i2c_delay(5); if(I2C_PIN_SDA) { i2c_stop(); return 0; } I2C_SCL_CLR; return 1; }
4、发送响应
/* *@brief i2c Send Acknowledge *@author Mr.W *@date 2020-8-3 */ static void i2c_send_ack(void) { I2C_SDA_CLR; i2c_delay(5); I2C_SCL_SET; i2c_delay(5); I2C_SCL_CLR; }
5、发送未响应
/* *@brief i2c Send No Acknowledge *@author Mr.W *@date 2020-8-3 */ static void i2c_send_noack(void) { I2C_SDA_SET; i2c_delay(5); I2C_SCL_SET; i2c_delay(5); I2C_SCL_CLR; }
6、发送数据
发送一个字节数据;
/* *@brief i2c Send Data *@author Mr.W *@date 2020-8-3 */ static void i2c_send_data(uint8_t data) { uint8_t i = 8; while(i--) { I2C_SCL_CLR; i2c_delay(10); if(data & 0x80) { I2C_SDA_SET; } else { I2C_SDA_CLR; } i2c_delay(5); data <<= 1; I2C_SCL_SET; i2c_delay(5); I2C_SCL_CLR; i2c_delay(5); } }
7、接收数据
接收一个字节数据;
/* *@brief i2c Receive Data *@author Mr.W *@date 2020-8-3 */ static uint8_t i2c_receive_data(void) { uint8_t i = 8; uint8_t data = 0; I2C_SDA_SET; while(i--) { data <<= 1; I2C_SCL_CLR; i2c_delay(5); I2C_SCL_SET; i2c_delay(5); if(I2C_PIN_SDA) data |= 0x01; } I2C_SCL_CLR; return data; }
8、读多个数据
/* *@brief Read Data *@author Mr.W *@date 2020-8-3 */ uint8_t ReadNByte(uint8_t sla, uint16_t suba, uint8_t *pdata, uint16_t num) { uint8_t i; i2c_start(); i2c_send_data(sla); if(i2c_wait_ack() == 0) { i2c_stop(); return 0; } i2c_send_data(suba); if(i2c_wait_ack() == 0) { i2c_stop(); return 0; } i2c_start(); i2c_send_data(sla|0x01); if(i2c_wait_ack() == 0) { i2c_stop(); return 0; } for(i = 0; i < num; i++) { *pdata++ = i2c_receive_data(); if(i < (num - 1)) i2c_send_ack(); } i2c_send_noack(); i2c_stop(); return 1; }
9、写多个数据
/* *@brief Write Data *@author Mr.W *@date 2020-8-3 */ uint8_t WriteNByte(uint8_t sla, uint16_t suba, uint8_t *pdata, uint16_t num) { uint8_t i; i2c_start(); i2c_send_data(sla); if(i2c_wait_ack() == 0) { i2c_stop(); return 0; } i2c_send_data(suba); if(i2c_wait_ack() == 0) { i2c_stop(); return 0; } for(i = 0; i < num; i++) { i2c_send_data(*pdata++); if(i2c_wait_ack() == 0) { i2c_stop(); return 0; } } i2c_stop(); return 1; }
#end