/*
本程序是IIC作为主设备(主动发起启动信号)
*/
#define uint8_t unsigned char
#define DEV_ADDR 0x70 //需要控制的设备地址
#define ADDRESS_DEV (DEV_ADDR << 7)
int SDA = 0; // 某GPIO_DAT;如51单片机时 #define SDA P1_0
int SCL = 0; // 某GPIO_CLK;如51单片机时 #define SCL P1_1
void I2C_SendByte(uint8_t _ucByte)
{
uint8_t i;
IIC_Delay();
/* 先发送字节的高位bit7 */
for (i = 0; i < 8; i++)
{
if (_ucByte & 0x80)
{
SDA = 1;
}
else
{
SDA = 0;
}
IIC_Delay();
SCL = 1;
IIC_Delay();
SCL = 0;
if (i == 7)
{
SDA = 1;
}
_ucByte <<= 1; /* 左移一个bit */
IIC_Delay();
}
}
uint8_t I2C_ReadByte(void)
{
uint8_t i;
uint8_t value = 0;
IIC_Delay();
// 读到第1个bit为数据的bit7
for (i = 0; i < 8; i++)
{
value <<= 1;
SCL = 1;
IIC_Delay();
if (SDA == 1)
{
value++;
}
IIC_Delay();
SCL = 0;
IIC_Delay();
}
return value;
}
/*SDA下降沿=start*/
void I2C_Start(void)
{
IIC_Delay();
SDA = 1; // 顺序不能反了,先是SDA=1;
SCL = 1;
IIC_Delay();
SDA = 0;
IIC_Delay();
SCL = 0;
IIC_Delay();
}
/*SDA上升沿=stop*/
void I2C_Stop(void)
{
IIC_Delay();
SDA = 0; // 顺序不能反了,先是SDA=0;
IIC_Delay();
SCL = 1;
IIC_Delay();
SDA = 1;
}
void I2C_Ack(void)
{
IIC_Delay();
SDA = 0;
IIC_Delay();
SCL = 1;
IIC_Delay();
SCL = 0;
IIC_Delay();
SDA = 1;
}
void I2C_NAck(void)
{
IIC_Delay();
SDA = 1;
IIC_Delay();
SCL = 1;
IIC_Delay();
SCL = 0;
IIC_Delay();
}
void I2C_WaitAck(void)
{
uint8_t i = 100;
IIC_Delay();
SCL = 1;
IIC_Delay();
while ((SDA == 1) && (i > 0))
{
IIC_Delay();
i--;
}
SCL = 0;
IIC_Delay();
if (i == 0)
{
}
}
void I2C_WriteSensor(uint8_t addrReg, uint8_t buf)
{
I2C_Start(); /*发送启动信号*/
I2C_SendByte(ADDRESS_DEV);
I2C_WaitAck(); /* 检测设备的ACK应答 */
I2C_SendByte(addrReg);
I2C_WaitAck(); /* 检测设备的ACK应答 */
I2C_SendByte(buf);
I2C_WaitAck(); /* 检测设备的ACK应答 */
I2C_Stop();
}
void I2C_ReadSensor(uint8_t addrReg, uint8_t *buffer, uint8_t len)
{
uint8_t i;
I2C_Start();
/*发送启动信号*/
/* 发送设备地址+读写控制bit(0 = w, 1 = r) bit7 先传 */
I2C_SendByte(ADDRESS_DEV);
I2C_WaitAck();
/* 检测设备的ACK应答*/
I2C_SendByte(addrReg);
I2C_WaitAck();
/*检测设备的ACK应答*/
//========================
I2C_Start();
/*发送启动信号*/
I2C_SendByte(ADDRESS_DEV + 1);
I2C_WaitAck();
/*检测设备的ACK应答 */
for (i = 0; i < len - 1; i++)
{
*buffer++ = I2C_ReadByte();
I2C_Ack();
}
*buffer++ = I2C_ReadByte();
I2C_NAck();
I2C_Stop();
}
void IIC_Delay(void)
{
uint8_t i;
for (i = 0; i < 10; i++)
{
nop();
}
}
void I2C_Init(void) // 初始化
{
SDA = 1;
IIC_Delay();
SCL = 1;
IIC_Delay();
}
[单片机] GPIO模拟IIC
于 2023-02-03 22:49:33 首次发布