在board_config.h文件中添加#define SOFTWARE_IIC选项用以选择使用软件IIC还是硬件IIC,如果注释掉该行则为硬件IIC方式。并完整实现软件IIC功能。

This commit is contained in:
2024-12-29 22:07:49 +08:00
parent 9b9f14f97a
commit 0ac221ce6f
10 changed files with 187 additions and 89 deletions

View File

@@ -47,11 +47,11 @@ void soft_i2c_start(void) {
// sda_out();
I2C_SDA_HIGH();
I2C_SCL_HIGH();
i2c_delay();
soft_i2c_delay();
I2C_SDA_LOW();
i2c_delay();
soft_i2c_delay();
I2C_SCL_LOW();
// i2c_delay();
// soft_i2c_delay();
// 从全高开始SCL为高期间SDA下降沿表示start信号再拉低SCL
}
@@ -65,9 +65,9 @@ void soft_i2c_stop(void) {
// sda_out();
I2C_SCL_LOW();
I2C_SDA_LOW();
i2c_delay();
soft_i2c_delay();
I2C_SCL_HIGH();
i2c_delay();
soft_i2c_delay();
I2C_SDA_HIGH();
// 从全低开始SCL为高期间SDA上升沿表示stop
}
@@ -81,11 +81,11 @@ void soft_i2c_stop(void) {
void soft_i2c_send_ack(void) {
// sda_out();
I2C_SDA_LOW();
i2c_delay();
soft_i2c_delay();
I2C_SCL_HIGH();
i2c_delay();
soft_i2c_delay();
I2C_SCL_LOW();
i2c_delay();
soft_i2c_delay();
I2C_SDA_HIGH();
// SCL产生一个正常的时钟周期其间SDA始终为低电平表示ACK
}
@@ -99,11 +99,11 @@ void soft_i2c_send_ack(void) {
void soft_i2c_send_nack(void) {
// sda_out();
I2C_SDA_HIGH();
i2c_delay();
soft_i2c_delay();
I2C_SCL_HIGH();
i2c_delay();
soft_i2c_delay();
I2C_SCL_LOW();
i2c_delay();
soft_i2c_delay();
I2C_SDA_HIGH();
// SCL产生一个正常的时钟周期其间SDA始终为高电平表示NACK
}
@@ -117,9 +117,9 @@ void soft_i2c_send_nack(void) {
uint8_t soft_i2c_wait_ack(void) {
// sda_in();
I2C_SDA_HIGH();
i2c_delay();
soft_i2c_delay();
I2C_SCL_HIGH();
i2c_delay();
soft_i2c_delay();
uint8_t ack = !I2C_SDA_READ();
//ACK信号是第九个时钟期间SDA被从机在SCL高期间拉低并保持低电平。此处判断SDA是否被拉低被拉低则返回0取反为1表示收到ACK
I2C_SCL_LOW();
@@ -141,9 +141,9 @@ void soft_i2c_send_byte(uint8_t byte) {
I2C_SDA_LOW(); //SCL低电平期间SDA低电平表示0
}
byte <<= 1; //左移一位,把原本第二位的数据移到第一位,再判断高低电平
i2c_delay();
soft_i2c_delay();
I2C_SCL_HIGH(); //SCL拉高电平SDA电平状态保持不变
i2c_delay();
soft_i2c_delay();
I2C_SCL_LOW(); //SCL拉低电平
delay_us(5);
}
@@ -163,12 +163,12 @@ uint8_t soft_i2c_receive_byte(uint8_t ack) {
for (int i = 0; i < 8; i++) {
byte <<= 1;
I2C_SCL_HIGH();
i2c_delay();
soft_i2c_delay();
if (I2C_SDA_READ()) {
byte |= 0x01;
}
I2C_SCL_LOW();
i2c_delay();
soft_i2c_delay();
}
if (ack) {
soft_i2c_send_ack();
@@ -176,4 +176,53 @@ uint8_t soft_i2c_receive_byte(uint8_t ack) {
soft_i2c_send_nack();
}
return byte;
}
uint8_t soft_i2c_write_16bits(uint8_t slave_addr, uint8_t reg_addr, uint8_t data[2]) {
soft_i2c_start();
soft_i2c_send_byte(slave_addr);
if (!soft_i2c_wait_ack()) {
soft_i2c_stop();
return SOFT_I2C_FAIL;
}
soft_i2c_send_byte(reg_addr);
if (!soft_i2c_wait_ack()) {
soft_i2c_stop();
return SOFT_I2C_FAIL;
}
soft_i2c_send_byte(data[0]);
if (!soft_i2c_wait_ack()) {
soft_i2c_stop();
return SOFT_I2C_FAIL;
}
soft_i2c_send_byte(data[1]);
if (soft_i2c_wait_ack()){}
soft_i2c_stop();
return SOFT_I2C_OK;
}
uint8_t soft_i2c_read_16bits(uint8_t slave_addr, uint8_t reg_addr, uint8_t *data)
{
soft_i2c_start();
soft_i2c_send_byte(slave_addr);
if (!soft_i2c_wait_ack()) {
soft_i2c_stop();
return SOFT_I2C_FAIL;
}
soft_i2c_send_byte(reg_addr);
if (!soft_i2c_wait_ack()) {
soft_i2c_stop();
return SOFT_I2C_FAIL;
}
soft_i2c_start();
soft_i2c_send_byte(slave_addr | 0x01);
if (!soft_i2c_wait_ack()) {
soft_i2c_stop();
return SOFT_I2C_FAIL;
}
soft_i2c_delay();
data[0] = soft_i2c_receive_byte(1);
data[1] = soft_i2c_receive_byte(0);
soft_i2c_stop();
return SOFT_I2C_OK;
}