基于具体平台实现基础接口
void delay(void)
{
// TO-DO: delay
// volatile uint32_t count = 5U;
// while(count > 0)
// {
// count--;
// }
}
#define SW_I2C_DELAY() delay()
#define SW_SW_I2C_SCL_INIT() //TO-DO: scl pin init
#define SW_I2C_SCL_IN() //TO-DO: set scl pin as input
#define SW_I2C_SCL_OUT() //TO-DO: set scl pin as output
#define SW_I2C_SCL_H() //TO-DO: set scl pin to high
#define SW_I2C_SCL_L() //TO-DO: set scl pin to low
#define SW_SW_I2C_SDA_INIT() //TO-DO: sda pin init
#define SW_I2C_SDA_IN() //TO-DO: set sda pin as input
#define SW_I2C_SDA_OUT() //TO-DO: set sda pin as output
#define SW_I2C_SDA_H() //TO-DO: set sda pin to high
#define SW_I2C_SDA_L() //TO-DO: set sda pin to low
#define SW_I2C_SDA_IS_H() //TO-DO: get sda pin level
I2C基础时序实现
void sw_i2c_init(void)
{
SW_SW_I2C_SDA_INIT();
SW_SW_I2C_SCL_INIT();
SW_I2C_SCL_OUT();
SW_I2C_SDA_OUT();
SW_I2C_SCL_H();
SW_I2C_SDA_H();
}
void sw_i2c_start(void)
{
SW_I2C_SDA_OUT();
SW_I2C_SCL_OUT();
SW_I2C_SDA_H();
SW_I2C_SCL_H();
SW_I2C_DELAY();
SW_I2C_SDA_L();
SW_I2C_DELAY();
SW_I2C_SCL_L();
}
void sw_i2c_stop(void)
{
SW_I2C_SDA_OUT();
SW_I2C_SDA_L();
SW_I2C_DELAY();
SW_I2C_SCL_H();
SW_I2C_DELAY();
SW_I2C_SDA_H();
}
void sw_i2c_tx_ack(void)
{
SW_I2C_SDA_OUT();
SW_I2C_SDA_L();
SW_I2C_DELAY();
SW_I2C_SCL_H();
SW_I2C_DELAY();
SW_I2C_SCL_L();
}
void sw_i2c_tx_nack(void)
{
SW_I2C_SDA_OUT();
SW_I2C_SDA_H();
SW_I2C_DELAY();
SW_I2C_SCL_H();
SW_I2C_DELAY();
SW_I2C_SCL_L();
}
uint8_t sw_i2c_rx_ack(void)
{
uint8_t ret = 0;
SW_I2C_SDA_IN();
SW_I2C_DELAY();
SW_I2C_SCL_H();
SW_I2C_DELAY();
if (!SW_I2C_SDA_IS_H()) {
ret = 1;
}
SW_I2C_SCL_L();
return ret;
}
void sw_i2c_tx_byte(uint8_t dat)
{
uint8_t i = 0;
uint8_t temp = dat;
SW_I2C_SDA_OUT();
for (i = 0; i < 8; i++)
{
if (temp & 0x80)
{
SW_I2C_SDA_H();
}
else
{
SW_I2C_SDA_L();
}
SW_I2C_DELAY();
SW_I2C_SCL_H();
SW_I2C_DELAY();
SW_I2C_SCL_L();
temp <<= 1;
}
}
uint8_t sw_i2c_rx_byte(void)
{
uint8_t i = 0;
uint8_t dat = 0;
SW_I2C_SDA_IN();
for (i = 0; i < 8; i++)
{
SW_I2C_DELAY();
SW_I2C_SCL_H();
SW_I2C_DELAY();
dat <<= 1;
if (SW_I2C_SDA_IS_H())
{
dat |= 0x01;
}
SW_I2C_SCL_L();
}
return dat;
}
示例
根据slave的i2c时序要求,实现读写接口示例如下:
void sw_i2c_write(uint8_t device_addr, uint16_t reg_addr, uint8_t dat[], uint8_t len)
{
uint8_t i = 0;
sw_i2c_start();
sw_i2c_tx_byte(device_addr & 0xFE);
sw_i2c_rx_ack();
sw_i2c_tx_byte((uint8_t)(reg_addr >> 8));
sw_i2c_rx_ack();
sw_i2c_tx_byte((uint8_t)(reg_addr & 0xff));
sw_i2c_rx_ack();
for(i = 0; i < len; i++)
{
sw_i2c_tx_byte(dat[i]);
sw_i2c_rx_ack();
}
sw_i2c_stop();
}
void sw_i2c_read(uint8_t device_addr, uint16_t reg_addr, uint8_t dat[], uint8_t len)
{
uint8_t i = 0;
sw_i2c_start();
sw_i2c_tx_byte(device_addr & 0xFE);
sw_i2c_rx_ack();
sw_i2c_tx_byte((uint8_t)(reg_addr >> 8));
sw_i2c_rx_ack();
sw_i2c_tx_byte((uint8_t)(reg_addr & 0xff));
sw_i2c_rx_ack();
sw_i2c_start();
sw_i2c_tx_byte(device_addr | 0x01);
sw_i2c_rx_ack();
for(i = 0; i < len; i++)
{
dat[i] = sw_i2c_rx_byte();
if(i == (len-1))
{
sw_i2c_tx_nack();
}
else
{
sw_i2c_tx_ack();
}
}
sw_i2c_stop();
}