#include "iic_soft.h" void soft_iic_delay(uint16 delay_time) { uint16 i; // 简单的延时函数,可以根据实际需要调整 for (i = 0; i < delay_time; i++) { _nop_(); // 空操作,延时 } } void soft_iic_init(IIC_Soft_Config *config) { // 设置SCL和SDA引脚为推挽输出模式 // gpio_mode(config->scl_pin, GPIO); // gpio_mode(config->sda_pin, GPIO); // 初始化SCL和SDA引脚为高电平 config->SCL_SET(); config->SDA_SET(); } void soft_iic_start(IIC_Soft_Config *config) { config->SDA_CLR(); // SDA拉低 soft_iic_delay(config->wait_time); // 等待一段时间 config->SCL_CLR(); // SCL拉低 soft_iic_delay(config->wait_time); // 等待一段时间 } void soft_iic_stop(IIC_Soft_Config *config) { config->SDA_CLR(); // SDA拉低 soft_iic_delay(config->wait_time); // 等待一段时间 config->SCL_SET(); // SCL拉高 soft_iic_delay(config->wait_time); // 等待一段时间 config->SDA_SET(); // SDA拉高 soft_iic_delay(config->wait_time); // 等待一段时间 } uint8 soft_iic_read(IIC_Soft_Config *config) { uint8 dat = 0,i; config->SDA_SET(); // 设置SDA为输入模式 for (i = 0; i < 8; i++) { config->SCL_SET(); // SCL拉高 soft_iic_delay(config->wait_time); // 等待一段时间 if (config->SDA_READ()) // 读取SDA的状态 { dat |= (1 << (7 - i)); // 将读取的位存入dat } config->SCL_CLR(); // SCL拉低 soft_iic_delay(config->wait_time); // 等待一段时间 } return dat; } void soft_iic_write(IIC_Soft_Config *config, uint8 dat) { uint8 i; config->SDA_CLR(); // 设置SDA为输出模式 for (i = 0; i < 8; i++) { soft_iic_delay(config->wait_time); // 等待一段时间 if (dat & (1 << (7 - i))) // 检查当前位 { config->SDA_SET(); // 写入1 } else { config->SDA_CLR(); // 写入0 } config->SCL_SET(); // SCL拉高 soft_iic_delay(config->wait_time); // 等待一段时间 config->SCL_CLR(); // SCL拉低 } soft_iic_delay(config->wait_time); // 等待一段时间 } uint8 soft_iic_rev_ack(IIC_Soft_Config *config) { uint8 err_count = 0; config->SDA_SET(); // 发送 soft_iic_delay(config->wait_time); // 等待一段时间 config->SCL_SET(); // SCL拉高 soft_iic_delay(config->wait_time); // 等待一段时间 while(config->SDA_READ() == 1) { err_count++; if(err_count > 30) { return 0; // 返回ACK失败 } soft_iic_delay(config->wait_time); // 等待一段时间 } config->SCL_CLR(); // SCL拉低 soft_iic_delay(config->wait_time); // 等待一段时间 return 1; } void soft_iic_scan(IIC_Soft_Config *config) { uint8 i; for(i = 0; i <= 0x7F; i++) { //7位SlaveAddress uint8 ACK_or_NACK = 0; soft_iic_start(config); printf("."); soft_iic_write(config,(i << 1) | 0); //I2C从地址+写标志 if(soft_iic_rev_ack(config) ) { printf("\r\nFound Device Address:0x%02X\r\n", i); // UART_SendHex(i); // printf("%02x",i); } else { soft_iic_stop(config); } } } void soft_iic_nack(IIC_Soft_Config *config) { config->SDA_SET(); // 发送NACK soft_iic_delay(config->wait_time); // 等待一段时间 config->SCL_SET(); // SCL拉高 soft_iic_delay(config->wait_time); // 等待一段时间 config->SCL_CLR(); // SCL拉低 soft_iic_delay(config->wait_time); // 等待一段时间 } void soft_iic_ack(IIC_Soft_Config *config) { config->SDA_CLR(); // 发送ACK soft_iic_delay(config->wait_time); // 等待一段时间 config->SCL_SET(); // SCL拉高 soft_iic_delay(config->wait_time); // 等待一段时间 config->SCL_CLR(); // SCL拉低 soft_iic_delay(config->wait_time); // 等待一段时间 } void soft_iic_write_reg(IIC_Soft_Config *config, uint8 dev_addr, uint8 reg, uint8 dat) { soft_iic_start(config); // 发送起始信号 soft_iic_write(config, (dev_addr << 1) | 0); // 发送设备地址和写命令 soft_iic_rev_ack(config); // 等待ACK soft_iic_write(config, reg); // 发送寄存器地址 soft_iic_rev_ack(config); // 等待ACK soft_iic_write(config, dat); // 发送数据 soft_iic_rev_ack(config); // 等待ACK soft_iic_stop(config); // 发送停止信号 } void soft_iic_write_reg_bytes(IIC_Soft_Config *config, uint8 dev_addr, uint8 reg, uint8 *dat, uint8 len) { soft_iic_start(config); // 发送起始信号 soft_iic_write(config, (dev_addr << 1) | 0); // 发送设备地址和写命令 soft_iic_rev_ack(config); // 等待ACK soft_iic_write(config, reg); // 发送寄存器地址 soft_iic_rev_ack(config); // 等待ACK while(len--) { soft_iic_write(config, *dat); // 发送数据 soft_iic_rev_ack(config); // 等待ACK dat++; } soft_iic_stop(config); // 发送停止信号 } uint8 soft_iic_read_reg(IIC_Soft_Config *config, uint8 dev_addr, uint8 reg, uint8 *dat) { soft_iic_start(config); // 发送起始信号 soft_iic_write(config, (dev_addr << 1) | 0); // 发送设备地址和写命令 soft_iic_rev_ack(config); // 等待ACK soft_iic_write(config, reg); // 发送寄存器地址 soft_iic_rev_ack(config); // 等待ACK soft_iic_start(config); // 重新发送起始信号 soft_iic_write(config, (dev_addr << 1) | 1); // 发送设备地址和读命令 soft_iic_rev_ack(config); // 等待ACK *dat = soft_iic_read(config); // 读取数据 soft_iic_nack(config); // 发送NACK soft_iic_stop(config); // 发送停止信号 return *dat; // 返回读取的数据 } uint8 soft_iic_read_reg_bytes(IIC_Soft_Config *config, uint8 dev_addr, uint8 reg, uint8 *buf, uint8 len) { soft_iic_start(config); // 发送起始信号 soft_iic_write(config, (dev_addr << 1) | 0); // 发送设备地址和写命令 soft_iic_rev_ack(config); // 等待ACK soft_iic_write(config, reg); // 发送寄存器地址 soft_iic_rev_ack(config); // 等待ACK soft_iic_start(config); // 重新发送起始信号 soft_iic_write(config, (dev_addr << 1) | 1); // 发送设备地址和读命令 soft_iic_rev_ack(config); // 等待ACK while(len--) { *buf = soft_iic_read(config); // 读取数据 if(len==0) { soft_iic_nack(config); // 发送NACK } else { soft_iic_ack(config); // 发送ACK buf++; } } soft_iic_stop(config); // 发送停止信号 return *buf; // 返回成功 }